C Pointers
A pointer is a variable that holds an address
#include <stdio.h>
int main() { int i = 10; printf("The value of i is %d\n", i); printf("The address of i is %p\n", (void *) &i);};
Passing pointers as arguments
#include <stdio.h>
void increment(int *p) { *p = *p + 1;}
int main() { int i = 10; int *j = &i;
printf("i is %d\n", i); printf("j is also %d\n", *j); increment(j); printf("i is %d\n",i );};
Pointers and Arrays
- When a pointer is assigned to an array, it points to the first element of the array.
#include <stdio.h>
int main() { int a[5] = {11,22,33,44,55}; int *p;
p = a; printf("%d\n", *p); // 11 printf("%d\n", *(p+1)); // 22};
- Array/Pointer Equivalence in function calls
void test(char *s){ printf("%c", *s);}int main(void){ char s[]="Antelopes"; char *t = "Wombats";
test(s); //works test(t); //works, too}
- Changing arrays in functions
#include <stdio.h>
void double_array(int *a, int len){ for (int i = 0; i< len;i++){ a[i] *= 2; }}
int main() { int x[5] = {1,2,3,4,5}; double_array(x,5);
for (int i = 0; i< 5; i++){ printf("%d\n", x[i]); }
};
Void pointer
- Sometimes it’s useful to have a pointer to a thing that we don’t know the type of.
- Example use case:
void *memcpy(void *s1, void *s2, size_t n);
- This function copies n bytes of memory starting from address s2 into the memory starting at address s1. With the
void *
type, we can use this function to copy any type.
char s[] = "Goats!";char t[100];memcpy(t,s,7); //Copy 7 bytes including the NUL terminator;
int a[] = {11,22,33};int b[3];memcpy(b,a,3*sizeof(int));printf("%d\n", b[1]); // 22
- A more practical example:
#include <stdio.h>#include <stdlib.h>
typedef struct { char *name; int leg_count;} animal;
int compar(const void *elem1, const void *elem2){ const animal *animal1 = elem1; const animal *animal2 = elem2;
if (animal1->leg_count > animal2->leg_count){ return 1; } if (animal1->leg_count < animal2->leg_count){ return -1; } return 0;};
int main(){ animal a[4] = { {.name="Dog", .leg_count=4}, {.name="Monkey", .leg_count=2}, {.name="Antelope", .leg_count=4}, {.name="Snake", .leg_count=0} };
qsort(a,4,sizeof(animal), compar);
for (int i = 0; i < 4 ;i++){ printf("%d: %s\n", a[i].leg_count, a[i].name); }}
Pointers to Pointers
- When we use pointer as an argument in function, only changes in where this pointer is pointing at
#include <stdio.h>#include <stdlib.h>
void change_pointer(int *p){ printf("[Begin of func]: \n\tValue of p = %d\n\tAddress of p = %p\n", *p, p); // 200;
int *b; b = malloc(sizeof(int)); *b = 100;
p = b; // 100 printf("[End of func]: \n\tValue of p = %d\n\tAddress of p = %p\n", *p, p);}
int main(void){ int x = 200; int *p = &x; printf("-------- CALLING FUNCTION ----------\n"); change_pointer(p); printf("-------- **************** ----------\n"); printf("[Main]: \n\tValue of p = %d\n\tAddress of p = %p\n", *p, p); // p still points to address of x // 200;}
Pointers to Functions
#include <stdio.h>#include <stdlib.h>
int add(int num1, int num2){ return num1 + num2;}
int subtract(int num1, int num2){ return num1 - num2;}
typedef int (*fptrOperation)(int,int);
int compute(fptrOperation operation, int num1, int num2){ return operation(num1, num2);}
int main(void){ int a = 10; int b = 20; printf("Result is: %d\n", compute(add, a, b));}