0% found this document useful (0 votes)
4 views42 pages

C Program Module 2-4

The document provides an overview of input and output operators in C, including functions like getchar(), scanf(), putchar(), and printf() for reading and writing characters. It also covers decision-making structures such as if statements, loops (while, do-while, for), and jump statements (break, continue, goto), along with arrays and dynamic arrays for managing collections of data. Additionally, it explains the concept of strings in C as arrays of characters terminated by a null character.

Uploaded by

mjb7dyf6yw
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views42 pages

C Program Module 2-4

The document provides an overview of input and output operators in C, including functions like getchar(), scanf(), putchar(), and printf() for reading and writing characters. It also covers decision-making structures such as if statements, loops (while, do-while, for), and jump statements (break, continue, goto), along with arrays and dynamic arrays for managing collections of data. Additionally, it explains the concept of strings in C as arrays of characters terminated by a null character.

Uploaded by

mjb7dyf6yw
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Managing Input and Output Operators

Reading a Character:

1. Using getchar()

• getchar() reads a single character from standard input (usually the keyboard).

• It waits until the user presses the Enter key and returns the entered character as an int
(ASCII value).

Example:

#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
ch = getchar(); // Read a character
printf("You entered: ");
putchar(ch); // Display the character
return 0;
}

• If you enter A, it will display A.

• getchar() can also read whitespace characters like spaces, tabs, and newlines.

2. Using scanf()

• scanf("%c", &ch) reads a single character from the input and stores it in the variable ch.

Example:

#include <stdio.h>
int main() {
char ch;
printf("Enter a character: ");
scanf("%c", &ch);
printf("You entered: %c\n", ch);
return 0;
}

• If you enter B, it will display B.

Writing a Character:

1. Using putchar()

• putchar() writes a single character to the standard output.

Example:
#include <stdio.h>
int main() {
char ch = 'A';
putchar(ch); // Output: A
return 0;
}

2. Using printf()

• printf() can also print characters using the %c format specifier.

Example:

#include <stdio.h>
int main() {
char ch = 'B';
printf("Character: %c\n", ch);
return 0;
}

2. Formatted Input and Output

Formatted input and output functions allow structured reading and displaying of data:

Formatted Input using scanf()

• scanf() reads input based on format specifiers and stores the values in the corresponding
variables.

• It stops reading when it encounters whitespace or a non-matching character.

Example:

#include <stdio.h>
int main() {
int a;
float b;
char ch;
printf("Enter an integer, a float, and a character: ");
scanf("%d %f %c", &a, &b, &ch);
printf("You entered: %d, %.2f, %c\n", a, b, ch);
return 0;
}
Format Specifier Description Example
%d Integer 42
%f Float 3.14
%c Character A
%s String "Hello"
%lf Double 3.1415
Formatted Output using printf()

• printf() formats and displays values based on format specifiers.

Example:

#include <stdio.h>
int main() {
int a = 42;
float b = 3.14;
char ch = 'X';
printf("Integer: %d\n", a);
printf("Float: %.2f\n", b);
printf("Character: %c\n", ch);
return 0;
}

Format Specifier Description Example Output


%d Integer 42
%f Float 3.14
%.2f Float (2 decimal places) 3.14
%c Character X
%s String Hello

Decision Making

Decision-making allows programs to execute different instructions depending on the


evaluation of conditions.

1. If

Syntax:

if (condition) {
// Code to execute if condition is true
}

Example:

#include <stdio.h>
int main() {
int num = 10;
if (num > 5) {
printf("Number is greater than 5\n");
}
return 0;
}

2. If-Else Statement
Syntax:

if (condition) {
// Code to execute if condition is true
} else {
// Code to execute if condition is false
}

Example:

int num = 10;


if (num > 5) {
printf("Greater than 5");
} else {
printf("Less than or equal to 5");
}

3. Else-If Ladder

Syntax:

if (condition1) {
// Code if condition1 is true
} else if (condition2) {
// Code if condition2 is true
} else {
// Code if no condition is true
}

Example:

int num = 0;
if (num > 0) {
printf("Positive");
} else if (num < 0) {
printf("Negative");
} else {
printf("Zero");
}

4. Switch Statement

Syntax:

switch(expression) {
case value1:
// Code
break;
case value2:
// Code
break;
default:
// Code
}
Example:

int day = 2;
switch(day) {
case 1: printf("Monday"); break;
case 2: printf("Tuesday"); break;
default: printf("Invalid day");
}

5. Conditional Operator

Syntax:

result = (condition) ? value_if_true : value_if_false;

Example:

int a = 10;
int b = (a > 5) ? 1 : 0;
printf("%d", b);

Loops

