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

c Programming

The document explains pointers and arrays in C programming, detailing how pointers store memory addresses and how arrays are collections of variables of the same type. It covers key operations involving pointers, such as dereferencing and pointer arithmetic, as well as the relationship between pointers and arrays, including passing arrays to functions. Additionally, it discusses dynamic memory allocation using functions like malloc(), calloc(), realloc(), and free(), along with important concepts and best practices to avoid common issues.

Uploaded by

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

c Programming

The document explains pointers and arrays in C programming, detailing how pointers store memory addresses and how arrays are collections of variables of the same type. It covers key operations involving pointers, such as dereferencing and pointer arithmetic, as well as the relationship between pointers and arrays, including passing arrays to functions. Additionally, it discusses dynamic memory allocation using functions like malloc(), calloc(), realloc(), and free(), along with important concepts and best practices to avoid common issues.

Uploaded by

amrishmca1
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 17

*******Pointers and Arrays in C Programming*******

What are Pointers in C?

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


Instead of holding the actual data itself, a pointer holds the location (address)
where the data is stored.

Pointer Syntax:

data_type *pointer_name;

 data_type: The type of data the pointer will point to (like int, char, etc.).
 *: Indicates that it's a pointer.
 pointer_name: The name of the pointer.

Example:

int num = 5;
int *ptr;
ptr = # // Store the address of 'num' in the pointer 'ptr'

 Here, num is an integer, and ptr is a pointer to an integer. &num gives the
address of the variable num.

Important Pointer Operations:

In C programming, the indirection operator (*) is used with pointers to access the value
stored at the memory address the pointer is pointing to.

Key Points about the Indirection Operator (*):

1. Pointer Declaration: A pointer holds the memory address of a variable, rather than
the value itself.
2. Indirection Operator (*): When applied to a pointer, it "dereferences" the pointer,
meaning it accesses the value at the memory location the pointer is pointing to.

Syntax:
*pointer: This is used to get the value stored at the memory address the pointer is pointing to.

Example:

#include <stdio.h>

int main() {
int num = 10; // Normal integer variable
int *ptr = &num; // Pointer variable that holds the address of num

// Using the indirection operator to access the value of num via ptr
printf("Value of num: %d\n", num); // Direct access
printf("Value of num through pointer: %d\n", *ptr); // Indirect access using pointer

return 0;
}

1. Dereferencing: Access the value at the memory address the pointer is


pointing to.

int value = *ptr; // Dereferencing the pointer 'ptr'

2. Address-of Operator (&): Returns the memory address of a variable.

ptr = &num; // Get address of 'num'

3. Pointer Arithmetic: You can perform arithmetic operations on pointers


(add/subtract integers) to navigate through memory.

ptr++; // Move to the next memory location

What are Arrays in C?

An array is a collection of variables of the same data type stored in contiguous


memory locations. Arrays in C are accessed by their index, starting from 0.

data_type array_name[array_size];

 data_type:Type of elements in the array (like int, char, etc.).


 array_name: The name of the array.
 array_size: Number of elements in the array.

Example:

int arr[5] = {1, 2, 3, 4, 5}; // An integer array of 5 elements

SORTING ARRAY
In C programming, sorting an array refers to arranging the elements of an array
in a particular order (either ascending or descending). The most common sorting
algorithms include Bubble Sort, Selection Sort, Insertion Sort, and more
complex algorithms like Merge Sort and Quick Sort.

Pointers and Arrays Relationship:

 In C, an array name is essentially a pointer to the first element of the


array.
 You can access array elements using pointers.
 For example:

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


int *ptr = arr; // 'arr' is a pointer to the first element



 You can use pointer arithmetic to access array elements:

printf("%d\n", *(ptr + 1)); // Accesses second element, 20

Pointer to Array Example:

Here’s an example of how pointers can be used with arrays:

#include <stdio.h>

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

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


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

return 0;
}

Pointer and Array as Function Arguments:

Arrays are always passed to functions as pointers. This means when you pass an
array to a function, you are passing the address of the first element.

Function with Pointer:

#include <stdio.h>

void display(int *arr, int size) {


for (int i = 0; i < size; i++) {
printf("%d ", *(arr + i)); // Accessing array elements using pointer
}
printf("\n");
}

int main() {
int arr[] = {10, 20, 30};
display(arr, 3); // Passing array to function
return 0;
}

Function with Array:

You can also pass the array directly:

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


// Same as above
}

Dynamic Memory Allocation with Pointers:

In C, you can allocate memory at runtime using pointers. This is done using
functions like malloc(), calloc(), realloc(), and freeing memory using free().

Example (malloc):

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

int main() {
int *ptr;
int n = 5;

// Dynamically allocate memory for an array of 5 integers


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

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

// Initialize and print the array elements


for (int i = 0; i < n; i++) {
ptr[i] = i + 1;
printf("%d ", ptr[i]);
}
free(ptr); // Don't forget to free the memory
return 0;
}

Common Pointer and Array Issues:

1. Accessing Out-of-Bounds Memory: Always ensure you don’t access memory


outside the allocated range (e.g., an array index beyond its size).
2. Dangling Pointers: After freeing a pointer, ensure you don't use it again.
3. Pointer Arithmetic: When performing pointer arithmetic, make sure
you're not moving outside the array’s bounds.

Summary of Key Points:

1. Pointers store the memory address of variables.


2. Arrays are collections of elements of the same type.
3. Pointers to Arrays: Arrays can be accessed using pointers, and array names
are pointers to the first element.
4. Passing Arrays to Functions: Arrays are passed as pointers to functions.
5. Dynamic Memory Allocation: You can allocate memory at runtime using
functions like malloc() and free().

By understanding pointers and arrays, you can manage memory efficiently and
perform tasks like dynamic memory allocation and passing large arrays to
functions.
Dynamic Memory Allocation in C
Dynamic memory allocation in C allows you to allocate memory during the
runtime of your program, as opposed to static memory allocation, where memory
is allocated before the program begins execution. This is especially useful when
you don’t know the amount of memory you’ll need in advance or when the memory
requirements change during the program's execution.

Dynamic memory allocation is done using a set of functions provided by C’s


standard library. These functions are:

 malloc()
 calloc()
 realloc()
 free()

Key Functions for Dynamic Memory Allocation

1. malloc() (Memory Allocation)

The malloc() function allocates a block of memory of a specified size and


returns a pointer to the first byte of the allocated memory. If the memory
allocation fails (e.g., insufficient memory), it returns NULL.

Syntax:

void *malloc(size_t size);

 size: The number of bytes to allocate.


 Returns: A pointer to the allocated memory, or NULL if the allocation fails.

Example:

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

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

// Allocating memory for an array of 5 integers


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

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

// Initialize and print the array elements


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

// Free the allocated memory


free(arr);
return 0;
}

Here, malloc() is used to allocate memory for an array of 5 integers.

2. calloc() (Contiguous Allocation)

The calloc() function is similar to malloc(), but it initializes the allocated


memory to zero. This can help avoid errors that can occur due to uninitialized
variables.

Syntax:

void *calloc(size_t num_elements, size_t size_of_element);

 num_elements: The number of elements to allocate memory for.


 size_of_element: The size of each element.

Example:

#include <stdio.h>
#include <stdlib.h>
int main() {
int *arr;
int n = 5;

// Allocating memory for 5 integers and initializing them to 0


arr = (int *)calloc(n, sizeof(int));

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

// Print the array elements (will all be initialized to 0)


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

// Free the allocated memory


free(arr);
return 0;
}

Here, calloc() allocates memory for 5 integers and initializes them to zero.

3. realloc() (Reallocation)

The realloc() function is used to resize a previously allocated block of memory.


It changes the size of the memory block while keeping the content intact. If
the reallocation is successful, it returns a new pointer to the resized memory
block. If it fails, it returns NULL, and the original memory block remains
unchanged.

