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

unit4

A pointer in C is a variable that stores the memory address of another variable, allowing indirect access to variables, arrays, and functions. Pointer initialization involves assigning the address of a variable to the pointer, and pointer arithmetic allows operations like incrementing and decrementing pointers, as well as adding or subtracting integers to/from pointers. Pointers are closely related to arrays, where the array name acts as a constant pointer to its first element, enabling access through both array indexing and pointer arithmetic.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

unit4

A pointer in C is a variable that stores the memory address of another variable, allowing indirect access to variables, arrays, and functions. Pointer initialization involves assigning the address of a variable to the pointer, and pointer arithmetic allows operations like incrementing and decrementing pointers, as well as adding or subtracting integers to/from pointers. Pointers are closely related to arrays, where the array name acts as a constant pointer to its first element, enabling access through both array indexing and pointer arithmetic.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 27

Pointer in C – Definition and Initialization

✅ Definition:

A pointer in C is a variable that stores the memory address of another variable.

It allows indirect access to variables, arrays, and functions.

✅ Initialization:

Pointer initialization means assigning the address of a variable to the pointer.

📌 Syntax:
data_type *pointer_name;
pointer_name = &variable_name;

Or in one line:

data_type *pointer_name = &variable_name;

✅ Example:
#include <stdio.h>

int main() {
int a = 10; // normal integer variable
int *p = &a; // pointer initialization

printf("Value of a: %d\n", a); // 10


printf("Address of a: %p\n", &a); // e.g., 0x7ffee...
printf("Pointer p: %p\n", p); // same as &a
printf("Value pointed by p: %d\n", *p); // 10

return 0;
}

📝 Important Notes:

 *p → dereferences the pointer (gives value at that address).


 &a → gives the address of variable a.
 p → holds the address of a.

Pointer Operators in C
Pointer operators are special symbols used to work with pointers in C. The two main pointer
operators are:

🔹 1. Address-of Operator (&)

 Used to get the memory address of a variable.


 Returns a pointer to the variable.

Example:

int a = 10;
int *p = &a; // &a gives the address of a

🔹 2. Dereference Operator (*)

 Used to access the value stored at the memory address a pointer is pointing to.
 It is also used when declaring a pointer.

Example:

int a = 10;
int *p = &a;

printf("%d", *p); // prints 10 (value of a)

📌 How Both Work Together:


int a = 5;
int *p = &a; // & → address-of
printf("%d", *p); // * → dereference, prints value at address

🔧 Summary Table:

Operator Name Use


& Address-of Gets address of a variable
* Dereference Accesses value at a memory address

Pointer Arithmetic in C

A pointer variable in C stores the address of another variable. The address


is always an integer. So, can we perform arithmetic operations such as
addition and subtraction on the pointers? In this chapter, we will explain
which arithmetic operators use pointers in C as operands, and which
operations are not defined to be performed with pointers.
C pointers arithmetic operations are different from the general
arithmetic operations. The following are some of the important pointer
arithmetic operations in C:
 Increment and Decrement of a Pointer
 Addition and Subtraction of Integer to Pointer
 Subtraction of Pointers
 Comparison of Pointers

Let us discuss all these pointer arithmetic operations in detail with the
help of examples.

Increment and Decrement of a Pointer


We know that "++" and "--" are used as the increment and decrement
operators in C. They are unary operators, used in prefix or postfix manner
with numeric variable operands, and they increment or decrement the
value of the variable by one.

Assume that an integer variable "x" is created at address 1000 in the


memory, with 10 as its value. Then, "x++" makes the value of "x" as 11.

int x = 10; // created at address 1000

x++; // x becomes 11

What happens if we declare "y" as pointer to "x" and increment "y" by 1


(with "y++")? Assume that the address of "y" itself is 2000.

int x = 10; // created at address 1000

// "y" is created at address 2000


// it holds 1000 (address of "x")
int *y = &x ;

y++; // y becomes 1004

Since the variable "y" stores 1000 (the address of "x"), we expect it to
become 1001 because of the "++" operator, but it increments by 4, which
is the size of "int" variable.