A loop is used to execute a block of code repeatedly as long as a specified condition is true.
Loops help reduce code repetition and make programs more efficient.

Types of Loops:

1. While Loop

2. Do-While Loop

3. For Loop

4. Nested Loops

While Loop

The while loop executes a block of code as long as the specified condition is true.

Syntax:

while (condition) {
// Code to execute
}

• The condition is evaluated before entering the loop.

• If the condition is true, the body of the loop is executed.

• After executing the loop body, the condition is re-evaluated.


• If the condition is false, the loop stops.

Example 1: Print numbers from 1 to 5 using a while loop

#include <stdio.h>
int main() {
int i = 1; // Initialization
while (i <= 5) { // Condition
printf("%d\n", i);
i++; // Update
}
return 0;
}

Output:

1
2
3
4
5

Do-While Loop

The do-while loop executes the loop body at least once and then checks the condition.

Syntax:

do {
// Code to execute
} while (condition);

• The loop body is executed first.

• The condition is evaluated after the execution of the loop body.

• If the condition is true, the loop repeats.

• If the condition is false, the loop stops.

Example: Print numbers from 1 to 5 using a do-while loop

#include <stdio.h>
int main() {
int i = 1;
do {
printf("%d\n", i);
i++;
} while (i <= 5);
return 0;
}

Output:

1
2
3
4
5

Key Difference from while:

• The do-while loop executes at least once, even if the condition is false initially.

Example:

int x = 5;
do {
printf("Hello\n");
} while (x < 0);

• Output: Hello (executed once even though the condition is false).

For Loop

The for loop is used when the number of iterations is known beforehand.

Syntax:

for (initialization; condition; update) {


// Code to execute
}

• Initialization – Sets the starting value of the loop variable.

• Condition – Evaluated before each iteration; if true, the loop executes; if false, the loop
stops.

• Update – Adjusts the loop variable after each iteration.

Example: Print numbers from 1 to 5 using a for loop

#include <stdio.h>
int main() {
for (int i = 1; i <= 5; i++) {
printf("%d\n", i);
}
return 0;
}

Output:

1
2
3
4
5
Example: Reverse counting using a for loop

#include <stdio.h>
int main() {
for (int i = 5; i >= 1; i--) {
printf("%d\n", i);
}
return 0;
}

Output:

5
4
3
2
1

Example: Increment by 2

#include <stdio.h>
int main() {
for (int i = 0; i <= 10; i += 2) {
printf("%d\n", i);
}
return 0;
}

Output:

0
2
4
6
8
10

Nested Loops

A loop inside another loop is called a nested loop.

Syntax:

for (int i = 0; i < 3; i++) {


for (int j = 0; j < 3; j++) {

}
}

• The outer loop runs first.

• For each iteration of the outer loop, the inner loop runs completely.

#include <stdio.h>
int main() {

int n = 5;

for (int i = 1; i <= n; i++)

for (int j = 1; j <= i; j++)

printf("* "); // Print star

printf("\n");

return 0;

Jump Statements

Jump statements alter the normal sequence of execution:

Statement Description
break Exits the loop or switch statement immediately.
continue Skips the current iteration and jumps to the next.
goto Transfers control to a labeled statement.

Break Statement

• break is used to terminate a loop or a switch statement prematurely.

• Control passes to the statement after the loop or switch.

Example: Stop the loop when i = 3

for (int i = 1; i <= 5; i++) {


if (i == 3) {
break;
}
printf("%d\n", i);
}

Output:
1
2

Continue Statement

• continue skips the current iteration and moves to the next.

Example: Skip printing number 3

for (int i = 1; i <= 5; i++) {


if (i == 3) {
continue;
}
printf("%d\n", i);
}

Output:

1
2
4
5

Goto Statement

• goto jumps to a labeled statement.

• It is generally discouraged because it makes code hard to understand.

Syntax:

goto label;
label:
// Code to execute

Example:

int i = 1;
start:
if (i <= 5) {
printf("%d\n", i);
i++;
goto start;
}

Output:

1
2
3
4
5
Unit -3

Arrays in C

An array is a collection of similar data elements stored at contiguous memory locations. It


allows storing multiple values of the same type under a single variable name, which can be
accessed using an index.

One-Dimensional Array

A one-dimensional array stores a list of elements of the same data type in a single row or line.

1.1 Declaration of One-Dimensional Array

To declare an array, use the following syntax:

data_type array_name[size];

• data_type – Type of data (e.g., int, float, char, etc.)

• array_name – Name of the array

• size – Number of elements in the array

Example:

int numbers[5]; // Declares an integer array of size 5

1.2 Initialization of One-Dimensional Array

You can initialize an array in multiple ways:

Method 1: Assigning values at the time of declaration

int numbers[5] = {10, 20, 30, 40, 50};

Method 2: Letting the compiler determine the size

int numbers[] = {10, 20, 30, 40, 50};

Method 3: Assigning values one by one

int numbers[5];
numbers[0] = 10;
numbers[1] = 20;
numbers[2] = 30;
numbers[3] = 40;
numbers[4] = 50;

1.3 Accessing Elements of a One-Dimensional Array

• Array elements are accessed using an index (starting from 0).

• To access the i-th element, use:

array_name[i];

Example:

#include <stdio.h>
int main() {
int numbers[5] = {10, 20, 30, 40, 50};
for (int i = 0; i < 5; i++) {
printf("%d\n", numbers[i]); // Access and display each element
}
return 0;
}

Output:

10
20
30
40
50

Two-Dimensional Array

A two-dimensional array is an array of arrays, used to store data in a tabular format (rows and
columns).

2.1 Declaration of Two-Dimensional Array

To declare a two-dimensional array:

data_type array_name[rows][columns];

Example:

int matrix[3][4]; // Declares a 3x4 matrix

• matrix[3][4] means 3 rows and 4 columns.

2.2 Initialization of Two-Dimensional Array

Method 1: Assigning values directly


int matrix[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};

Method 2: Assigning values one by one

int matrix[3][4];
matrix[0][0] = 1;
matrix[0][1] = 2;
matrix[0][2] = 3;
matrix[0][3] = 4;

2.3 Accessing Elements of a Two-Dimensional Array

• Elements are accessed using row and column indices.

• Syntax:

array_name[row][column];

Example:

#include <stdio.h>
int main() {
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};

for (int i = 0; i < 3; i++) { // Row loop


for (int j = 0; j < 3; j++) { // Column loop
printf("%d ", matrix[i][j]);
}
printf("\n");
}

return 0;
}