Syntax:

void *realloc(void *ptr, size_t new_size);

 ptr: The pointer to the previously allocated memory block.


 new_size: The new size in bytes.
Example:

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

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

// Allocate memory for 5 integers


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

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

// Initialize and print the array elements


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

// Reallocate memory to accommodate 10 integers


n = 10;
arr = (int *)realloc(arr, n * sizeof(int));

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

// Initialize the new elements


for (int i = 5; i < n; i++) {
arr[i] = i + 1;
}

// Print the updated array elements


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

// Free the allocated memory


free(arr);
return 0;
}

In this example, we initially allocate memory for 5 integers. Then, we resize the
memory block to accommodate 10 integers using realloc().

4. free() (Freeing Memory)

The free() function deallocates the memory that was previously allocated using
malloc(), calloc(), or realloc(). After calling free(), the pointer no longer points
to valid memory, and it should not be accessed again. It's good practice to set
the pointer to NULL after freeing the memory.

Syntax:

void free(void *ptr);

 ptr: The pointer to the memory that was previously allocated.

Example:

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

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

// Allocate memory
arr = (int *)malloc(n * sizeof(int));

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

// Free the allocated memory


free(arr);

// It's a good practice to set the pointer to NULL after freeing memory
arr = NULL;

return 0;
}

Important Concepts and Tips

1. Memory Leaks: Always ensure you free() dynamically allocated memory


when you're done using it to prevent memory leaks (memory that’s no
longer needed but hasn’t been deallocated).
2. Accessing Freed Memory: After using free(), don’t access the pointer. If
you do, it results in undefined behavior.
3. Null Pointer After Freeing: It’s a good practice to set a pointer to NULL
after calling free() on it. This helps to prevent accidental access to freed
memory.
4. Fragmentation: Dynamic memory allocation can lead to memory
fragmentation over time (if many allocations and deallocations happen),
which can make future allocations fail due to insufficient contiguous
memory space.

Example of Using All Dynamic Memory Functions:

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

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

// Step 1: Dynamically allocate memory using malloc()


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

// Step 2: Initialize the memory and print values


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

// Step 3: Reallocate memory using realloc() to expand the array


n = 8;
arr = (int *)realloc(arr, n * sizeof(int));
if (arr == NULL) {
printf("Memory reallocation failed!\n");
return 1;
}

// Step 4: Initialize the new elements


for (int i = 5; i < n; i++) {
arr[i] = i + 1;
}

// Step 5: Print the updated array


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

// Step 6: Free the allocated memory


free(arr);

return 0;
}
String in C Language
In C, strings are essentially arrays of characters that are terminated by a special null character
('\0'). A string is a sequence of characters enclosed in double quotes.

Definition, Declaration, and Initialization of Strings

1. Definition of Strings: A string is an array of characters in C. Each character is stored in


contiguous memory locations, and the last character is always the null character ('\0') to
indicate the end of the string.
2. Declaration of Strings: To declare a string, you use the following syntax:

char stringName[size];

o char is the data type, which denotes a character.


o stringName is the name of the string (array of characters).
o size is the number of characters the string can hold (including the null character '\0').
3. Initialization of Strings: Strings in C can be initialized in two ways:
o Using a string literal:

char str1[] = "Hello, World!";

In this case, the compiler automatically allocates enough space for the string, including
the null character '\0'.

o Using an explicit size:

char str2[20] = "Hello";

Here, the string "Hello" is initialized, and the rest of the array will be filled with the
null character '\0' (up to 20 characters in this example).

Standard Library Functions for Strings:


C provides several built-in functions to work with strings, such as strlen(), strcpy(), strcat(), and
strcmp(). These functions are declared in the <string.h> header.

However, you can also implement these functions manually, without using the standard library.

Custom Implementations of String Functions (Without Using Library Functions):


1. my_strlen() – Finding the Length of a String

Definition:
The my_strlen() function counts the number of characters in a string until it encounters the
null character ('\0'), which marks the end of the string.