The is why because, if the address of "x" is 1000, then it occupies 4 bytes:
1000, 1001, 1002 and 1003. Hence, the next integer can be put only in
1004 and not before it. Hence "y" (the pointer to "x") becomes 1004 when
incremented.

Example of Incrementing a Pointer


The following example shows how you can increment a pointer −

Open Compiler

#include <stdio.h>

int main(){

int x = 10;
int *y = &x;

printf("Value of y before increment: %d\n", y);

y++;

printf("Value of y after increment: %d", y);


}
Output

Run the code and check its output −

Value of y before increment: 6422036


Value of y after increment: 6422040

You can see that the value has increased by 4. Similarly, the "--" operator
decrements the value by the size of the data type.

Example of Decrementing a Pointer


Let us change the types of "x" and "y" to "double" and "float" and see the
effect of decrement operator.

Open Compiler

#include <stdio.h>

int main(){

double x = 10;
double *y = &x;

printf("value of y before decrement: %ld\n", y);


y--;

printf("value of y after decrement: %ld", y);


}
Output
Value of y before decrement: 6422032
Value of y after decrement: 6422024
When an array is declared, the elements are stored in adjacent memory
locations. In case of "int" array, each array subscript is placed apart by 4
bytes, as the following figure shows −

Hence, if a variable stores the address of 0th element of the array, then
the "increment" takes it to the 1st element.

Example of Traversing an Array by Incrementing Pointer


The following example shows how you can traverse an array by
incrementing a pointer successively −

Open Compiler

#include <stdio.h>

int main(){

int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int len = sizeof(a)/sizeof(int);
int *x = a;
int i = 0;

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


printf("Address of subscript %d = %d Value = %d\n", i, x, *x);
x++;
}

return 0;
}
Output

Run the code and check its output −

Address of subscript 0 = 6421984 Value = 10


Address of subscript 1 = 6421988 Value = 20
Address of subscript 2 = 6421992 Value = 30
Address of subscript 3 = 6421996 Value = 40
Address of subscript 4 = 6422000 Value = 50
Address of subscript 5 = 6422004 Value = 60
Address of subscript 6 = 6422008 Value = 70
Address of subscript 7 = 6422012 Value = 80
Address of subscript 8 = 6422016 Value = 90
Address of subscript 9 = 6422020 Value = 100

Addition and Subtraction of Integer to Pointer

An integer value can be added and subtracted to a pointer. When an


integer is added to a pointer, the pointer points to the next memory
address. Similarly, when an integer is subtracted from a pointer, the
pointer points to the previous memory location.

Addition and subtraction of an integer to a pointer does not add and


subtract that value to the pointer, multiplication with the size of the data
type is added or subtracted to the pointer.

For example, there is an integer pointer variable ptr and it is pointing to


an address 123400, if you add 1 to the ptr (ptr+1), it will point to the
address 123404 (size of an integer is 4).

Let's evaluate it,

ptr = 123400
ptr = ptr + 1
ptr = ptr + sizeof(int)*1
ptr = 123400 + 4
ptr = 123404

Example of Adding Value to a Pointer


In the following example, we are declaring an array and pointer to an
array. Initializing the pointer with the first element of the array and then
adding an integer value (2) to the pointer to get the third element of the
array.
Open Compiler

#include <stdio.h>

int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = int_arr;

printf("Value at ptrArr: %d\n", *ptrArr);

// Adding 2 in ptrArr
ptrArr = ptrArr + 2;

printf("Value at ptrArr after adding 2: %d\n", *ptrArr);

return 0;
}
Output
Value at ptrArr: 12
Value at ptrArr after adding 2: 45

Example of Subtracting Value to a Pointer


In the following example, we are declaring an array and pointer to an
array. Initializing the pointer with the last element of the array and then
subtracting an integer value (2) from the pointer to get the third element
of the array.

Open Compiler

#include <stdio.h>

int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = &int_arr[4]; // points to last element

printf("Value at ptrArr: %d\n", *ptrArr);

// Subtracting 2 in ptrArr
ptrArr = ptrArr - 2;
printf("Value at ptrArr after adding 2: %d\n", *ptrArr);

return 0;
}
Output
Value at ptrArr: 89
Value at ptrArr after adding 2: 45