Output:

1 2 3
4 5 6
7 8 9

Multi-Dimensional Arrays

A multi-dimensional array is an array with more than two dimensions.

3.1 Declaration of a Multi-Dimensional Array


Syntax:

data_type array_name[size1][size2][size3]...[sizeN];

Example:

• A 3D array of size 2 x 3 x 4:

int array[2][3][4];

3.2 Initialization of a Multi-Dimensional Array

Example:

int array[2][3][4] =
{
{
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
},
{
{13, 14, 15, 16},
{17, 18, 19, 20},
{21, 22, 23, 24}
}
};

3.3 Accessing Elements of a Multi-Dimensional Array

Example:

#include <stdio.h>
int main() {
int array[2][2][3] = {
{
{1, 2, 3},
{4, 5, 6}
},
{
{7, 8, 9},
{10, 11, 12}
}
};

for (int i = 0; i < 2; i++) {


for (int j = 0; j < 2; j++) {
for (int k = 0; k < 3; k++) {
printf("%d ", array[i][j][k]);
}
printf("\n");
}
printf("\n");
}
return 0;
}

Dynamic Arrays in C

A dynamic array is an array whose size is determined during runtime. Unlike static arrays,
where the size is fixed at compile time, dynamic arrays allow for flexible memory allocation
and resizing based on the program’s requirements.

In C, dynamic memory allocation is managed using the following functions from the stdlib.h
library:

• malloc() – Allocates memory but does not initialize it.

• calloc() – Allocates memory and initializes it to zero.

• realloc() – Resizes an already allocated memory block.

• free() – Frees the dynamically allocated memory to avoid memory leaks.

Why Use Dynamic Arrays?

• The size of static arrays must be known at compile time.

• If the size requirement is not known beforehand, dynamic arrays allow for adjusting the size
at runtime.

• Efficient use of memory as memory can be increased or decreased as required.

Strings in C

In C, a string is defined as an array of characters terminated by a null character ('\0'). The null
character marks the end of the string, allowing functions to identify where the string ends.

1. Declaring Strings

Syntax:

char str[size];

• char – Data type for character strings

• size – Number of characters in the string including the null character ('\0')

Example 1:

char str[20] = "Hello";

• The string Hello is stored as:


H e l l o \0

Example 2:

Using a character array:

char str[] = {'H', 'e', 'l', 'l', 'o', '\0'};

Example 3:

Using a pointer:

char *str = "Hello";

2. Reading and Writing Strings

2.1 scanf() and printf()

• scanf() reads a string from standard input.

• printf() prints a string to standard output.

Example:

#include <stdio.h>

int main() {
char name[20];

printf("Enter your name: ");


scanf("%s", name); // Reads until a space or newline

printf("Hello, %s\n", name);

return 0;
}

Output:

Enter your name: John


Hello, John

