unit4
unit4
✅ Definition:
✅ Initialization:
📌 Syntax:
data_type *pointer_name;
pointer_name = &variable_name;
Or in one line:
✅ Example:
#include <stdio.h>
int main() {
int a = 10; // normal integer variable
int *p = &a; // pointer initialization
return 0;
}
📝 Important Notes:
Pointer Operators in C
Pointer operators are special symbols used to work with pointers in C. The two main pointer
operators are:
Example:
int a = 10;
int *p = &a; // &a gives the address of a
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;
🔧 Summary Table:
Pointer Arithmetic in C
Let us discuss all these pointer arithmetic operations in detail with the
help of examples.
x++; // x becomes 11
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.
Open Compiler
#include <stdio.h>
int main(){
int x = 10;
int *y = &x;
y++;
You can see that the value has increased by 4. Similarly, the "--" operator
decrements the value by the size of the data type.
Open Compiler
#include <stdio.h>
int main(){
double x = 10;
double *y = &x;
Hence, if a variable stores the address of 0th element of the array, then
the "increment" takes it to the 1st element.
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;
return 0;
}
Output
ptr = 123400
ptr = ptr + 1
ptr = ptr + sizeof(int)*1
ptr = 123400 + 4
ptr = 123404
#include <stdio.h>
int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = int_arr;
// Adding 2 in ptrArr
ptrArr = ptrArr + 2;
return 0;
}
Output
Value at ptrArr: 12
Value at ptrArr after adding 2: 45
Open Compiler
#include <stdio.h>
int main() {
int int_arr[] = {12, 23, 45, 67, 89};
int *ptrArr = &int_arr[4]; // points to last element
// 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.
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
}
Output
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.
Open Compiler
#include <stdio.h>
int main() {
int var[] = {10, 100, 200};
int i, *ptr1, *ptr2;
// Initializing pointers
ptr1 = var;
ptr2 = &var[MAX - 1];
return 0;
}
Output
In C, pointers and arrays are closely related. The name of an array acts like a pointer to its
first element.
✅ Key Concepts:
🔹 Example:
#include <stdio.h>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int *p = arr; // or int *p = &arr[0];
printf("\n");
return 0;
}
Here, the number "1" is at the 0th index, "2" at index 1, and so on.
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(){
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
int arr[2][2];
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 −
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.
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;
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,
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}
};
// pointer
int *ptr = &arr[0][0];
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
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} },
};
Knowing that, the name of the array itself is the address of 0th element,
we can write the pointer of a 3D array as −
x * y * sizeof(data_type)
The formula to obtain the value of an element at the jth row and kth
column of the ith slice can be given as −
#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} },
};
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
✅ 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;
return 0;
}
🔹 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
return 0;
}
🧠 How it works:
a → value
p → points to a
pp → points to p
⚡ Summary:
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];
Detailed Example:
#include <stdio.h>
int main() {
// Declare and initialize an array
int arr[5] = {10, 20, 30, 40, 50};
return 0;
}
Explanation:
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>
int main() {
int i = 42;
float f = 3.14;
char c = 'A';
ptr = &f;
printValue(ptr, 'f'); // Output: Float value: 3.14
ptr = &c;
printValue(ptr, 'c'); // Output: Char value: A
return 0;
}
Explanation:
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.
Callback functions
Dynamic function calling
Passing functions as arguments
🔹 Syntax:
return_type (*pointer_name)(parameter_list);
🔹 Simple Example:
#include <stdio.h>
int main() {
// Declare a function pointer
int (*func_ptr)(int, int);
✅ 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.
🔹 Definition:
Dynamic memory allocation in C allows you to allocate memory at runtime using functions from
<stdlib.h>.
Functions:
Function Purpose
int main() {
int *arr;
int n;
// 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]);
}
return 0;
}
🧠 Key Points:
#include <stdio.h>
#include <stdlib.h>
int main() {
int n;
printf("Enter number of elements: ");
scanf("%d", &n);
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;
✅ 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>
int main() {
ulong num = 1234567890;
IntPointer ptr;
int a = 10;
ptr = &a;
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:
int main() {
int x = 10; // Declare an integer variable 'x' and initialize it with
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:
🔹 Example Program:
#include <stdio.h>
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.
Would output:
Number of arguments: 3
Argument 0: ./program
Argument 1: hello
Argument 2: 123
🔚 Summary Table
Feature Description Example Usage