0% found this document useful (0 votes)
19 views

Adv C Notes

Functions allow programmers to organize code into modular, reusable units. They consist of a declaration that specifies inputs and outputs, and a definition containing the code. Functions promote code reuse, modularity, abstraction, and readability. Variables represent memory locations for storing data, and come in various scopes and storage classes. Pointers store the addresses of other variables, enabling access to dynamic memory and data structures. They are closely related to functions and arrays.

Uploaded by

Raj Katkar
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
19 views

Adv C Notes

Functions allow programmers to organize code into modular, reusable units. They consist of a declaration that specifies inputs and outputs, and a definition containing the code. Functions promote code reuse, modularity, abstraction, and readability. Variables represent memory locations for storing data, and come in various scopes and storage classes. Pointers store the addresses of other variables, enabling access to dynamic memory and data structures. They are closely related to functions and arrays.

Uploaded by

Raj Katkar
Copyright
© © All Rights Reserved
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 14

Functions:

1. Introduction & Definition of Function:


A function is a block of code that performs a specific task or a set of
instructions. It is designed to carry out a particular action and can be reused
throughout a program. Functions allow programmers to organize code into
modular and manageable units, making it easier to read, write, and maintain.

A function consists of a function header and a function body. The function


header includes the function's return type (if any), name, and parameters (if
any). The function body contains the set of instructions or statements that are
executed when the function is called.

2. Need or Use of Function:


Functions are used for several reasons:

- Code Reusability: By defining a function, you can encapsulate a specific piece


of code and reuse it whenever needed. This avoids duplicating code and makes
the program more efficient and manageable.

- Modularity: Functions enable modular programming, dividing a program into


smaller, self-contained units. This makes it easier to understand and maintain
the codebase.

- Abstraction: Functions can hide complex logic behind a simple interface.


Other parts of the program can use the function without worrying about its
internal implementation details.

- Readability: Breaking down a program into functions enhances readability. It


allows programmers to focus on specific tasks within the code.

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.

- User-defined Functions: These are functions created by the programmer to


perform specific tasks. User-defined functions are written according to the
requirements of the program and can be reused throughout the program.

4. Steps to Add or Include User-Defined Function in a Program:


- Function Declaration (Prototyping): The function declaration specifies the
function's name, return type, and parameters (if any). It informs the compiler
about the function's existence and signature before its actual implementation.

- 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 Definition (Function Implementation): The function definition


contains the actual code that is executed when the function is called. It includes
the function header and the function body, where the instructions or statements
are written.

5. Types of Functions based on Arguments and Return Value:


- Function with Argument without Return Value: This type of function takes
one or more arguments as input but does not return any value to the caller. It
performs a specific task or operation and may modify variables outside its
scope.

- 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.

2. Characteristics & Importance of Local & Global Variables:


- Local Variables: Local variables are declared within a specific block, such as a
function or a loop. They have a limited scope and are only accessible

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.

Recursion is useful for solving problems that exhibit self-similar or repetitive


structures. It provides an elegant and concise solution in many scenarios, but
excessive recursion or improperly defined base cases can lead to stack overflow
errors or infinite loops.

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.

2. Definition of Storage Classes:


- Auto: The auto storage class is the default storage class for local variables. It
allocates memory automatically when a block or function is entered and
releases it when the block or function is exited. The auto keyword is rarely used
explicitly, as it is implicitly applied to local variables by default.
- Extern: The extern storage class is used to declare a variable that is defined
outside the current scope or file. It is typically used when you want to access a
global variable defined in another file. The extern keyword informs the
compiler that the variable is defined elsewhere and should be linked during the
program's linking phase.

- 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.

To declare a pointer, you specify the data type it points to followed by an


