Pointers

#include stdio.h

char *copy_string(char *source, char *destination) {
  int *start = destination;
  while (*source != '\0') {
    *destination++ = *source++;
  }
  *destination = '\0';
  return start;
}

int main() {
  char a[9] = "hello";
  char b[9];
  char *pA = a;
  char *pB = b;
  copy_string(a, b);
  return 0;
}

Pointers. int x = 12; allocates a block of memory (4 bytes for 32, 8 bytes for 64 bit OSes) and then 12 is placed into that block of memory. If you then do int y = x;, you have taken the value of x, which is 12, and then placed that value also in the allocation for y.

However — I don’t know if this is only because integers are constants - I don’t think this would be the same for objects.

&x is the memory address that the x block exists under. Addresses are stored in “pointer types”. I thought that all things storing addresses should be integers, but that doesn’t seem to be the case. There are pointer ‘modifiers’ on the types. int *pX; is a pointer, and if you do int *pX = 4;, your compiler will yell at you.

One weird thing - declaring a pointer with an *, but you also reference the value of the block at the pointers address with *. For example:

int c = 5;            // put 5 in the c box
int *pC = &c;     // store the address of c in pC, an int pointer
int c_copy = *pC; // get the value of the box at the address of c, which is 5

c_copy holds 5.

 Arrays

Arrays are, simply, multiple blocks of allocated memory. int x; allocates 1 block (of arbitrary size for now) for an integer. int x[5]; allocates 5 blocks of memory for 5 integers. Interestingly, if you reference x, alone, you are actually referencing a pointer to the first element in the array. So if you have the following:

int x[5] = {10, 11, 12, 13, 14};

And said int y = *x;, y would be 10. * in this case is getting the value at the address of the first int in x. Normally, to do this, you would say x[0]. Curiously, this is actually just shorthand for *(x + 0).

Huh?

x is a pointer. Doing arithmetic on pointers is pointer arithmetic. C gets a bit magic here - x + 1 actually means the next memory block. The one in this case is 1 memory block (which may be n bytes, depending on the system). (x+1) means ‘the memory block after x’. *(x+1) means ‘the value in the memory block after x’.

int y = *(x+1); and int y = x[1]; are equal.

But int y = *x++;

The third however, requires some more explanation. The order of operations is screwy. x is a pointer. *x returns the value of the block at x. ++ then increments the pointer, not the value. So after int y = *x++; runs, x is the address of the memory block after the original address x held.

x[n] is a shorthand for *(x + n). Back to the original code.

#include stdio.h

char *copy_string(char *source, char *destination) { // cP + cP => cP
  int *start = destination; // copy first element address for later
  while (*source != '\0') { // \0 will always be last element
    *destination++ = *source++; 
    //value of first destination block is now equal to value of source
    // destination and source are also now pointing to next block
  }
  *destination = '\0'; // make sure to end destination with \0
  return start; //return address of first element in destination
}

int main() {
  char a[9] = "hello";
  char b[9];
  char *pA = a;
  char *pB = b;
  copy_string(a, b);
  return 0;
}
 
3
Kudos
 
3
Kudos

Now read this

What is a Bloom Filter, Really?

When are sets not enough? As we’ve seen, sets provide a powerful and efficient solution to specific problems. They allow you to efficiently determine if something belongs in a certain categorization, or not. Have I seen this song before?... Continue →