Last Updated: February 25, 2016
·
376
· clubsonmeteor

To make it easier for myself to understand pointer:

Pointer

Why?

Moving is expensive and should be avoided at the expense of making the code more complicated.

Consider this analogy. Bob and you have identical farm land, but Bob has 1000 sheep while you have 1000 cows. One day, you two decide to swap all his sheep with all your cows. You can hire a shepherd to move the sheep and cows, or you two can just switch farms, by telling the post office your addresses have swapped.

For example, let say we want to swap two 1000-entries arrays a and b 100001 times.
The naive way is to switch the thousands of entries like so

#include <stdio.h>

int main() {
  int array_size = 1000;
  char a[array_size];
  char b[array_size];

  int i;
  for (i = 0; i < array_size - 1; i++){
    a[i] = 'a';
    b[i] = 'b';
  }
  a[array_size] = '\0';
  a[array_size] = '\0';

  printf("Before swapping, first char of a is %c\n", a[0]);
  printf("Before swapping, first char of b is %c\n", b[0]);


  char temp[array_size];
  int j;
  for (j = 0; j < 100001; j++){
    for (i = 0; i < array_size; i++) {
      temp[i] = b[i];
      b[i] = a[i];
      a[i] = temp[i];
    }
  }

  printf("After swapping, first char of a is %c\n", a[0]);
  printf("After swapping, first char of b is %c\n", b[0]);

  return 0;
} 

This takes a noticeable amount of time. But if we don't swap the locations of the data, but just swap how we name them, then it takes less time:

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

int main() {
  int array_size = 1000;
  char* a;
  char* b;
  a = (char*) malloc(sizeof(char) * array_size);
  b = (char*) malloc(sizeof(char) * array_size);

  int i;
  for (i = 0; i < array_size - 1; i++){
    a[i] = 'a';
    b[i] = 'b';
  }
  a[array_size] = '\0';
  a[array_size] = '\0';

  printf("Before swapping, first char of a is %c\n", *a);
  printf("Before swapping, first char of b is %c\n", *b);

  int j;
  for (j = 0; j < 100001; j++){
    char* tmp;
    tmp = b;
    b = a;
    a = tmp;
  }

  printf("After swapping, first char of a is %c\n", *a);
  printf("After swapping, first char of b is %c\n", *b);
  return 0;
} 

Before trying to understand what's going on above, let's start with something simpler

Basics

Consider the program

#include <stdio.h>

int main() {
  int x;
  x = 1;
  printf("%d\n", x);
  return 0;
}

What's happening?

  1. int x; allocate 4 bytes of space named x, whose address is &x
  2. x = 1; assign 1 to the space located at &x
  3. printf gets the value at space &x

Here is a similar procedure, but with an extra flexibility.

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

int main() {
  int* p;
  p = (int*) malloc(sizeof(int));
  *p = 1;
  printf("%d\n", *p);
  return 0;
}

You should think of x from before as *p, and the value of the address &x as p. Before, &x is constant because it is a physical address. Now, p can be changed, like so p = &y, because p is the value of the address, not the actual physical address. Here's what's happening

  1. int* p; allocates space for p, which stores the value of an address
  2. malloc allocates space for *p (a.k.a. x)
  3. *p = 1; assign 1 to the space (a.k.a. x)
  4. retrieves the value *p (a.k.a. x)