C Pointers 6th April 07 Giulio Picierro <giulio.picierro@uniroma.it>
Functions Return type Function name Arguments list Function body int sum(int a, int b) { return a + b; } Return statement (return keyword + value)
Functions Function argument pass By value void my_function(int a) { a++; } int main(void) { int b = 0; my_function(b); printf("b=%d\n", b); } A copy of variable is made. Modifying a variable inside a function, DOES NOT modify variable outside.
Functions Function argument pass By reference No copy is made: a reference is passed Modifying a variable inside called function, MODIFY variable outside C doesn t support this, but you can pass pointers!
Data type that represents a memory address Typically pointers to variables, i.e. address of variables. Declaration: or: T* var_name; T *var_name; How to read it: Pointer to T
Data type that represents a memory address You can retrieve address of a variable using the & operator Memory 48 int num = 5; int *num_addr = # 5 56 60 5 987 num num_addr 5 64 68 3 5
Dereference You can retrieve pointed value using the * operator Memory int a = *num_addr; a 5 5 5 56 987 Here, a is a new variable which holds a copy of num. This means that address of a is different from address of num num_addr 5 48 60 64 68 3 5 num
Dereference You can change pointed value using the * operator Memory *num_addr = 3; 5 3 num_addr 5 48 56 60 64 68 987 3 5 num
Functions Function argument pass By address : Address of variable passed by value void my_function(int *a) { (*a)++; } int main(void) { int b = 0; my_function(&b); printf("b=%d\n", b); } Increase value pointed by a (dereference) Passing memory address of b.. Passing by reference doesn t exists in C
NULL A pointer with address value of 0 is considered NULL pointer Special value => Point to nothing => Invalid pointer Memory 48 5 5 num int *num_addr = NULL; 56 60 987 num_addr 0 64 68 3 5
Dereference Dereference a NULL pointer is an error! Memory int *num_addr = NULL; 48 int a = *num_addr; // the program will crash 5 56 5 987 num 60 num_addr 0 64 68 3 5
Arithmetic Different from integer arithmetic int num = 5; 48 5 56 60 64 68 Memory 5 987 3 5 num
Arithmetic Different from integer arithmetic int num = 5; num++; 48 5 56 60 64 68 num now is 6 Memory 6 987 3 5 num
Arithmetic Different from integer arithmetic int num = 5; num++; Pointer arithmetic int *num_addr = # 48 5 Memory 6 num 56 987 60 num_addr 5 64 68 3 5
Arithmetic Different from integer arithmetic int num = 5; num++; Pointer arithmetic int *num_addr = # num_addr++; 48 5 56 Memory 6 987 num 60 Pointer is increased by 4!!! num_addr 56 64 68 3 5
Arithmetic Given a pointer T* Increase a pointer by one equals to increase by sizeof(t) num_addr 56 48 5 56 60 64 68 Memory 6 987 3 5
Arithmetic Given a pointer T* Increase a pointer by one equals to increase by sizeof(t) char *a = ; short *b = ; double *c = ; a++; // a now is 3 b++; // b now is 4 c++; // c now is 0 num_addr 56 48 5 56 60 64 68 Memory 6 987 3 5
Pointers and Arrays Same values: array &(array[0]) array[i] *(array + i) Different types: array is an int[7] array+i is an int* 6 0 4 8 3 36 array 3 5 8 3 array[0] array[] array[] array[3] array[4] array[5] array[6]
Pointers and Arrays array int array[] = {,,, 3, 5, 8, 3}; 6 array[0] int* ptr = array; ptr 6 0 4 array[] array[] 8 3 array[3] 3 5 array[4] 36 8 array[5] 3 array[6]
Pointers and Arrays array int array[] = {,,, 3, 5, 8, 3}; 6 array[0] int* ptr = array; ptr++; ptr 0 0 4 array[] array[] 8 3 array[3] 3 5 array[4] 36 8 array[5] 3 array[6] NOTE: Pointers have their arithmetic, increase a pointer T* by one, means increase address by sizeof(t)
Pointers and Arrays array int array[] = {,,, 3, 5, 8, 3}; 6 array[0] int* ptr = array; ptr++; ptr 0 4 array[] array[] ptr = array + 6; 8 3 array[3] 3 5 array[4] 36 8 array[5] 3 array[6] NOTE: Pointers have their arithmetic, increase a pointer T* by one, means increase address by sizeof(t)
Pointers and Arrays array int array[] = {,,, 3, 5, 8, 3}; 6 array[0] int* ptr = array; ptr++; ptr 0 4 array[] array[] ptr = array + 6; 8 3 array[3] *ptr = ; 3 5 array[4] 36 8 array[5] array[6] NOTE: Pointers have their arithmetic, increase a pointer T* by one, means increase address by sizeof(t)
Pointers and Arrays array int array[] = {,,, 3, 5, 8, 3}; 6 array[0] int* ptr = array; ptr++; ptr 4 0 4 array[] array[] ptr = array + 6; 8 3 array[3] *ptr = ; 3 5 array[4] ptr = &array[]; 36 8 array[5] array[6] NOTE: Pointers have their arithmetic, increase a pointer T* by one, means increase address by sizeof(t)
Pointers and Arrays array int array[] = {,,, 3, 5, 8, 3}; 6 array[0] int* ptr = array; ptr++; ptr 4 0 4 7 array[] array[] ptr = array + 6; 8 3 array[3] *ptr = ; 3 5 array[4] ptr = &array[]; ptr[0] = 7; 36 8 array[5] array[6] NOTE: Pointers have their arithmetic, increase a pointer T* by one, means increase address by sizeof(t)
Arrays and functions Arrays are always passed by base address 6 0 array array[0] array[] void function(int v[]) { v[3] = 7; } 4 8 3 3 5 array[] array[3] array[4] 36 8 array[5] 3 array[6]
Arrays and functions Arrays are always passed by base address 6 0 array array[0] array[] void function(int v[]) { v[3] = 7; } 4 8 3 7 5 array[] array[3] array[4] function(array); 36 8 array[5] You re not copying the array, but the base address!!! Change an element of the array inside the function equals to change the element of the original array!!! 3 array[6]
Arrays and functions Arrays are always passed by base address 6 0 array array[0] array[] int* function(void) { int array[] = {,, 3, 4, 5}; } return array; 4 8 3 36 3 5 8 array[] array[3] array[4] array[5] Returning a pointer to a local variable IS AN ERROR! Since local variables lives on the stack, the memory of those variables could be overwritten by subsequent function calls! 3 array[6]
Pointers and Const const int* p; *p = 5; // compiler error p = NULL; // ok int* const p; *p = 5; // ok p = NULL; // compiler error () () Read from right to left: ) Pointer to int const ) Const pointer to int 3) Const pointer to int const const int* const p; *p = 5; // compiler error p = NULL; // compiler error (3)