Subtraction of Pointers
We are familiar with the "+" and "−" operators when they are used with
regular numeric operands. However, when you use these operators with
pointers, they behave in a little different way.

Since pointers are fairly large integers (especially in modern 64-bit


systems), addition of two pointers is meaningless. When we add a 1 to a
pointer, it points to the next location where an integer may be stored.
Obviously, when we add a pointer (itself a large integer), the location it
points may not be in the memory layout.

However, subtraction of two pointers is realistic. It returns the number of


data types that can fit in the two pointers.

Example of Subtracting Two Pointers


Let us take the array in the previous example and perform the subtraction
of pointers of a[0] and a[9]

Open Compiler

#include <stdio.h>

int main(){

int a[]= {10, 20, 30, 40, 50, 60, 70, 80, 90, 100};
int *x = &a[0]; // zeroth element
int *y = &a[9]; // last element

printf("Add of a[0]: %ld add of a[9]: %ld\n", x, y);


printf("Subtraction of two pointers: %ld", y-x);

}
Output

Run the code and check its output −

Add of a[0]: 140729162482768 add of a[9]: 140729162482804


Subtraction of two pointers: 9

It can be seen that the numerical difference between the two integers is
36; it suggests that the subtraction is 9, because it can accommodate 9
integers between the two pointers.

Comparison of Pointers
Pointers may be compared by using relational operators such as "==",
"<", and ">". If "p1" and "p2" point to variables that are related to each
other (such as elements of the same array), then "p1" and "p2" can be
meaningfully compared.

Example of Comparing Pointers


In the following example, we are declaring two pointers and initializing
them with the first and last elements of the array respectively. We will
keep incrementing the first variable pointer as long as the address to
which it points is either less than or equal to the address of the last
element of the array, which is "&var[MAX 1]" (i.e., the second pointer).

Open Compiler

#include <stdio.h>

const int MAX = 3;

int main() {
int var[] = {10, 100, 200};
int i, *ptr1, *ptr2;

// Initializing pointers
ptr1 = var;
ptr2 = &var[MAX - 1];

while (ptr1 <= ptr2) {


printf("Address of var[%d] = %p\n", i, ptr1);
printf("Value of var[%d] = %d\n", i, *ptr1);
/* point to the previous location */
ptr1++;
i++;
}

return 0;
}
Output

Run the code and check its output −

Address of var[0] = 0x7ffe7101498c


Value of var[0] = 10
Address of var[1] = 0x7ffe71014990
Value of var[1] = 100
Address of var[2] = 0x7ffe71014994
Value of var[2] = 200

Pointers and One-Dimensional Arrays in C

In C, pointers and arrays are closely related. The name of an array acts like a pointer to its
first element.

✅ Key Concepts:

 The array name (arr) is a constant pointer to the first element.


 You can use a pointer to access array elements using either array indexing or pointer
arithmetic.

🔹 Example:
#include <stdio.h>

int main() {
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr; // or int *p = &arr[0];

// Access elements using array indexing


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

printf("\n");

// Access elements using pointer arithmetic


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

return 0;
}

Pointers and One-dimensional Arrays

In a one-dimensional array, each element is identified by a single integer:

int a[5] = {1, 2, 3, 4, 5};

Here, the number "1" is at the 0th index, "2" at index 1, and so on.

A variable that stores the address of 0th element is its pointer −

int *x = &a[0];

Simply, the name of the array too points to the address of the 0th
element. So, you can also use this expression −

int *x = a;

Example
Since the value of the pointer increments by the size of the data type, "x+
+" moves the pointer to the next element in the array.

Open Compiler

#include <stdio.h>

int main(){

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


int length = sizeof(arr) / sizeof(arr[0]);
int i = 0;

int *ptr = arr;

while (i < length){


printf("arr[%d]: %d \n", i, *(ptr + i));
i++;
}

return 0;
}
Output

When you run this code, it will produce the following output −

arr[0]: 1
arr[1]: 2
arr[2]: 3
arr[3]: 4
arr[4]: 5

If a one-dimensional array is like a list of elements, a two-dimensional


array is like a table or a matrix.

The elements in a 2D array can be considered to be logically arranged in


