Adv C Notes
Adv C Notes
3. Types of Functions:
- Inbuilt/Predefined/Library Functions: These are functions provided by
programming languages or external libraries. They are already implemented and
can be used directly in the program. Examples include functions for
mathematical operations, string manipulation, file handling, etc.
- Function Calling: To execute a function, you need to call it by its name and
provide arguments (if any) that match the function's parameters. The function
call transfers control from the caller to the function.
- Function with Argument with Return Value: This type of function takes one or
more arguments as input and returns a value to the caller. It performs a specific
task and provides the result back to the calling code.
- Function without Argument with Return Value: This type of function does not
take any arguments but returns a value to the caller. It performs a predefined
task and provides the result back.
- Function without Argument without Return Value: This type of function does
not take any arguments and does not return any value. It performs a specific
task or action without providing any output to the caller.
Variables:
1. Definition:
A variable is a named storage location in a program that can hold a value. It
represents a memory location where data can be stored, retrieved, and
manipulated during the program's execution. Variables have a specific data
type, which determines the kind of data they can store.
within that block. Once the block is exited, the local variable is destroyed, and
its value is no longer available. Local variables help in encapsulating data
within a specific context and prevent accidental modification from other parts of
the program.
- Global Variables: Global variables are declared outside any function and have
a global scope. They can be accessed from anywhere in the program, including
different functions. Global variables retain their values throughout the program's
execution, and their state can be modified by any part of the code. However,
excessive use of global variables can make the program harder to understand
and maintain.
The choice between local and global variables depends on the specific
requirements of the program. Local variables are generally preferred as they
promote encapsulation and avoid unintended side effects.
Recursion:
Recursion is a programming concept where a function calls itself during its
execution. In other words, a recursive function solves a problem by reducing it
into smaller sub-problems of the same type.
When a function encounters a recursive call, it saves its current state (including
variables and return address) and executes the called function. The called
function continues the same process until a base case is reached, which triggers
the unwinding of the recursive calls. This unwinding process resumes the
execution of each function, restoring the saved state, and finally, the original
function returns its result.
Storage Classes:
1. Introduction:
Storage classes in programming languages determine the lifetime, visibility, and
scope of variables. They define how and where memory is allocated for
variables during the program's execution.
- Static: The static storage class is used to declare variables that retain their
values throughout the program's execution. Static variables are initialized only
once and persist between function calls. They have a local scope, but their
lifetime extends beyond the block or function where they are defined. Static
variables are useful when you want to preserve a value across multiple function
calls or when you want to limit the visibility of a variable to a specific scope.
- Register: The register storage class is used to suggest the compiler to store the
variable in a register instead of memory. Register variables provide faster
access, as they are stored in CPU registers, but their usage is dependent on the
compiler and hardware. The register keyword is optional, and the compiler may
choose to ignore it if there are no available registers or if the variable's address
is required.
Pointers:
1. Definition and Declaration of Pointer:
A pointer is a variable that stores the memory address of another variable.
Pointers allow direct manipulation of memory and enable efficient access to
data structures and dynamic memory allocation.
2. Pointer Initialization:
Pointer variables can be initialized in several ways:
- Assigning the address of an existing variable: `int* ptr = &
variable;`
- Using the `new` operator to allocate dynamic memory: `int* ptr = new int;`
- Initializing to null or nullptr: `int* ptr = nullptr;`
Additionally, functions can also return pointers as their return value. This is
useful when a function dynamically allocates memory and needs to provide
access to the allocated memory outside the function.
For example, given an array `int arr[5];`, the expression `arr` is equivalent to
`&arr[0]`, pointing to the first element. By incrementing the pointer, you can
traverse the array.
5. Pointer of Pointer:
A pointer can also store the memory address of another pointer. This is known
as a pointer to a pointer or a double pointer. It is useful in scenarios where you
want to modify a pointer variable from within a function or when dealing with
dynamically allocated multi-dimensional arrays.
- Call by Value: In call by value, the function receives a copy of the passed
value. Any modifications made to the parameter within the function do not
affect the original value in the calling code.
In C and C++, dynamic memory allocation is performed using the `new` and
`delete` keywords.
To declare a structure or union, you define its name and list its members along
with their data types.
2. Array of Structures:
You can create an array of structures by declaring a structure and then declaring
an array of that structure type. This allows you to store multiple instances of the
structure, each with its own set of values.
For example, if you have a structure called `Person` with members like `name`,
`age`, and `address`, you can create an array of `Person` structures to store
multiple people's information.
4. Pointer to Structure:
A pointer to a structure is a variable that stores the memory address of a
structure. It allows you to access and manipulate the structure's members using
the pointer.
5. Nested Structure:
A nested structure is a structure that is a member of another structure. This
allows you to create hierarchical relationships between structures.
For example, you can have a structure called `Address` nested within the
`Person` structure. This allows you to group related data together and access
them using the appropriate hierarchy.
6. Self-Referential Structure:
A self-referential structure, also known as a recursive structure, is a structure
that contains a member that is a pointer to the same type of structure.
This concept is commonly used when working with linked lists, trees, and other
data structures that require self-referencing elements. The self-referential
member allows the structure to point to another instance of the same structure,
forming a chain or hierarchy.
- Typedef: The `typedef` keyword is used to create a new name (alias) for an
existing data type, including structures and unions. It allows you to define a new
name that can be used interchangeably with the original type.
For example, you can use `typedef struct Person { ... } Person;` to define a new
type `Person` that represents the structure. This simplifies the declaration and
usage of the structure.
File Handling:
1. Introduction
:
File handling refers to the process of reading from and writing to files in a
computer system. It allows programs to store and retrieve data persistently on
secondary storage devices like hard drives.
- getche(): Reads a single character from the standard input and displays it on
the screen.
- putche(): Writes a single character to the standard output and displays it on the
screen.
3. Formatted Input:
- scanf(): Reads formatted input from the standard input based on the specified
format string.
- sscanf(): Reads formatted input from a string based on the specified format
string.
- fscanf(): Reads formatted input from a file based on the specified format
string.
4. File Modes:
File modes define the intended operations on a file. Common file modes
include:
These modes can be combined with a "b" flag to indicate binary mode, such as
"rb" or "wb".
Binary mode treats the file as a sequence of bytes, preserving the data as-is
without any translation. It is used for non-textual data or when precise control
over file contents is required.
2. Macro Declaration:
Macros in C are defined using the `#define` directive. They allow you to create
symbolic constants or define function-like macros that perform text substitution.
For example, `#define PI 3.14159` defines a macro `PI` with the value 3.14159.
3. Expansion:
Macro expansion refers to the process where the preprocessor replaces macro
invocations with their corresponding values or substitutions. During this
process, the preprocessor scans the code for occurrences of macros and replaces
them before the actual compilation.
4. File Inclusion:
The preprocessor allows you to include the contents of other files in your source
code using the `#include` directive. This is useful for reusing code or including
header files that contain function prototypes and definitions.
for system header files or double quotes (`" "`) for user-defined header files.
File inclusion is resolved during the preprocessing stage, where the
preprocessor replaces the `#include` directive with the actual contents of the
specified file.
Note: Proper inclusion guards or `#pragma once` directives are often used to
prevent multiple inclusions of the same file.