asterisk (*) and the pointer's name. For example, `int* ptr;` declares a pointer
named `ptr` that can store the memory address of an integer.

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;`

3. Pointer and Function:


Pointers and functions have a close relationship. Pointers can be passed as
arguments to functions, allowing the function to access and modify the value
stored at the memory address pointed to by the pointer.

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.

4. Pointer and Array:


Pointers and arrays are closely related in C and C++. An array name can be
treated as a pointer to the first element of the array. You can use pointers to
access and manipulate array elements.

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.

6. Call by Value and Call by Reference:


In programming languages, parameters can be passed to functions using
different mechanisms.

- 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.

- Call by Reference: In call by reference, the function receives the memory


address (reference) of the passed variable. Any modifications made to the
parameter within the function affect the original value in the calling code.

Call by reference is achieved in C and C++ by passing pointers as function


arguments. By dereferencing the pointer, the function can access and modify the
original value.

Dynamic Memory Allocation:


Dynamic memory allocation allows programs to request memory from the
operating system at runtime. It is useful when you need to allocate memory for
variables whose size or lifetime cannot be determined at compile time.

In C and C++, dynamic memory allocation is performed using the `new` and
`delete` keywords.

- `new` is used to allocate memory for a single variable or an array dynamically.


It returns a pointer to the allocated memory.
- `delete` is used to deallocate memory that was previously allocated using
`new`. It frees the memory and makes it available for reuse.

Dynamic memory allocation is commonly used when working with data


structures of unknown or varying size, implementing dynamic lists, trees, and
other data structures.
It's important to note that when using dynamic memory allocation, it is the
programmer's responsibility to deallocate the memory when it is no longer
needed to avoid memory leaks.

Structures and Union:


1. Definition and Declaration:
Structures and unions are composite data types in C and C++ that allow you to
combine multiple variables of different data types into a single unit.

- Structure: A structure is a user-defined data type that allows you to group


related variables under a single name. It provides a way to represent a collection
of different data types as a single entity. The variables within a structure are
called members or fields.

- Union: A union is similar to a structure but differs in how memory is


allocated. In a union, all members share the same memory location, allowing
them to occupy the same space. Only one member of the union can be accessed
at a time, but they all refer to the same memory location.

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.

3. Passing Structure to a Function:


You can pass a structure to a function in C and C++ by either passing it directly
as an argument or passing a pointer to the structure.

- Passing by Value: When passing a structure by value, a copy of the structure is


made and passed to the function. Any modifications made to the structure
within the function do not affect the original structure.

- Passing by Pointer: When passing a pointer to a structure, the function can


access and modify the original structure. Changes made to the structure within
the function will persist outside the function.

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.

To declare a pointer to a structure, you specify the structure type followed by an


asterisk (*) and the pointer's name. For example, `struct Person* ptr;` declares a
pointer named `ptr` that can store the memory address of a `Person` structure.

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.

7. Size of and Type Def:


- Sizeof: The `sizeof` operator is used to determine the size, in bytes, of a
structure or union. It returns the total memory occupied by the structure,
including padding for alignment.

- 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.

2. Standard Input/Output Functions:


- getchar(): Reads a single character from the standard input (keyboard).
- getch(): Reads a single character from the standard input without displaying it
on the screen.

- getche(): Reads a single character from the standard input and displays it on
the screen.

- putchar(): Writes a single character to the standard output (console).

- putch(): Writes a single character to the standard output without displaying 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:

- "r": Open an existing file for reading.


- "w": Create a new file for writing. If the file already exists, its contents are
truncated.
- "a": Open a file for appending. Data is written at the end of the file.
- "r+": Open an existing file for both reading and writing.
- "w+": Create a new file for both reading and writing, truncating the file if it
exists.
- "a+": Open a file for both reading and appending.

These modes can be combined with a "b" flag to indicate binary mode, such as
"rb" or "wb".

5. Text and Binary Mode:


Text mode treats the file as a sequence of characters, where newline characters
may be translated between different platforms (e.g., '\n' on Unix, "\r\n" on
Windows).

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.

Macros and Preprocessing:


1. Features of C Preprocessor:
The C preprocessor is a part of the compilation process that performs various
text manipulations before the actual compilation. It is responsible for macro
substitution, file inclusion, and conditional compilation.

Some features of the C preprocessor include:


- Macro substitution: The preprocessor replaces macros defined using `#define`
with their corresponding values throughout the code.
- File inclusion: The preprocessor includes the contents of other files in the
source code using the `#include` directive.

- Conditional compilation: The preprocessor allows code blocks to be included


or excluded based on certain conditions using directives such as `#if`, `#ifdef`,
and `#ifndef`.

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 example, `#include <stdio.h>` includes the contents of the standard


input/output library header file.

File inclusion can be done using angle brackets (`< >`)

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.

You might also like