rows and columns. Hence, the location of any element is decided by two
indices, its row number and column number. Both row and column
indexes start from "0".

int arr[2][2];

Such an array is represented as −

Col0 Col1 Col2

Row0 arr[0][0] arr[0][1] arr[0][2]

Row1 arr[1][0] arr[1][1] arr[1][2]

Row2 arr[2][0] arr[2][1] arr[2][2]

It may be noted that the tabular arrangement is only a logical


representation. The compiler allocates a block of continuous bytes. In C,
the array allocation is done in a row-major manner, which means the
elements are read into the array in a row−wise manner.
Here, we declare a 2D array with three rows and four columns (the
number in the first square bracket always refers to the number of rows) as

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

The compiler will allocate the memory for the above 2D array in a
row−wise order. Assuming that the first element of the array is at the
address 1000 and the size of type "int" is 4 bytes, the elements of the
array will get the following allocated memory locations −

Row 0 Row 1 Row 2

Value 1 2 3 4 5 6 7 8 9 10 11

Address 1000 1004 1008 1012 1016 1020 1024 1028 1032 1036 10

We will assign the address of the first element of the array num to the
pointer ptr using the address of & operator.

int *ptr = &arr[0][0];

Example 1
If the pointer is incremented by 1, it moves to the next address. All the 12
elements in the "34" array can be accessed in a loop as follows −

Open Compiler

#include <stdio.h>

int main(){

int arr[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12},
};
// pointer ptr pointing at array num
int *ptr = &arr[0][0];

int i, j, k = 0;

// print the elements of the array num via pointer ptr


for (i = 0; i < 3; i++){
for (j = 0; j < 4; j++){
printf("%d ", *(ptr + k));
k++;
}
printf("\n");
}

return 0;
}
Output

When you run this code, it will produce the following output −

1 2 3 4
5 6 7 8
9 10 11 12

In general, the address of any element of the array by with the use the
following formula −

add of element at ith row and jth col = baseAddress + [(i * no_of_cols + j)
* sizeof(array_type)]

In our 34 array,

add of arr[2][4] = 1000 + (2*4 + 2)*4 = 1044

You can refer to the above figure and it confirms that the address of
"arr[3][4]" is 1044.

Example 2
Use the dereference pointer to fetch the value at the address. Let us use
this formula to traverse the array with the help of its pointer −
Open Compiler

#include <stdio.h>

int main(){

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

int ROWS = 3, COLS = 4;


int i, j;

// pointer
int *ptr = &arr[0][0];

// print the element of the array via pointer ptr


for (i = 0; i < ROWS; i++){
for (j = 0; j < COLS; j++) {
printf("%4d ",*(ptr + (i * COLS + j)));
}
printf("\n");
}

return 0;
}
Output

When you run this code, it will produce the following output −

1 2 3 4
5 6 7 8
9 10 11 12

Pointers and Three-dimensional Arrays

A three-dimensional array is an array of two-dimensional arrays. Such an


array is declared with three subscripts −
int arr [x] [y] [j];

This array can be considered as "x" number of layers of tables, each table
having "x" rows and "y" number of columns.

An example of a 3D array is −

int arr[3][3][3] ={
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};

A pointer to the 3D array can be declared as −

int * ptr = &arr[0][0][0];

Knowing that, the name of the array itself is the address of 0th element,
we can write the pointer of a 3D array as −

int * ptr = arr;

Each layer of "x" rows and "y" columns occupies −

x * y * sizeof(data_type)

Number of bytes. Assuming that the memory allocated to the 3D array


"arr" as declared above starts from the address 1000, the second layer
(with "i = 1") starts at 1000 + (3 3) 4 = 1036 byte position.

ptr = Base address of 3D array arr


If JMAX is the number of rows and KMAX is the number of columns, then
the address of the element at the 0 th row and the 0 th column of the 1 st slice
is −
arr[1][0][0] = ptr + (1 * JMAX * KMAX)

The formula to obtain the value of an element at the jth row and kth
column of the ith slice can be given as −

arr[i][j][k] = *(ptr + (i * JMAX*KMAX) + (j*KMAX + k))

Example: Printing a 3D Array using Pointer Dereferencing


Let us use this formula to print the 3D array with the help of the pointer
dereferencing −
Open Compiler

