POINTERS
POINTERS
Pointers are variables whose values are memory addresses. Normally, a variable directly
contains a specific value. A pointer, on the other hand, contains the address of a variable that
contains a specific value
A variable name directly references a value, and a pointer indirectly references a value.
Referencing a value through a pointer is called indirection.
DECLARING A POINTER
Pointers, like all variables, must be defined before they can be used.
int *countPtr, count;
The definition specifies that variable countPtr is of type int * (i.e., a pointer to an integer) and is
read, “countPtr is a pointer to int” or “countPtr points to an object of type int.”
Also, the variable count is defined to be an int, not a pointer to an int.
The * only applies to countPtrin the definition. When * is used in this manner in a definition, it
indicates that the variable being defined is a pointer. Pointers can be defined to point to objects
of any type.
INITIALIZING POINTERS
Pointers should be initialized either when they’re defined or in an assignment statement.
A pointer may be initialized to NULL, 0 or an address.
A pointer with the value NULL points to nothing.
NULL is a symbolic constant defined in the <stddef.h> header (and several other headers,
such as <stdio.h>). Initializing a pointer to 0 is equivalent to initializing a pointer to NULL,
but NULL is preferred.
When 0 is assigned, it’s first converted to a pointer of the appropriate type. The value 0 is
the only integer value that can be assigned directly to a pointer variable
POINTER OPERATORS
The &, or address operator, is a unary operator that returns the address of its operand. For
example, assuming the definitions
int y = 5;
int *yPtr;
The statement assigns the variable y’s address to pointer variable yPtr. Variable yPtr is then
said to “point to” y. Below is a schematic representation of memory after the preceding
assignment is executed.
yPtr = &y;
POINTER OPERATORS
The unary * operator, commonly referred to as the indirection operator or dereferencing
operator, returns the value of the object to which its operand (i.e., a pointer) points. For
example, the statement
printf( "%d", *yPtr );
Prints the value of variable y, namely 5. Using * in this manner is called dereferencing a pointer.
EXAMPLE OF POINTERS
#include <stdio.h>
printf("Value of x: %d\n", x); // Print the
int main(){
value of x
printf("Address of x: %p\n", (void*)&x); //
int y = 5, x=20;
Print the address of x
printf("Value of y: %d\n", y); // Print the value
of y
printf("Address of y: %p\n", (void*)&y); // Print return 0;
the address of y
}
POINTER OPERATORS EXPLAINED
The code snippet above demonstrates the pointer operators & and *. The printf conversion
specifier %p outputs the memory location as a hexadecimal integer on most platforms.
Notice that the address of a and the value of aPtr are identical in the output, thus
confirming that the address of a is indeed assigned to the pointer variable aPtr.
The & and * operators are complements of one another—when both are applied
consecutively to aPtr in either order , the same result is printed.
RECAP : ARRAYS AND POINTERS
An array is a collection of objects of the same type that you can refer to using a single
name. For example, an array called scores[50] could contain all your basketball scores
for a 50-game season.
You use a different index value to refer to each element in the array. scores[0] is your first score
and scores[49] is your last.
If you had ten games each month, you could use a multidimensional array, scores[12][10]. If
you start playing in January, the third game in June would be referenced by scores[5][2].
A pointer is a variable that has as its value the address of another variable or constant of
a given type. You can use a pointer to access different variables at different times, as
long as they’re all of the same type.
An array name by itself can be used to refer to an address
ARRAY EXAMPLE
#include <stdio.h>
int main(void)
{
char multiple[] = "My string";
char *p = &multiple[0];
printf("\nThe address of the first array element : %p", p);
p = multiple;
printf("\nThe address obtained from the array name: %p\n", p);
return 0;
}
ARRAYS AS POINTERS EXPLAINED
From the output of this program that the expression &multiple[0] produces the same value as
the expression multiple.
This is what you might expect because multiple evaluates to the address of the first byte of the
array, and &multiple[0] evaluates to the first byte of the first element of the array, and it would
be surprising if these were not the same.
If p is set to multiple, which has the same value as &multiple[0], what does p + 1 equal?
ARRAY EXAMPLE 2
#include <stdio.h>
int main(void) {
char multiple[] = "a string"; char *p = multiple;
for(int i = 0 ; i<strlen(multiple) ; i++)
printf("\nmultiple[%d] = %c *(p+%d) = %c &multiple[%d] = %p p+%d = %p", i, multiple[i], i,
*(p+i), i, &multiple[i], i, p+i);
return 0; }
ARRAY EXAMPLE 3
#include <stdio.h>
int main(void) {
long multiple[] = {15L, 25L, 35L, 45L}; long * p = multiple;
for(int i = 0 ; i<sizeof(multiple)/sizeof(multiple[0]) ; i++) printf("\naddress p+%d
(&multiple[%d]): %d *(p+%d) value: %d",
i, i, p+i, i, *(p+i));
printf("\n Type long occupies: %d bytes\n", sizeof(long)); // you get to see that each element
is four bytes
return 0; }
POINTERS IN FUNCTION ARGUMENTS
There are two ways to pass arguments to a function: pass-by-value and pass-by-reference.
All arguments in C are passed by value.
Return may be used to return one value from a called function to a caller (or to return control from a
called function without passing back a value). Many functions require the capability to modify
variables in the caller or to pass a pointer to a large data object to avoid the overhead of passing the
object by value (which incurs the time and memory overheads of making a copy of the object).
In C, you use pointers and the indirection operator to simulate pass-by-reference. When calling a
function with arguments that should be modified, the addresses of the arguments are passed. This is
normally accomplished by applying the address operator (&) to the variable (in the caller) whose
value will be modified.
Arrays are not passed using operator & because C automatically passes the starting location in
memory of the array (the name of an array is equivalent to &arrayName[0]).
When the address of a variable is passed to a function, the indirection operator (*) may be used in the function
to modify the value at that location in the caller’s memory
PASS BY VALUE AND PASS BY REFERENCE
A function that cubes an integer—cubeByValue and cubeByReference. The first code
snippet passes the variable number by value to function cubeByValue. The cubeByValue
function cubes its argument and passes the new value back to main using a return
statement. The new value is assigned to number in main.
The second code snippet passes the variable number by reference —the address of number
is passed—to function cubeByReference. Function cubeByReference takes as a parameter a
pointer to an int called nPtr . The function dereferences the pointer and cubes the value to
which nPtr points, then assigns the result to *nPtr (which is number in main), thus changing
the value of number in main.
PASS BY VALUE
#include <stdio.h> printf("\nThe new value of number is %d\n",
number);
int cubeByValue(int n); // Function prototype
return 0; // Return statement for main
int main(void) {
}
int number = 5; // Initialize number
int cubeByValue(int n) {
printf("The original value of number is %d",
number); return n * n * n; // Calculate the cube
number = cubeByValue(number); }
PASS BY REFERENCE
#include <stdio.h>
void cubeByReference (int *nPtr); printf (“\the new value of number is %d\n”,
number);
int main (void)
}
{
void cubeByReference (int *nPtr)
int number = 5;
{
printf( “The original value of number is %d”,
number); *nPtr * *nPtr * *nPtr ; //cube *nPtr
//pass address of number to cubeByReference }
cubeByReference (&number);
PASS BY REFERENCE
A function receiving an address as an argument must define a pointer parameter to receive
the address.
void cubeByReference( int *nPtr )
The header specifies that cubeByReference receives the address of an integer variable as
an argument, stores the address locally in nPtr and does not return a value.
The function prototype for cubeByReference contains int * in parentheses. As with other
variable types, it’s not necessary to include names of pointers in function prototypes.
Names included for documentation purposes are ignored by the C compiler.
READING ASSIGNMENT
COMMAND LINE ARGUMENTS