Pointer and Smart Pointer

Pointer

A pointer is a group of memory cells that can hold an address.

The operator & gives an address to an object, so the statement p = &c; assigns the address of c to the variable p, or p points to c

The operator * is the indirection or dereferencing operator, meaning if applied to pointer, it accesses the object the pointer points to

Consider

int x = 1, y = 2, z[10];
int *ip;

ip = &x; // ip points to x
y = *ip; // y is now 1
*ip = 0; // x is now 0
ip = &z[0]; // ip now points to z[0]

The below example outputs the same result

y = *ip + 1 // increments whatever ip points to by 1
++*ip
(*ip)++ // if parentheses are ommitted, it will increment ip as variable instead

Pointer as Arguments

Since C passes arguments to functions by value, it’s not enough to use variables as functions’ parameters

Consider a swap function that performs type casting

Normally, we would write

void swap(int x, int y) {
    int tmp;

    tmp = x;
    x = y;
    y = tmp;
}

Because of call by value, this function can’t affect the arguments in the routine that calls it; it only swaps copies of x and y

To obtain the desired behavior, we pass pointers as parameters

void swap(int *px, int *py) {
    int tmp;

    tmp = *px;
    *px = *py;
    *py = tmp;
}

swap(&a, &b);

Now, consider the function getint that performs free-format input conversion

We want to input a stream of inputs, break them and convert them into integer one by one

Then, signal EOF when there’s no input

We can use a pointer as parameter

The function would be

#include <ctype.h>

int getint(int *pn) {
    int c, sign;

    while (isspace(c = getch())) {
        ; // skip white type
    }

    // validate if c is a number
    if (!isdigit(c) && c != EOF &&  c != '+' && c != '-') {
        ungetch(c);
        return 0;
    }

    if (c == '-') {
        sign = -1;
    } else {
        sign = 1;
    }

    if (c == '+' || c == '-') {
        c = getch();
    }

    for (*pn = 0; isdigit(c); c = getch()) {
        *pn *= 10;
        *pn += (c - '0');
    }

    *pn *= sign;

    if (c != EOF) {
        ungetch(c);
    }

    return c;
}

Pointers and Arrays

If pa is a pointer to an integer, declared as int *pa;, then the assignment pa = &a[0]; sets pa to point to element zero of a; that is, pa contains the address of a[0]

Now the assignment x = *pa; will copy the contents of a[0] into x

If pa points to a particular element of an array, then by definition pa + 1 points to the next element, pa + i points i elements after pa, and pa - i points i elements before

Thus, if pa points to a[0], *(pa+1) refers to the contents of a[1], pa + i is the address of a[i], and *(pa + i) is the contents of a[i]

By definition, the value of a variable or expression of type array is the address of element zero of the array.