2.2 Using gets() and puts()

• gets() reads an entire line including spaces. (Deprecated in modern C)

• puts() prints a string followed by a newline.

Example:

#include <stdio.h>
int main() {
char name[50];

printf("Enter your full name: ");


gets(name); // Unsafe, may cause buffer overflow

puts("Your name is:");


puts(name);

return 0;
}

2.3 Using fgets()

• fgets() reads a string including spaces.

• It prevents buffer overflow by limiting input size.

Example:

#include <stdio.h>

int main() {
char name[50];

printf("Enter your full name: ");


fgets(name, sizeof(name), stdin); // Read input safely

printf("Your name is: %s", name);

return 0;
}

3. Arithmetic Operations on Characters

Since characters are represented by ASCII values internally, they can be manipulated using
arithmetic operations.

Example 1: Adding Characters

#include <stdio.h>

int main() {
char c = 'A';
c = c + 1; // Increment ASCII value of 'A' (65) by 1

printf("%c\n", c); // Output: B

return 0;
}

Example 2: Subtracting Characters


#include <stdio.h>

int main() {
char c = 'D';
printf("%d\n", c - 'A'); // Output: 3

return 0;
}

4. Comparison of Strings

You cannot directly compare strings using == because strings are pointers to memory
locations.

4.1 Using strcmp()

• strcmp() compares two strings:

• Returns 0 if both strings are equal.

• Returns a positive value if the first string is greater.

• Returns a negative value if the first string is smaller.

Example:

#include <stdio.h>
#include <string.h>

int main() {
char str1[] = "Hello";
char str2[] = "World";

if (strcmp(str1, str2) == 0) {
printf("Strings are equal\n");
} else {
printf("Strings are not equal\n");
}

return 0;
}

. String Handling Functions

The <string.h> header provides various functions to handle strings.

5.1 strlen() – Length of a String

Returns the length of the string (excluding the null character).

Example:

#include <stdio.h>
#include <string.h>
int main() {
char str[] = "Hello World";

printf("Length of the string: %lu\n", strlen(str));

return 0;
}

5.2 strcpy() – Copy String

Copies one string into another.

Example:

#include <stdio.h>
#include <string.h>

int main() {
char str1[] = "Hello";
char str2[20];

strcpy(str2, str1);

printf("Copied String: %s\n", str2);

return 0;
}

5.3 strcat() – Concatenate Strings

Appends one string to another.

Example:

#include <stdio.h>
#include <string.h>

int main() {
char str1[20] = "Hello";
char str2[] = " World";

strcat(str1, str2);

printf("Concatenated String: %s\n", str1);

return 0;
}

5.4 strcmp() – Compare Strings

Compares two strings.

Example:

#include <stdio.h>
#include <string.h>
int main() {
char str1[] = "Hello";
char str2[] = "World";

if (strcmp(str1, str2) == 0) {
printf("Strings are equal\n");
} else {
printf("Strings are not equal\n");
}

return 0;
}

5.5 strchr() – Find a Character in a String

Returns a pointer to the first occurrence of a character in a string.

Example:

#include <stdio.h>
#include <string.h>

int main() {
char str[] = "Hello World";
char *pos = strchr(str, 'o');

if (pos != NULL) {
printf("Character found at position: %ld\n", pos - str);
} else {
printf("Character not found\n");
}

return 0;
}

5.6 strstr() – Find a Substring

Returns a pointer to the first occurrence of a substring in a string.

Example:

#include <stdio.h>
#include <string.h>

int main() {
char str[] = "Hello World";
char *pos = strstr(str, "World");

if (pos != NULL) {
printf("Substring found at position: %ld\n", pos - str);
} else {
printf("Substring not found\n");
}

return 0;
}
5.7 strrev() – Reverse a String (Not part of standard C, but can be implemented)

#include <stdio.h>
#include <string.h>

void reverseString(char *str) {


int len = strlen(str);
for (int i = 0; i < len / 2; i++) {
char temp = str[i];
str[i] = str[len - i - 1];
str[len - i - 1] = temp;
}
}

int main() {
char str[] = "Hello";
reverseString(str);
printf("Reversed String: %s\n", str);
return 0;
}

Summary of String Functions

Function Description
strlen() Length of string
strcpy() Copy string
strcat() Concatenate strings
strcmp() Compare strings
strchr() Find character in string
strstr() Find substring
strrev() Reverse string (custom implementation)

Functions in C

Functions are reusable blocks of code designed to perform a specific task. They allow
programmers to break down complex problems into smaller, manageable parts, improving the
clarity, reusability, and efficiency of the code.

Functions provide the following benefits:

• Code Reusability – Write once, use multiple times.

