Skip to content

C Pointers

A pointer is a variable that holds an address

pointer.c
#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

pointers_as_arguments.c
#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.
pointers_and_arrays.c
#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
double_array.c
#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));
}