Pointer: The Memory Address of Another Data

  1. "Pointers" seems to be the most daunting concept in C language. However, you don't need to be scared. Essentially a pointer is simply a variable, which stores a memory address, that points to another data.
  2. We can use the address-of operator (&) to get the pointer to a variable. For example,
    int  n = 10;
    int* p = &n;
    
  3. Because a pointer is merely a memory address, it can be printed out. For printf(), you may
    printf("%p\n", &n)
  4. For cout, you must convert the "pointer to char" to other type of pointer, otherwise when cout gets a pointer to char, it will try to output a sequence of characters, starting from the address pointed by that pointer, until it encounters '\0'.
  5. If you want to convert from "pointer to char" to "pointer to void", in C you may use "(void*) &n)", in C++ you use "reinterpret_cast<void*>(&n)".
  6. You all have written recursive functions. For example, the following code prints the reverse of a char array by recursively calling a function reverse().
    #include <iostream>
    using std::cout;
    using std::endl;
    
    void reverse(const char* s) {
        if (*s == '\0')
            return;
        reverse(s+1);
        cout << *s;
    }
    
    int main()
    {
        reverse("ALICE");   cout << endl;
        return 0;
    }
  7. You may have heard that each time when a function recursively calls itself, it allocates an independent memory frame from the operating system. The first one is placed at the bottom of memory; the next one on top of it; and the next on top of the previous one, and so on.
    Recursive Function Call
  8. Let's modify the previous recursive function so that it prints out the memory address of the function parameter s whenever the function is invoked.
  9. The output may look like the following. However, please note that the memory address may differ because each time the operation system may arrange your program to run at a different address. (This is a busy server which serves multiple users.)
    E - 0x7ffc20c0bcf8
    C - 0x7ffc20c0bd18
    I - 0x7ffc20c0bd38
    L - 0x7ffc20c0bd58
    A - 0x7ffc20c0bd78
  10. Nethertheless, you should be able to observe that the first function call occupies the highest memory address, while the last last one occupied the lowest memory address.
    Note: In my program, the function will not output anything until the recursive call to the next level finishes. Therefore, the first call (which outputs 'A') is the last one to print out, while the last call (which outputs 'E') is the first one to print out.