• Modularity – Divides the program into smaller, manageable parts.

• Readability – Improves code organization and clarity.

• Debugging – Makes it easier to test and debug individual parts of a program.

• Reduces Code Length – Avoids repetition of code.


Types of functions

1. Library functions /pre defined functions /standard functions /built in functions


2. User defined functions

. Library functions

These functions are defined in the library of C compiler which are used frequently in the C
program.

User defined functions

A user-defined function in C consists of the following components:

Function Declaration

• Informs the compiler about the function name, return type, and parameters.

• Placed before main() or in a header file.

Function Definition

• Contains the actual code for the function.

• It defines the return type, function name, and parameter list.

Function Call

• Invokes the function and transfers control to the function body.

• Returns control to the caller after execution.

Function Syntax:

return_type function_name(parameters) {
// Function body
}

Example:

#include <stdio.h>

// Function declaration
int add(int, int);

int main() {
int sum = add(5, 7); // Function call
printf("Sum: %d\n", sum);
return 0;
}

// Function definition
int add(int a, int b) {
return a + b; // Return statement
}

Return Values and Their Types

A function can return a value to the calling function using the return statement.

Return Types:

Return Type Description


void No return value
int Returns an integer
float Returns a float
char Returns a character
double Returns a double

Example: Returning an Integer

int getNumber() {
return 42;
}

Example: Returning a String

char* getMessage() {
return "Hello, World!";
}

Function Call and Declaration

Function Declaration

• Placed before main() or in a header file.

• Informs the compiler about the function’s name, return type, and parameters.

Example:

int add(int, int); // Declaration

Function Call

• Transfers control to the function body.

• Function parameters are evaluated and passed.

Example:
int sum = add(3, 5);

Call by Value vs. Call by Reference

Call by Value

• The actual value is passed to the function.

• Changes to the parameter within the function do not affect the original value.

Example:

#include <stdio.h>

void modifyValue(int a) {
a = 20;
}

int main() {
int x = 10;
modifyValue(x);
printf("%d\n", x); // Output: 10
return 0;
}

Call by Reference

• The memory address of the argument is passed to the function.

• Changes to the parameter within the function affect the original value.

Example:

#include <stdio.h>

void modifyValue(int *a) {


*a = 20;
}

int main() {
int x = 10;
modifyValue(&x);
printf("%d\n", x); // Output: 20
return 0;
}

Categories of Functions

No Arguments and No Return Value

• Function is called without arguments and does not return a value.


Example:

void display() {
printf("Hello");
}

int main() {
display();
return 0;
}

Arguments but No Return Value

• Function accepts parameters but does not return a value.

Example:

void greet(char name[]) {


printf("Hello, %s\n", name);
}

int main() {
greet("John");
return 0;
}

No Arguments but Returns a Value

• Function does not accept parameters but returns a value.

Example:

int getNumber() {
return 42;
}

int main() {
int num = getNumber();
printf("%d\n", num);
return 0;
}

Arguments and Returns a Value

• Function accepts parameters and returns a value.


Example:

int sum(int a, int b) {


return a + b;
}

int main() {
int result = sum(5, 3);
printf("%d\n", result);
return 0;
}

Nesting of Functions

A function can be called within another function.

A function definition cannot appear inside another function.

Example:

#include <stdio.h>

int sum(int a, int b) {


return a + b;
}

int main() {
int result = sum(sum(2, 3), sum(4, 5));
printf("%d\n", result);
return 0;
}

Recursion

A recursive function is a function that calls itself.

Requires a base condition to avoid infinite recursion.

Example: Factorial using Recursion

#include <stdio.h>

int factorial(int n) {
if (n == 0) return 1;
return n * factorial(n - 1);
}

int main() {
printf("%d\n", factorial(5)); // Output: 120
return 0;
}
Command Line Arguments

Command line arguments allow passing input values when executing a program.

• argc – Number of arguments.

• argv – Array of character pointers containing the arguments.

Example:

#include <stdio.h>

int main(int argc, char *argv[]) {


for (int i = 0; i < argc; i++) {
printf("Argument %d: %s\n", i, argv[i]);
}
return 0;
}

Execution:

./program Hello World

Output:

Argument 0: ./program
Argument 1: Hello
Argument 2: World

Passing Arrays to Functions

Arrays are passed to functions by reference (address is passed).

Example:

#include <stdio.h>

void display(int arr[], int size) {


for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
}