Steps:

1. Initialize a counter variable (length) to 0.


2. Use a loop to check each character of the string.
3. Increase the counter each time a character is encountered.
4. Stop when the null character is encountered.
5. Return the final length.

#include <stdio.h>

int my_strlen(const char *str) {


int length = 0;
while (str[length] != '\0') { // Continue until the null character is found
length++; // Increase the length count
}
return length; // Return the total length
}

int main() {
char str[] = "Hello, World!";
printf("Length of string: %d\n", my_strlen(str)); // Output: 13
return 0;
}

2. my_strcpy() – Copying One String to Another

Definition:
The my_strcpy() function copies each character from a source string to a destination string,
ensuring the destination string is null-terminated.

Steps:

1. Initialize an index variable (i) to 0.


2. Use a loop to copy each character from the source string to the destination.
3. Stop when the null character is reached.
4. Add a null character at the end of the destination string to terminate it.
#include <stdio.h>

void my_strcpy(char *dest, const char *src) {


int i = 0;
while (src[i] != '\0') { // Continue until the null character in source
dest[i] = src[i]; // Copy each character to the destination
i++;
}
dest[i] = '\0'; // Null-terminate the destination string
}

int main() {
char source[] = "Hello";
char destination[20];
my_strcpy(destination, source);
printf("Copied string: %s\n", destination); // Output: Hello
return 0;
}

3. my_strcat() – Concatenating Two Strings

Definition:
The my_strcat() function appends one string (source) to the end of another string (destination).

Steps:

1. Find the end of the destination string (where the null character '\0' is).
2. Use a loop to copy characters from the source string to the end of the destination
string.
3. Add the null character at the end of the concatenated string.

#include <stdio.h>

void my_strcat(char *dest, const char *src) {


int i = 0;
while (dest[i] != '\0') { // Find the end of the destination string
i++;
}

int j = 0;
while (src[j] != '\0') { // Copy characters from source to destination
dest[i] = src[j];
i++;
j++;
}
dest[i] = '\0'; // Null-terminate the concatenated string
}

int main() {
char str1[50] = "Hello";
char str2[] = " World!";
my_strcat(str1, str2);
printf("Concatenated string: %s\n", str1); // Output: Hello World!
return 0;
}

4. my_strcmp() – Comparing Two Strings

Definition:
The my_strcmp() function compares two strings. It returns a negative value if the first string
is smaller, 0 if both strings are equal, or a positive value if the first string is greater.

Steps:

1. Compare each character of both strings one by one.


2. If a mismatch is found, return the difference between the characters.
3. If both strings are equal up to the null character, return 0.
4. If one string is shorter and the other matches up to the null character, the shorter
string is considered smaller.

#include <stdio.h>

int my_strcmp(const char *str1, const char *str2) {


int i = 0;
while (str1[i] != '\0' && str2[i] != '\0') { // Compare until one string ends
if (str1[i] != str2[i]) {
return str1[i] - str2[i]; // Return the difference if characters don't match
}
i++;
}
return str1[i] - str2[i]; // Compare the null characters if strings are equal up to this point
}

int main() {
char str1[] = "Hello";
char str2[] = "World";
int result = my_strcmp(str1, str2);
if (result < 0)
printf("\"%s\" is less than \"%s\"\n", str1, str2);
else if (result == 0)
printf("\"%s\" is equal to \"%s\"\n", str1, str2);
else
printf("\"%s\" is greater than \"%s\"\n", str1, str2);
return 0;
}
Summary:
 Strings in C: A string is an array of characters, ending with the null character ('\0').
 String Operations:
o my_strlen(): Finds the length of a string.
o my_strcpy(): Copies one string into another.
o my_strcat(): Concatenates (appends) one string to another.
o my_strcmp(): Compares two strings to determine which is lexicographically greater
or smaller.

These functions provide basic string operations without using the C standard library
functions. Each function helps you manipulate strings in a controlled way.

You might also like