Day 3 : 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

Living With Zombie Software

The budding software developer is excited! She has landed her first programming job. She’s never done programming for other humans before, but she’s eager to learn! She’s read plenty of books and has a plethora of pet projects under her... Continue →