Chapter 5 Pointers and Arrays by Brian Kernighan and Dennis Ritchie

What is a pointer?
A pointer is a variable that contains the memory address of another variable.

What are the two reasons that C uses pointers?
The two reasons that C uses pointers are:

  1. They're the only way to express a computation sometimes.
  2. They usually lead to more compact and efficient code.

What used to be the data type for a generic pointer?
The data type for a generic pointer used to be void *.

What is the data type for a generic pointer now?
The data type for a generic pointer now is char *.

5.1 Pointers and Addresses

How is memory organized in a typical machine?
In a typical machine, memory is organized as an array of consecutively numbered or addressed memory cells

How can the memory cells in a typical machine be manipulated?
The memory cells in a typical machine can be manipulated individually or in contiguous groups.

Typically, how many bytes is a char in C?
Typically, a char in C is 1 byte.

Typically, how many bytes is a short integer in C?
Typically, a short integer in C is 2 bytes.

Typically, how many bytes is a long in C?
Typically, a long in C is 4 bytes.

Typically, how many bytes is a pointer in C?
Typically, a pointer in C is 2-4 bytes.

What does the unary operator & do?
The unary operator & gives the address of an object.

What are the only two objects the & operator applies to?
The only two objects the & operator applies to are:

  1. Variables.
  2. Array elements.

What three things can the & operator not be applied to?
Three things the & operator cannot be applied to are:

  1. Expressions.
  2. Constants.
  3. register variables.

What is the unary operator *?*
The unary operator * is the indirection or dereferencing operator.

What does the unary operator * do when applied to a pointer?
When applied to a pointer, the unary operator * accesses the object the pointer points to.

...

How do you declare a variable named ip which is a pointer for some int?
To declare a variable named ip which is a pointer for some int, write:

int *ip;

How do you assign a pointer variable named ip to point to a variable named x?
To assign a pointer variable named ip to point to a variable named x, write:

ip = &x;

How do you assign a variable named y to the value of the variable pointed to by the pointer ip?
To assign a variable named y to the value of the variable pointed to by the pointer ip, write:

y = *ip;

How do you change the value of a variable pointed to by a pointer named ip?
To change the value of a variable pointed to by a pointer named ip, write:

*ip = 0;
Note

When you see an asterisk (*) in the declaration of a variable between the data type and the variable name (like char *c, int *i, etc.), that means the variable is a pointer for that data type.

char *c;
int *i;

If a function declaration's argument list has declarations which look like what's described above (asterisk between the data type and variable name), that means the function accepts pointers of that data type.

void swap(int *px, int *py)
{
	/*...*/
}

After a pointer is declared and assigned with the memory location of a variable, its name (with no other symbols or operators) refers to the memory location of that original variable.

int *px;
int regular_var = 10;
px = &regular_var;

/* The output of both statements below is the same. */
printf("%p", (void *)px);
printf("%p", (void *)&regular_var);

When you see an asterisk to the left of the variable name of a pointer, that means you're working with its value (either changing the value, assigning the value to another variable, passing the value to another function, etc.).

int *px;
int regular_var = 1;
int new_value = 2;

/* Assigns the value of the variable pointed to by px to the variable regular_var. */
regular_var = *px;

/* Assigns the value of the variable new_value to the variable pointed to by px. */
*px = new_value;

When you see an ampersand (&) to the left of a variable, that means you're working with the variable's memory address (either assigning it to a pointer, passing it to a function, etc.). It cannot appear on the left of the assignment operator (=).

/* Make two pointers point to two specific variables. */
int *px = &regular_var;
int *py = &new_value;

/* Both lines below have the same effect. */
swap(&regular_var, &new_value);
swap(px, py);

...

What is the constraint that pointers have?
The constraint that pointers have is they point to a specific data type.

What is the one exception to the data type constraint of pointers?
The one exception to data type constraint of pointers is a pointer to void, which can hold any type of pointer.

Can a dereferenced pointer be used in contexts where the original variable can appear?
Yes, a dereferenced pointer be used in contexts where the original variable can appear.

...

How do you make a pointer named iq point to the same variable as another pointer called ip?
To make a pointer named iq point to the same variable as another pointer called ip, write:

iq = ip;

5.2 Pointers and Function Arguments

How does C pass arguments to functions?
C passes arguments to functions by value.

...

What is the only way for a function in C to directly affect variables passed to it as arguments?
The only way for a function in C to directly affect variables passed to it as arguments is to take pointers to the variables as arguments.

If you had a function with the declaration void swap(int x, int y), how would you change the function to take two pointers instead of two values?
If you had a function with the declaration void swap(int x, int y), you would change the function to take two pointers instead of two values by writing:

void swap(int *px, int *py)

If you had a function with the declaration void swap(int *px, int *py), how would you pass two pointers to it as arguments?
If you had a function with the declaration void swap(int *px, int *py), you would pass two pointers to it as arguments by writing:

swap(&a, &b);

What is the source code for a function with the declaration void swap(int *px, int *py)?
The source for a function with the declaration void swap(int *px, int *py) is:

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

	temp = *px;
	*px = *py;
	*py = temp;
}

Pointer arguments enable a function to ... and ... objects in the function that called it?
Pointer arguments enable a function to access and change objects in the function that called it.

...

5.3 Pointers and Arrays

What are the two ways of accessing the elements of an array?
The two ways of accessing the elements of an array are:

  • Subscripting.
  • Using pointers.

...

If a pointer named pa points a particular element of an array named a, what would incrementing pa by 1 do?
If a pointer named pa points to a particular element of an array named a, incrementing pa by 1 would make pa point to the next element in the array.

If a pointer named pa points a particular element of an array named a, what would decrementing pa by 1 do?
If a pointer named pa points to a particular element of an array named a, decrementing pa by 1 would make pa point to the previous element in the array.

Will incrementing or decrementing a pointer to an element in an array will always make the pointer point to the next or previous element in the array regardless of the data type or size of the variables in the array?
Yes, incrementing or decrementing a pointer to an element in an array will always make the pointer point to the next or previous element in the array regardless of the data type or size of the variables in the array.

...

What does the variable name of an array refer to?
The variable name of an array refers to the memory address of the first element of that array.

What are some expressions involving arrays and pointers to elements in array which are equivalent?
Some expressions involving arrays and pointers to elements in arrays which are equivalent are:

Expression 1 Expression 2
pa = &a[0]; pa = a;
a[i] *(a+i)
&a[i] a+i
pa[i] *(pa+i)

What does C automatically do when it encounters a subscript for accessing a particular element of an array (like a[i])?
When C encounters a subscript for accessing a particular element of an array (like a[i]), it converts it to `(a+i)`.*

What is the difference between an array name and a pointer?
The difference between an array name and a pointer is that an array name is not a variable while a pointer is.

Are expressions like a = pa and a++ allowed?
No, expressions like a = pa and a++ aren't allowed.

Are expressions like pa = a and pa++ allowed?
Yes, expressions like pa = a and pa++ allowed.

When an array name is passed to a function as an argument, is it treated as an array or a pointer within the function?
When an array name is passed to a function as an argument, it is treated as a pointer within the function.

...

Note

When a function accepts a pointer as an argument, it uses its own private pointer which has the exact same memory address as what is passed to it when called from another function. Incrementing, decrementing, and changing the private pointer's memory address inside the function has no effect on the pointer that was passed to it as an argument from outside the function.

Are the formal parameters char s[]; and char *s; in a function definition equivalent?
Yes, the formal parameters char s[]; and char *s; in a function definition are equivalent.

...