int main() {
int arr[] = {1, 2, 3, 4, 5};

Passing Strings to a Function

In C, strings are arrays of characters terminated by '\0'. When passed to a function, the base
address of the string is passed, allowing direct access and modification of the original string.
Methods of Passing Strings

• Pass by Value: Use const to prevent modification.

• Pass by Reference: Directly pass the string; changes will reflect in the original string.

Syntax

void function_name(char str[]) {


// Function body
}

or

void function_name(char *str) {


// Function body
}

Examples

Passing and Displaying a String

void display(char str[]) {


printf("%s", str);
}

int main() {
char str[] = "Hello";
display(str);
}

Unit IV

Storage Classes in C

Storage classes in C define the scope, visibility, and lifetime of variables. They determine
how and where variables are stored, how long they persist, and how they are accessed.

Types of Storage Classes

1. auto

2. register

3. static

4. extern

1. auto Storage Class

• Scope: Local to the block where defined.


• Visibility: Accessible only within the block.

• Lifetime: Created when the block is entered and destroyed when exited.

• Storage: Stored in the memory (RAM).

• Default storage class for local variables.

Example:

#include <stdio.h>

void example() {
auto int x = 10; // auto keyword is optional
printf("%d\n", x);
}

int main() {
example();
}

Output:

10

2. register Storage Class

• Scope: Local to the block where defined.

• Visibility: Accessible only within the block.

• Lifetime: Created when the block is entered and destroyed when exited.

• Storage: Stored in the CPU registers (if available) for faster access.

• Cannot get the address using & operator.

Example:

#include <stdio.h>

void example() {
register int x = 5;
printf("%d\n", x);
}

int main() {
example();
}

Output:

5
3. static Storage Class

• Scope: Local to the block where defined.

• Visibility: Accessible only within the block.

• Lifetime: Exists for the entire program execution.

• Storage: Stored in memory (not stack).

• Maintains value between function calls.

Example:

#include <stdio.h>

void example() {
static int x = 0;
x++;
printf("%d\n", x);
}

int main() {
example(); // Output: 1
example(); // Output: 2
}

4. extern Storage Class

• Scope: Global (accessible from multiple files).

• Visibility: Accessible across multiple files.

• Lifetime: Exists for the entire program execution.

• Storage: Stored in memory.

• Declared using extern keyword.

Example (Two Files):

File 1: file1.c

#include <stdio.h>

int x = 10;

void display() {
printf("%d\n", x);
}

File 2: file2.c
#include <stdio.h>

extern int x; // Declaration of external variable

int main() {
printf("%d\n", x);
}

Output:

10

Structure

A structure is a collection of variables of different data types grouped under a single name.

Defining a Structure

struct Student {
int id;
char name[50];
float marks;
};

Giving Values to Structure Members

1. Using direct assignment

2. Using scanf or gets

#include <stdio.h>

struct Student {
int id;
char name[50];
float marks;
};

int main() {
struct Student s1;
[Link] = 101;
[Link] = 85.5;
strcpy([Link], "John");

printf("ID: %d\n", [Link]);


printf("Name: %s\n", [Link]);
printf("Marks: %.2f\n", [Link]);
return 0;
}

Initialization of Structure

You can initialize a structure at the time of declaration:

struct Student s1 = {101, "John", 85.5};


Comparison of Structure Variables

You cannot directly compare structures using ==. Use memcmp() or compare individual
members:

if ([Link] == [Link] && strcmp([Link], [Link]) == 0) {


printf("Structures are equal");
}

Array of Structures

An array of structures is defined like this:

struct Student s[3];

Example:

#include <stdio.h>

struct Student {
int id;
char name[50];
};

int main() {
struct Student s[3] = {{101, "John"}, {102, "Alex"}, {103, "Mary"}};

for (int i = 0; i < 3; i++) {


printf("ID: %d, Name: %s\n", s[i].id, s[i].name);
}

return 0;
}

Arrays within Structures

You can define an array inside a structure:

struct Student {
int id;
char name[50];
int marks[5];
};

Structures within Structures

A structure can contain another structure as a member:

struct Date {
int day;
int month;
int year;
};
struct Student {
int id;
char name[50];
struct Date dob;
};

Passing Structures to Functions

You can pass a structure by value or reference:

Pass by Value:

void display(struct Student s) {


printf("ID: %d, Name: %s", [Link], [Link]);
}

Pass by Reference:

void display(struct Student *s) {


printf("ID: %d, Name: %s", s->id, s->name);
}

Union

A union allows storing different types of data in the same memory location. Memory is
shared by all members.

Defining a Union

union Data {
int i;
float f;
char str[20];
};

Accessing Union Members

Only one member can store data at a time:

#include <stdio.h>

union Data {
int i;
float f;
char str[20];
};

int main() {
union Data data;
data.i = 10;
printf("i = %d\n", data.i);
data.f = 220.5;
printf("f = %.2f\n", data.f);
strcpy([Link], "C Programming");
printf("str = %s\n", [Link]);
return 0;
}

Difference Between Structure and Union

Feature Structure Union


Memory Allocates memory for all members Allocates memory for the largest
member
Size Total size = sum of all members’ size Size = size of the largest member
Access All members can store values Only one member can store a
simultaneously value at a time
Use Used when all members need to be stored Used when only one member is
simultaneously needed at a time

Pointers in C

A pointer is a variable that stores the memory address of another variable. Instead of storing a
value directly, a pointer stores the location in memory where the value is stored.

Declaration

The syntax to declare a pointer is:

data_type *pointer_name;

Examples:

int *ptr; // Pointer to an integer


char *cptr; // Pointer to a character
float *fptr; // Pointer to a float

Initialization

You can assign the address of a variable to a pointer using the address-of operator (&):

int x = 10;
int *ptr = &x;

Accessing a Variable Through Address and Pointer

1. Direct Access:

int x = 10;
printf("%d", x);

2. Access Using Pointer:

Use the dereference operator (*) to access the value stored at the address:
int x = 10;
int *ptr = &x;
printf("%d", *ptr); // Output: 10

Pointer Expressions

You can perform arithmetic operations on pointers like addition and subtraction:

Pointer Addition:

Adding a value to a pointer increases its value by the size of the data type.

int arr[] = {10, 20, 30};


int *ptr = arr;
printf("%d\n", *ptr); // Output: 10
ptr++; // Moves to the next integer (size = 4 bytes)
printf("%d\n", *ptr); // Output: 20

Pointer Subtraction:

Subtracting a value from a pointer decreases its value by the size of the data type.

ptr--;
printf("%d\n", *ptr); // Output: 10

Difference Between Pointers:

The difference between two pointers gives the number of elements between them:

int arr[] = {10, 20, 30};


int *ptr1 = &arr[0];
int *ptr2 = &arr[2];
printf("%ld", ptr2 - ptr1); // Output: 2

Pointer Increments and Scale Factor

When you increment a pointer, it increases by the size of the data type:

Data Type Size (Bytes)


int 4
char 1
float 4
double 8

Example:

int arr[] = {10, 20, 30};


int *ptr = arr;

printf("%d\n", *ptr); // Output: 10


ptr++; // Increments by 4 bytes (size of int)
printf("%d\n", *ptr); // Output: 20
Pointers and Arrays

An array name acts as a constant pointer to the first element of the array.

int arr[] = {10, 20, 30};


int *ptr = arr;

printf("%d\n", *(ptr)); // Output: 10


printf("%d\n", *(ptr + 1)); // Output: 20
printf("%d\n", *(ptr + 2)); // Output: 30

Pointer to Array:

You can pass an array to a function using a pointer:

void display(int *arr, int size) {


for (int i = 0; i < size; i++) {
printf("%d ", *(arr + i));
}
}

int main() {
int arr[] = {10, 20, 30};
display(arr, 3);
}

Pointers and Functions

You can pass pointers to functions to modify data directly:

Pass by Value:

Passing a copy of the value:

void modify(int x) {
x = 20;
}

int main() {
int num = 10;
modify(num);
printf("%d", num); // Output: 10
}

Pass by Reference:

Passing the address using a pointer allows modification of the original value:

void modify(int *x) {


*x = 20;
}
int main() {
int num = 10;
modify(&num);
printf("%d", num); // Output: 20
}

Returning a Pointer from a Function:

int* getPointer() {
static int x = 10;
return &x;
}

int main() {
int *ptr = getPointer();
printf("%d", *ptr); // Output: 10
}

Pointers and Structures

Pointers can store the address of a structure and access members using -> operator.

Example:

#include <stdio.h>

struct Student {
int id;
char name[50];
};

int main() {
struct Student s1 = {101, "John"};
struct Student *ptr = &s1;

printf("ID: %d\n", ptr->id);


printf("Name: %s\n", ptr->name);

return 0;
}

Accessing Structure Members Using Pointers:

• ptr->id is equivalent to (*ptr).id

• ptr->name is equivalent to (*ptr).name

Pointer to Structure as a Function Argument

You can pass a pointer to a structure to a function:

#include <stdio.h>

struct Student {
int id;
char name[50];
};

void display(struct Student *s) {


printf("ID: %d\n", s->id);
printf("Name: %s\n", s->name);
}

int main() {
struct Student s1 = {101, "John"};
display(&s1);
return 0;
}

Pointer to Pointer (Double Pointer)

A pointer can store the address of another pointer:

int x = 10;
int *ptr = &x;
int **pptr = &ptr;

printf("%d", **pptr); // Output: 10

Dynamic Memory Allocation

Dynamic memory allocation in C allows programs to request and manage memory during
runtime, providing flexibility when the required memory size isn’t known at compile time.

Key Functions for Dynamic Memory Allocation in C:

1. malloc() (Memory Allocation):

• Purpose: Allocates a specified number of bytes and returns a pointer to the first byte of the
allocated memory.

• Syntax: void* malloc(size_t size);

• Details: The memory allocated by malloc() is uninitialized, meaning it may contain garbage
values. It’s essential to check if the allocation was successful by verifying that the returned
pointer is not NULL.

• Example:

int* ptr = (int*)malloc(10 * sizeof(int));


if (ptr == NULL) {
// Handle memory allocation failure
}

2. calloc() (Contiguous Allocation):


• Purpose: Allocates memory for an array of elements, initializes all bytes to zero, and returns
a pointer to the allocated memory.

• Syntax: void* calloc(size_t num_elements, size_t element_size);

• Details: Unlike malloc(), calloc() initializes the allocated memory to zero, ensuring that all
elements start with a known value.

• Example:

int* ptr = (int*)calloc(10, sizeof(int));


if (ptr == NULL) {
// Handle memory allocation failure
}

3. realloc() (Reallocation):

• Purpose: Resizes a previously allocated memory block, preserving its content up to the
lesser of the new and old sizes.

• Syntax: void* realloc(void* ptr, size_t new_size);

• Details: If the new size is larger, the additional memory is uninitialized. If the memory
block pointed to by ptr cannot be resized, realloc() allocates a new memory block, copies the
existing data to it, and frees the old block.

• Example:

int* ptr = (int*)realloc(existing_ptr, 20 * sizeof(int));


if (ptr == NULL) {
// Handle memory allocation failure
}

4. free() (Deallocation):

• Purpose: Deallocates memory that was previously allocated by malloc(), calloc(), or


realloc(), returning it to the heap for future use.

• Syntax: void free(void* ptr);

• Details: It’s crucial to free dynamically allocated memory when it’s no longer needed to
prevent memory leaks, which can lead to increased memory usage and potential program
instability.

• Example:

free(ptr);
ptr = NULL; // Avoid dangling pointer

Exmple

#include <stdio.h>
#include <stdlib.h>

int main() {

int n1, n2, i;

int *ptr;

// 1. Using malloc()

printf("Enter number of elements for malloc: ");

scanf("%d", &n1);

// Allocating memory using malloc()

ptr = (int*)malloc(n1 * sizeof(int));

// Check if memory has been allocated successfully

if (ptr == NULL) {

printf("Memory allocation failed using malloc.\n");

return 1;

// Initializing the allocated memory

for (i = 0; i < n1; i++) {

ptr[i] = i + 1;

// Displaying the elements


printf("Elements allocated using malloc: ");

for (i = 0; i < n1; i++) {

printf("%d ", ptr[i]);

printf("\n");

// 2. Using realloc() to resize the memory block

printf("Enter new number of elements for realloc: ");

scanf("%d", &n2);

// Reallocating memory

int *temp = realloc(ptr, n2 * sizeof(int));

if (temp == NULL) {

printf("Memory reallocation failed.\n");

free(ptr); // Free the original block before exiting

return 1;

ptr = temp;

// Initializing the newly allocated memory (if expanded)

if (n2 > n1) {

for (i = n1; i < n2; i++) {

ptr[i] = i + 1;

}
// Displaying the elements after reallocation

printf("Elements after realloc: ");

for (i = 0; i < n2; i++) {

printf("%d ", ptr[i]);

printf("\n");

// 3. Freeing the allocated memory

free(ptr);

printf("Memory has been freed.\n");

return 0;

In C programming, effective memory management is crucial for creating efficient and


reliable applications. The language provides a set of standard library functions to handle
dynamic memory allocation and deallocation.

Function Description Syntax


malloc Allocates a specified number of bytes and void* malloc(size_t size);
returns a pointer to the allocated memory.
calloc Allocates memory for an array of void* calloc(size_t num, size_t
elements, initializes all bytes to zero, and size);
returns a pointer.
realloc Resizes a previously allocated memory void* realloc(void* ptr, size_t
block to a new size. new_size);
free Deallocates previously allocated memory, void free(void* ptr);
making it available for future allocations.
memset Sets a block of memory to a specified void* memset(void* ptr, int
value. value, size_t num);
memcpy Copies a block of memory from one void* memcpy(void* dest, const
location to another. void* src, size_t num);
memmove Similar to memcpy, but safely handles void* memmove(void* dest,
overlapping memory regions. const void* src, size_t num);
sizeof Returns the size in bytes of a data type or sizeof(type);
object.

You might also like