#include <stdio.h>

int main(){

int i, j, k;
int arr[3][3][3] = {
{ {11, 12, 13}, {14, 15, 16}, {17, 18, 19} },
{ {21, 22, 23}, {24, 25, 26}, {27, 28, 29} },
{ {31, 32, 33}, {34, 35, 36}, {37, 38, 39} },
};

int JMAX = 3, KMAX = 3;


int *ptr = arr; // &arr[0][0][0];

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


for(j = 0; j < 3; j++){
for(k = 0; k < 3; k++){
printf("%d ",*(ptr+(i*JMAX*KMAX)+(j*KMAX+k)));
}
printf("\n");
}
printf("\n");
}

return 0;
}
Output

When you run this code, it will produce the following output −

11 12 13
14 15 16
17 18 19

21 22 23
24 25 26
27 28 29
31 32 33
34 35 36
37 38 39

In general, accessing an array with a pointer is quite similar to accessing


an array with subscript representation. The main difference between the
two is that the subscripted declaration of an array allocates the memory
statically, whereas we can use pointers for dynamic memory allocation.

To pass a multi-dimensional array to a function, you need to use pointers


instead of subscripts. However, using a subscripted array is more
convenient than using pointers, which can be difficult for new learners.

✅ 1. Array of Pointers

An array of pointers is a collection of memory addresses stored in an array. Each element in the
array is a pointer that can point to a variable or array.

🔹 Syntax:
data_type *array_name[size];

🔹 Example:
#include <stdio.h>

int main() {
int a = 10, b = 20, c = 30;
int *arr[3]; // array of 3 int pointers

arr[0] = &a;
arr[1] = &b;
arr[2] = &c;

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


printf("Value at arr[%d] = %d\n", i, *arr[i]);
}

return 0;
}

🧠 Use-case: Useful for arrays of strings, dynamic arrays, or jagged arrays.

✅ 2. Pointer to Pointer (Double Pointer)

A pointer to a pointer is a variable that stores the address of another pointer.

🔹 Syntax:
data_type **ptr;

🔹 Example:
#include <stdio.h>

int main() {
int a = 100;
int *p = &a; // pointer to int
int **pp = &p; // pointer to pointer to int

printf("Value of a: %d\n", a); // 100


printf("Value via *p: %d\n", *p); // 100
printf("Value via **pp: %d\n", **pp);// 100

return 0;
}

🧠 How it works:

 a → value
 p → points to a
 pp → points to p

⚡ Summary:

Concept Description Syntax Example

Array of Pointers Array where each element is a pointer int *arr[5];

Pointer to Pointer Pointer that stores address of another ptr int **pp;

✅ 1. Pointer to an Array

Concept:

A pointer to an array is a pointer that points to an entire array. This is different from a pointer to an
element of an array (where the pointer points to just a single element).

Syntax:
data_type (*ptr)[size];

 ptr is a pointer to an array of size elements.


 It can be used to refer to the entire array using *ptr, followed by the index.

Detailed Example:
#include <stdio.h>

int main() {
// Declare and initialize an array
int arr[5] = {10, 20, 30, 40, 50};

// Declare a pointer to an array of 5 integers


int (*ptr)[5] = &arr;

// Access array elements through pointer to array


printf("First element using pointer: %d\n", (*ptr)[0]); // Output: 10
printf("Second element using pointer: %d\n", (*ptr)[1]); // Output: 20
printf("Third element using pointer: %d\n", (*ptr)[2]); // Output: 30
printf("Fourth element using pointer: %d\n", (*ptr)[3]); // Output: 40
printf("Fifth element using pointer: %d\n", (*ptr)[4]); // Output: 50

// Pointer arithmetic to access the next array element


printf("Accessing second element using pointer arithmetic: %d\n",
*(*ptr + 1)); // Output: 20

return 0;
}

Explanation:

1. Pointer Declaration: int (*ptr)[5] = &arr;


