Pointers Chapters 69 in ABC Pointers int a
Pointers Chapters 6+9 in ABC
Pointers int a = 1, b = 2, *p; a b 1 2 p & - reference operator (address) * - dereference operator (value) p = &a; // *p is now 1 a b 1 2 p
Why are they important? • • Call by reference Efficient argument passing to functions Dynamic memory allocation Efficient memory manipulation
Call by reference #include <stdio. h> void swap(int *p, int *q) { int tmp; tmp = *p; *p = *q; *q = tmp; } int main(void) { int i = 3, j = 5; swap(&i, &j); printf( “%d %dn”, i, j ); return 0; } Define pointers as params Use dereferenced values Pass addresses as arguments
Arrays and Pointers a[i] is equivalent to *(a + i) An array name is an address! p[i] is equivalent to *(p + i) for ( p = a; p < &a[ N ]; ++p ) sum += *p; is equivalent to: for ( i = 0; i < N; ++i ) sum += a[i]; The main difference between the two: a pointer can be modified, an array cannot, it is a CONSTANT pointer!
Pointer Arithmetic and Element Size double a[2], *p = NULL, *q = NULL; points to the base of the array p = a; equivalent to q = &a[ 1 ] q = p +1; 1 is printed printf(“%dn”, q - p); sizeof(dobule)==8 is printed printf(“%dn”, (int)q - (int)p);
Passing an array to a function double sum(double a[], int n) Base address is passed call by value. { int i = 0; double sum = 0. 0; for ( i = 0; i < n; ++i ) sum += a[i]; return sum; } What will sum(a+3, 3) compute?
Strings char s[] = “abcde” s a #include <string. h> char *strcat(char *s 1, const char *s 2); int strcmp(const char *s 1, const char *s 2); char *strcpy(char *s 1, const char *s 2); unsigned strlen(const char *s); b c d e
An implementation example char *strcat( char *s 1, const char *s 2 ) { register char *p = s 1; while ( *p ) ++p; while ( *p++ = *s 2++ ) ; return s 1; }
Dynamic memory allocation • #include <stdlib. h> • Functions work with void * - a generic pointer; all return NULL on failure • size_t is typically unsigned int void *calloc( size_t n, size_t el_size) //all allocated bytes are initialized to zero void *malloc( size_t size ) //no initialization void free( void *ptr )
Lexicographical sort (lexi-sort. c) int main(void) { an array of pointers char *w[N]; char word[MAXWORD]; work space int n = 0, i = 0; for ( i = 0; scanf("%s", word) == 1; ++i ) { if ( i >= N ) { printf( “Sorry, at most %d words can be sorted. ”, N ); exit(1); } w[i] = calloc(strlen(word) + 1, sizeof(char)); assert(w[i]!=NULL); Check allocation strcpy(w[i], word); }
Lexicographical sort n = i; sort_words( w, n ); print the sorted words for ( i = 0; i < n; ++i ) printf( “%sn”, w[i] ); return 0; }
Lexicographical sort void sort_words( char *w[], int n ) { n elements to be sorted int i = 0, j = 0; for ( i = 0; i < n; ++i ) for ( j = i + 1; j < n; ++j ) if ( strcmp(w[i], w[j]) > 0 ) swap( &w[i], &w[j] ); } void swap( char **p, char **q ) { char *temp = NULL; temp = *p; *p = *q; *q = temp; }
Arguments to main() (echo. c) #include <stdio. h> void main(int argc, char *argv[]) { int i = 0; printf( “argc = %dn”, argc ); for ( i = 0; i < argc; ++i ) printf( “argv[%d] = %sn”, i, argv[i] ); }
Multidimensional Arrays int a[5][2]={{1, 2}, {3, 4}, {5, 6}, {7, 8}, {9, 10}}; a[i][j] is equivalent to *(&a[0][0]+2*i+j) What is **(a+3) ? What is *(a[2]+1) ?
Functions as arguments double sum_square( double f(double), int m, int n ) { int k = 0; double sum = 0. 0; for ( k = m; k <= n; ++k ) sum += f(k) * f(k); return sum; } double sum_square( double (*f)(double), int m, int n ) {. . .
Functions as arguments #include <stdio. h> #include <math. h> double f(double), sin(double), sum_square(double (*)(double), int); int main(void) { printf( “%s%. 7 fn”, “ First computation: ”, sum_square(sin, 2, 13), “Second computation: ”, sum_square(f, 1, 10000)); return 0; } double f(double x) { return 1. 0 / x; First computation: 5. 7577885 } Second computation: 1. 6448341
The qsort function (int-qsort. c) qsort's prototype in stdlib. h : void qsort(void *array , size_t n_elem , size_t elem_size , int compare(const void *, const void ; ((* compare(a, b) returns negative int if a<b returns 0 if a=b returns positive int if a>b
//qsort an array of ints #include <stdio. h < #include <stdlib. h < #include <assert. h < #define KEYSIZE 16 int compare_int(const void *p 1, const void *p 2 ; ( void print_array(char *title, int *key, int n_elem ; ( int main(void ( } int key[] = { 4, 3, 1, 67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1; { print_array("before ", key, KEYSIZE ; ( qsort(key, KEYSIZE, sizeof(int), compare_int ; ( print_array("after ", key, KEYSIZE); return 0 ; {
void print_array)char *title, int *key, int n_elem ( } int i ; printf("n %s: n", title ; ( for (i = 0; i < n_elem; ++i ( printf("%4 d", key[i ; ([ putchar('n ; (' { //the compare function to be passed as a parameter to qosrt int compare_int(const void *p 1, const void *p 2 ( } const int *q 1 = p 1, *q 2 = p 2; return ((*q 1) - (*q 2; (( {
Linked lists typedef struct list { int data; struct list *next; {ll; data next void insert( ll *p, int a ) { //assume p!=NULL struct list *q = p->next; p->next = (ll *)malloc( sizeof( ll; ( ( assert(p->next != NULL; ( p->next->data = a; p->next = q; {
Linked lists void remove( ll *p ) { //assume p, p->next != NULL ll *q = p->next; p->next = q->next; free( q ); }
LINKED #include <stdio. h< #include <stdlib. h< #include <assert. h< typedef char DATA; We will use chars in the example struct linked_list } DATA d; struct linked_list *next; ; { typedef struct linked_list ELEMENT; typedef ELEMENT *LINK;
Iterative List Creation LINK string_to_list )char s( [] } int i = 0; LINK head = NULL, tail = NULL; String is not empty if ( s[0] != ‘ ( ’ } head = ( ELEMENT* )malloc( sizeof( ELEMENT; ( ( head→d =s[0; [ tail = head;