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

UNIT 4

This document provides a comprehensive overview of pointers in C, covering topics such as pointer arithmetic, relationships between arrays and pointers, dynamic memory allocation, and pointers to pointers. It includes code examples to illustrate concepts like pointer operations, accessing array elements, and modifying strings. Additionally, it discusses memory management functions like malloc, calloc, and realloc for dynamic memory allocation.

Uploaded by

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

UNIT 4

This document provides a comprehensive overview of pointers in C, covering topics such as pointer arithmetic, relationships between arrays and pointers, dynamic memory allocation, and pointers to pointers. It includes code examples to illustrate concepts like pointer operations, accessing array elements, and modifying strings. Additionally, it discusses memory management functions like malloc, calloc, and realloc for dynamic memory allocation.

Uploaded by

ninojustin1234
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 30

UNIT 4 - POINTERS

Introduction to pointers – Pointers arithmetic – call


by reference – Relationship between Array and
Pointers – Relationship between String and pointers
– pointers to pointers – array of pointers – pointers
to an array – Dynamic memory allocation –
Arguments to main().
Pointer Arithmetic in C
Pointer arithmetic allows operations like addition, subtraction, and comparison on
pointers. It is useful when working with arrays and dynamic memory.
1. Valid Pointer Operations in C
Given a pointer ptr, the following operations are allowed:
✅ ptr + n → Moves pointer forward by n elements.
✅ ptr - n → Moves pointer backward by n elements.
✅ ptr1 - ptr2 → Finds the difference between two pointers.
✅ ptr++ or ++ptr → Moves pointer to the next element.
✅ ptr-- or --ptr → Moves pointer to the previous element.
2. Pointer Arithmetic with Arrays
Since an array name (arr) acts as a pointer to the first element (&arr[0]), pointer
arithmetic can be used to traverse arrays.
Example: Incrementing a Pointer
#include <stdio.h> int main() { int arr[] = {10, 20, 30, 40, 50}; int *ptr = arr; // Points to
arr[0] printf("Address: %p, Value: %d\n", ptr, *ptr); ptr++; // Move to next element
printf("Address: %p, Value: %d\n", ptr, *ptr); return 0; }
Output (Addresses may vary):
Address: 0x100, Value: 10 Address: 0x104, Value: 20
Explanation:
•Since int is 4 bytes, incrementing ptr moves it by 4 bytes.
3. Pointer Subtraction
Pointer subtraction gives the number of elements between two addresses.
Example: Finding Distance Between Two Elements
#include <stdio.h> int main() { int arr[] = {5, 10, 15, 20, 25}; int *ptr1 = &arr[1]; //
Points to arr[1] (10) int *ptr2 = &arr[4]; // Points to arr[4] (25) printf("Distance:
%ld\n", ptr2 - ptr1); // Output: 3 return 0; }
🔹 Output:
Distance: 3
💡 Explanation:
•The difference ptr2 - ptr1 gives the number of elements (not bytes) between
ptr2 and ptr1.
4. Pointer Comparison
You can compare pointers using relational operators (==, !=, <, >).
Example: Comparing Two Pointers
#include <stdio.h> int main() { int arr[] = {2, 4, 6, 8}; int *p1 = &arr[0]; int *p2 =
&arr[2]; if (p1 < p2) { printf("p1 points to an earlier element than p2.\n"); } return 0; }
🔹 Output:
p1 points to an earlier element than p2.
💡 Explanation:
•p1 < p2 is true because p1 points to arr[0] and p2 points to arr[2].
5. Pointer Arithmetic with char, float, and double
Pointers increment based on data type size.
Example: Different Data Types
#include <stdio.h> int main() { char c = 'A'; int i = 10; double d = 20.5; char *pc = &c; int
*pi = &i; double *pd = &d; printf("Char pointer: %p, Next: %p\n", pc, pc + 1); printf("Int
pointer: %p, Next: %p\n", pi, pi + 1); printf("Double pointer: %p, Next: %p\n", pd, pd +
1); return 0; }
🔹 Output (Addresses will vary):
Char pointer: 0x100, Next: 0x101 Int pointer: 0x200, Next: 0x204 Double pointer: 0x300,
Next: 0x308
💡 Explanation:
•pc + 1 moves 1 byte (char = 1 byte).
•pi + 1 moves 4 bytes (int = 4 bytes).
•pd + 1 moves 8 bytes (double = 8 bytes).
Operation Meaning
Moves pointer forward by n
ptr + n
elements
Moves pointer backward by n
ptr - n
elements
Finds distance between two
ptr1 - ptr2
pointers
Moves pointer to the next
ptr++ or ++ptr
element
Moves pointer to the previous
ptr-- or --ptr
element
Compares two pointer
ptr1 < ptr2
addresses
Arrays and Pointers
Definition of Arrays: An array is a collection of elements of the same type, arranged in
a sequence. Each element has a unique index, which is used to access it. Changes to
one element do not affect others.
Memory Layout: Arrays occupy a contiguous block of memory. For example, in the
array int a[] = {10, 20, 30, 40, 50};, if it starts at a specific memory location (e.g.,
2147478270), the elements are positioned sequentially:
a[0] at 2147478270
a[1] at 2147478274
a[2] at 2147478278, and so forth.
Array Name as Pointer: The name of an array represents the address of its first
element (known as the base address). When you use the array name, you are actually
referring to its starting memory location. This means you can treat the name of the
array like a pointer to the first element.
This relationship between arrays and pointers allows for flexible and efficient
programming, but it's important to remember that they are not the same; arrays are
fixed-size structures while pointers can be reassigned.
1.Base Address: The expressions array and &array both give the
base address of an array, but they're treated differently:
•array gives you a pointer to the first element (type: pointer-to-
T).
•&array gives you a pointer to the entire array (type: pointer-
to-array-of-T).
2.Accessing Elements: You can access elements of an array using:
•Subscript notation: a[i]
•Pointer arithmetic: *(a + i)
•Both notations allow you to access the same element.
3.Relationship of Addresses:
• The address of the first element: &a[0] == a
• The address of the ith element: &a[i] == a + i
• Accessing an element: a[i] == *(a + i)
• Pointer Arithmetic: When using pointers, you can manipulate addresses with
integer offsets, e.g., p = a + 3 points p to the fourth element.
• Pointer Equivalence:
• An array can seemingly be assigned to a pointer: int *p; p = a; assigns p to the first
element of a.
• Pointer notation allows for array-like syntax: p[i] is equivalent to *(p + i).
• Flexible Pointers: Pointers can point to any element of an array, not just the first
one. For example, you can set a pointer to point to the third element with p =
&a[2];.
• C Standard Compliance: Trying to treat arrays as 1-based (instead of 0-based) does
not conform to C standards and may lead to undefined behavior if not handled
properly.
• The equivalence of arrays and pointers simplifies syntax and improves flexibility in
handling data structures in C, but it's crucial to follow pointer arithmetic rules to
ensure memory safety.
Strings and Pointers Relationship
String as a Pointer:
•When you declare a string as char *ptr = "Hello";, ptr points to the
first character of the string.
•This means ptr contains the memory address of the first character
'H'.
Pointer Arithmetic:
You can use pointer arithmetic to access individual characters in the string.
For example, *(ptr + 1) gives the second character, 'e'.
String and Array Name:
The name of an array (e.g., str in char str[] = "Hello";) acts as a pointer to its
first element. Hence, str is equivalent to &str[0].
Modifiability:
Strings declared as char *ptr = "Hello"; are stored in read-only memory
and should not be modified.
Strings declared as char str[] = "Hello"; can be modified.
#include <stdio.h>

int main() { OUTPUT


char str[] = "Hello"; // A modifiable string stored as an array Using array indexing:
char *ptr = str; // Pointer to the first character of str Hello
Using pointer arithmetic:
// Accessing string using array indexing Hello
printf("Using array indexing: "); Modified string: Yello
for (int i = 0; str[i] != '\0'; i++) {
printf("%c", str[i]);
}

// Accessing string using pointer arithmetic


printf("\nUsing pointer arithmetic: ");
for (int i = 0; *(ptr + i) != '\0'; i++) {
printf("%c", *(ptr + i));
}

// Modifying the string using the pointer


ptr[0] = 'Y'; // Equivalent to str[0] = 'Y'
printf("\nModified string: %s\n", str);

return 0;
}
Pointers to Pointers
Basic Pointer: A pointer holds the address of a variable.
int *p; // p is a pointer to an integer.
Pointer to Pointer: A pointer to a pointer holds the address of
another pointer.
int **q; // q is a pointer to a pointer to an integer.
Dereferencing:
1. Dereferencing p once (*p) gives the value stored in the
variable a.
2. Dereferencing q once (*q) gives the value stored in p (which
is the address of a).
3. Dereferencing q twice (**q) gives the value stored in a.
Example
#include <stdio.h>
Output
int main() { *p = 5
int a = 5; // Declare an integer variable **q = 5
int *p; // Pointer to an integer
int **q; // Pointer to a pointer to an integer

p = &a; // p stores the address of a


q = &p; // q stores the address of p

// Printing values using dereferencing


printf("\n*p = %d", *p); // Dereferencing p gives the value of a
printf("\n**q = %d", **q); // Dereferencing q twice gives the value of
a

return 0;
}
Array of Pointers:

Definition:
An array of pointers is declared as:
data_type *array_name[size];
•data_type indicates the type of data the pointers will point to.
•Each element of the array is a pointer.

Memory Representation:
Each element in the array stores the address of some data.
Example: Array of Pointers to Integers
#include <stdio.h>
OUTPUT
Value of a: 10
int main() {
Value of b: 20
int a = 10, b = 20, c = 30;
Value of c: 30
// Array of pointers to integers
int *arr[3];

// Assigning addresses to the pointers


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

// Accessing values using the array of


pointers
printf("Value of a: %d\n", *arr[0]);
printf("Value of b: %d\n", *arr[1]);
printf("Value of c: %d\n", *arr[2]);

return 0;
}
Example: Array of Pointers to Strings

#include <stdio.h> Output


Fruit 1: Apple
int main() { Fruit 2: Banana
// Array of pointers to strings Fruit 3: Cherry
char *fruits[] = {"Apple", "Banana", "Cherry"};

// Accessing each string


for (int i = 0; i < 3; i++) {
printf("Fruit %d: %s\n", i + 1, fruits[i]);
}

return 0;
}
POINTER TO AN ARRAY
A pointer to an array stores the address of the first element of the array, but it also
retains information about the size of the array it points to.
Syntax of Pointer to an Array:
data_type (*pointer_name)[size];
data_type: The type of elements stored in the array.
pointer_name: The name of the pointer.
size: The size of the array it points to.
#include <stdio.h>

int main() {
int arr[5] = {10, 20, 30, 40, 50};

// Declaring a pointer to an array of 5 integers int (*ptr)[5];


int (*ptr)[5]; ptr is a pointer to an array of 5 integers.

// Pointing ptr to the array arr ptr = &arr;


ptr = &arr; The address of the entire array arr is
assigned to ptr.
// Accessing elements of the array using the pointer
printf("First element: %d\n", (*ptr)[0]);
printf("Second element: %d\n", (*ptr)[1]);

// Iterating through the array using the pointer •(*ptr) gives access to the array itself.
for (int i = 0; i < 5; i++) { •(*ptr)[i] accesses the i-th element of
printf("Element %d: %d\n", i, (*ptr)[i]); the array.
}

return 0;
}
Dynamic Memory Allocation Functions:
Dynamic memory allocation allows the program to request and manage memory
during runtime (as opposed to compile-time).
 It provides flexibility, as the size of data structures like arrays can be decided during
execution, rather than being hard-coded.
C provides several functions for dynamic memory allocation in the <stdlib.h> library.

Function Description

Allocates a block of memory of specified


malloc
size but does not initialize it.
Allocates memory for an array of
calloc
elements, initializes all bytes to zero.
Resizes an already allocated memory
realloc
block.
Frees previously allocated memory to
free
avoid memory leaks.
1. malloc (Memory Allocation)

•Allocates a block of memory of specified size.


•Does not initialize the memory; the contents are indeterminate.
•Returns a void * pointer to the allocated memory, which can be typecast as
needed.
Syntax : void *malloc(size_t size);

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

int main() {
int *ptr;

// Allocating memory for 5 integers


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

if (ptr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Assigning values to the allocated memory OUTPUT
for (int i = 0; i < 5; i++) { 12345
ptr[i] = i + 1;
}

// Printing the values


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

// Freeing the allocated memory


free(ptr);

return 0;
}
2. calloc (Contiguous
Allocation)

•Allocates memory for an array of n elements, each of a specified size.


•Initializes all memory to zero.
Syntax: void *calloc(size_t n, size_t size);

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

int main() {
int *ptr;

// Allocating memory for 5 integers using calloc


ptr = (int *)calloc(5, sizeof(int));
if (ptr == NULL) { Output:
printf("Memory allocation failed!\n"); 00000
return 1;
}

// Printing the initialized values (all zeros)


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

// Freeing the allocated memory


free(ptr);

return 0;
}
3. realloc (Reallocation)
•Changes the size of an already allocated memory block.
•Can expand or shrink the memory block.
•If the block is expanded, the new part is uninitialized.
Syntax: void *realloc(void *ptr, size_t new_size);
#include <stdio.h>
#include <stdlib.h>

int main() {
int *ptr;

// Allocating memory for 3 integers


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

if (ptr == NULL) {
printf("Memory allocation failed!\n");
return 1;
}
// Assigning initial values
for (int i = 0; i < 3; i++) { Output:
ptr[i] = i + 1;
} 12345

// Reallocating memory to hold 5 integers


ptr = (int *)realloc(ptr, 5 * sizeof(int));

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

// Assigning values to the new memory


for (int i = 3; i < 5; i++) {
ptr[i] = i + 1;
}

// Printing all values


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

// Freeing the allocated memory


free(ptr);

return 0;
}
4. free (Memory Deallocation)
•Releases previously allocated memory.
•Prevents memory leaks by making memory available for future use.
Syntax: void free(void *ptr);
Example:
#include <stdlib.h>

int main() {
int *ptr = (int *)malloc(5 * sizeof(int));

// After usage
free(ptr); // Deallocate memory
return 0;
}
Comparison

Feature malloc calloc realloc

No
No Initializes to
Initialization initialization
initialization zero
for new part

Single block Array Resize existing


Usage
allocation allocation allocation

Faster (no Slightly slower Depends on


Performance
zeroing out) (zeroing) operation
// Step 3: Expand memory using realloc
Example: n = 10;
#include <stdio.h> arr = (int *)realloc(arr, n * sizeof(int));
#include <stdlib.h> if (arr == NULL) {
printf("Memory reallocation failed\n");
int main() { return 1;
int n = 5; }

// Step 1: Allocate memory using malloc // Add new values to the extended array
int *arr = (int *)malloc(n * sizeof(int)); for (int i = 5; i < n; i++) {
if (arr == NULL) { arr[i] = i + 1;
printf("Memory allocation failed\n"); }
return 1;
} // Print all values
for (int i = 0; i < n; i++) {
// Step 2: Initialize values printf("%d ", arr[i]);
for (int i = 0; i < n; i++) { }
arr[i] = i + 1;
} // Step 4: Free memory
free(arr);

return 0; Output:
} 1 2 3 4 5 6 7 8 9 10
Arguments to main()
It is mainly useful for command-line programs that need to handle user input or file
paths. The arguments to main() are:
int main(int argc, char *argv[])
a. argc (Argument Count)
Stands for argument count.
It represents the number of arguments passed to the program, including the program
name itself.
It is always at least 1 because the first argument is the program's name.
b. argv (Argument Vector)
Stands for argument vector.
It is an array of strings (char *argv[]) that contains the command-line arguments
passed to the program.
argv[0] is the program's name or path.
argv[1] to argv[argc - 1] are the additional arguments provided by the user.
Alternative Declaration
Some compilers support char **argv instead of char *argv[]. Both are equivalent.
Example

#include <stdio.h> Input (Command Line):


./program hello world 42
int main(int argc, char *argv[]) {
printf("Number of arguments (argc): %d\n", Output:
argc); Number of arguments (argc): 4
Argument 0: ./program
for (int i = 0; i < argc; i++) { Argument 1: hello
printf("Argument %d: %s\n", i, argv[i]); Argument 2: world
} Argument 3: 42

return 0;
}

You might also like