o ptr is declared as a pointer to an array of 5 integers.
o It is initialized to point to the array arr.
2. Accessing Array Elements: (*ptr)[i]
o We use (*ptr)[i] to access elements of the array through the pointer.
o For example, (*ptr)[0] accesses the first element of the array (10).
3. Pointer Arithmetic: *(*ptr + 1)
o Pointer arithmetic allows us to access the next element in the array by moving the
pointer. Here, (*ptr + 1) points to the second element.

✅ 2. Void Pointer (Generic Pointer)

Concept:

A void pointer is a generic pointer that can point to any data type. It does not have a specific type,
so you cannot directly dereference it or perform arithmetic on it without typecasting.

Syntax:
void *ptr;

 void * is a pointer that can hold the address of any data type.

Detailed Example:
#include <stdio.h>

void printValue(void *ptr, char type) {


// Type casting and dereferencing based on the type argument
if (type == 'i') {
printf("Integer value: %d\n", *(int *)ptr); // Casting void
pointer to int pointer
} else if (type == 'f') {
printf("Float value: %.2f\n", *(float *)ptr); // Casting void
pointer to float pointer
} else if (type == 'c') {
printf("Char value: %c\n", *(char *)ptr); // Casting void pointer
to char pointer
}
}

int main() {
int i = 42;
float f = 3.14;
char c = 'A';

// Declare a void pointer


void *ptr;

// Pass void pointer and type of the variable


ptr = &i;
printValue(ptr, 'i'); // Output: Integer value: 42

ptr = &f;
printValue(ptr, 'f'); // Output: Float value: 3.14

ptr = &c;
printValue(ptr, 'c'); // Output: Char value: A

return 0;
}

Explanation:

1. Void Pointer Declaration:


o void *ptr; declares a void pointer that can point to any data type.
2. Typecasting Void Pointer:
o In the printValue function, we typecast the void pointer into the appropriate type
(e.g., *(int *)ptr, *(float *)ptr, and *(char *)ptr) before dereferencing
it.
3. Usage:
o A void pointer is passed to the printValue function, and based on the type
argument ('i', 'f', 'c'), the function typecasts the void pointer to the correct
data type before printing the value.

Why Use Void Pointers?

 Void pointers are commonly used in situations where you need a generic pointer, such as in:
o Memory allocation functions like malloc().
o Function callbacks that can handle different data types.
o Generic data structures like linked lists or queues.
⚡ Summary:
Concept Description Example Syntax

Pointer to Array A pointer that points to an entire array int (*ptr)[5] = &arr;

Void Pointer A pointer that can point to any data type void *ptr = &a;

Both pointer to an array and void pointers are fundamental concepts in C programming. While a
pointer to an array is useful for working with multi-element arrays, a void pointer is great for
handling different data types in a generic manner.

✅ 1. Pointer to Function

🔹 Definition:

A pointer to a function stores the address of a function and allows calling the function through the
pointer.

This is useful for:

 Callback functions
 Dynamic function calling
 Passing functions as arguments

🔹 Syntax:
return_type (*pointer_name)(parameter_list);

🔹 Simple Example:
#include <stdio.h>

// Function to add two numbers


int add(int a, int b) {
return a + b;
}

int main() {
// Declare a function pointer
int (*func_ptr)(int, int);

// Assign address of function 'add' to pointer


func_ptr = add;

// Call the function using the pointer


int result = func_ptr(10, 20);
printf("Result = %d\n", result); // Output: 30
return 0;
}

✅ Explanation:

 func_ptr is a pointer to a function that takes two int and returns an int.
 func_ptr = add; assigns the address of the function add to the pointer.
 func_ptr(10, 20); calls the function using the pointer.

✅ 2. Dynamic Memory Allocation

🔹 Definition:

Dynamic memory allocation in C allows you to allocate memory at runtime using functions from
<stdlib.h>.

Functions:

Function Purpose

malloc Allocates uninitialized memory

calloc Allocates and initializes to zero

realloc Resizes previously allocated memory

free Frees dynamically allocated memory

🔹 Example with malloc:


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

int main() {
int *arr;
int n;

printf("Enter number of elements: ");


scanf("%d", &n);

// Allocate memory for n integers


arr = (int *)malloc(n * sizeof(int));

// Check for successful allocation


if (arr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}

// Input values
printf("Enter %d elements:\n", n);
for (int i = 0; i < n; i++) {
scanf("%d", &arr[i]);
}

// Display values
printf("You entered:\n");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}

// Free the memory


free(arr);

return 0;
}

🧠 Key Points:

 malloc(n * sizeof(int)): Allocates memory for n integers.


 Always check if memory is NULL after allocation.
 Use free(ptr) to release memory once done.

🔁 Combined Use Case: Function Pointer + Dynamic Memory

Example: Sorting with a callback comparison function.

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

// Comparison function for ascending order


int compare(const void *a, const void *b) {
return (*(int *)a - *(int *)b);
}

int main() {
int n;
printf("Enter number of elements: ");
scanf("%d", &n);

int *arr = (int *)malloc(n * sizeof(int));


if (!arr) {
printf("Memory error\n");
return 1;
}

printf("Enter elements:\n");
for (int i = 0; i < n; i++)
scanf("%d", &arr[i]);
// qsort uses function pointer for comparison
qsort(arr, n, sizeof(int), compare);

printf("Sorted array:\n");
for (int i = 0; i < n; i++)
printf("%d ", arr[i]);

free(arr);
return 0;
}

🔚 Summary
Topic Purpose Key Syntax/Function

Pointer to Function Call a function via pointer int (*fptr)(int, int) = add;

Dynamic Memory Allocation Allocate memory at runtime malloc(), calloc(), free()

✅ 1. typedef in C

🔹 Definition:

typedef is a keyword used to create alias names for existing data types. It makes your code more
readable and easier to manage, especially for complex data types like structures or pointers.

🔹 Syntax:
typedef existing_type new_type_name;

🔹 Example:
#include <stdio.h>

typedef unsigned long ulong; // alias 'ulong' for 'unsigned long'


typedef int* IntPointer; // alias 'IntPointer' for 'int*'

int main() {
ulong num = 1234567890;
IntPointer ptr;
int a = 10;
ptr = &a;

printf("Number: %lu\n", num);


printf("Pointer value: %d\n", *ptr); // dereferencing pointer 'ptr'

return 0;
}

✅ Explanation:

 typedef unsigned long ulong; creates an alias ulong for unsigned long.
 typedef int* IntPointer; creates an alias IntPointer for int* (pointer to int).

Using typedef reduces complexity, especially when dealing with structures or function pointers.
✅ 2. Comment Lines in C

Comments in C are used to explain the code and make it more understandable. They are ignored by
the compiler.

🔹 Types of Comments:

1. Single-line comment (//):


o Used for short explanations or notes on a single line.
o Everything after // on that line is considered a comment.

// This is a single-line comment


printf("Hello, World!\n");

2. Multi-line comment (/* ... */):


o Used for longer explanations or commenting out multiple lines of code.
o Everything between /* and */ is considered a comment.

/* This is a multi-line comment


that spans across multiple lines
and helps explain complex code. */
printf("Hello, World!\n");

✅ Example with Comments:


#include <stdio.h>

int main() {
int x = 10; // Declare an integer variable 'x' and initialize it with
10

/* The following code will print the value of x */


printf("Value of x: %d\n", x); // Output: 10

return 0;
}

✅ 3. Command-Line Arguments in C

🔹 Definition:

Command-line arguments allow you to pass parameters to your program when it is executed,
enabling more dynamic functionality.

🔹 Syntax:

The main function can be defined with two arguments:

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


Where:

 argc (Argument Count) is the number of arguments passed to the program.


 argv (Argument Vector) is an array of strings representing the arguments.

🔹 Example Program:
#include <stdio.h>

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


printf("Number of arguments: %d\n", argc);

// Print each argument


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

return 0;
}

✅ Explanation:

 argc counts how many arguments are passed when running the program (including the
program name).
 argv is an array of strings that stores the arguments.

For example, running the program:

./program hello 123

Would output:

Number of arguments: 3
Argument 0: ./program
Argument 1: hello
Argument 2: 123

🔚 Summary Table
Feature Description Example Usage

Creates alias names for existing data typedef unsigned long


typedef
types ulong;

Used to document code and make it more // single-line, /* multi-


Comments
readable line */

Command-Line Allows passing parameters to the int main(int argc, char


Arguments program at runtime *argv[])

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy