pointers chapters 6+9 in abc. abp 12 int a = 1, b = 2, *p; & - reference operator (address) * -...

26
Pointers Chapters 6+9 in ABC

Post on 20-Dec-2015

215 views

Category:

Documents


0 download

TRANSCRIPT

Pointers

Chapters 6+9 in ABC

a b p

1 2

int a = 1, b = 2, *p;

& - reference operator (address)

* - dereference operator (value)

p = &a; // *p is now 1

a b p

1 2

Pointers

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 %d\n”, i, j );

return 0;

}

Define pointers as paramsDefine pointers as params

Use dereferenced valuesUse dereferenced values

Pass addresses as argumentsPass addresses as arguments

Arrays and Pointers

a[i] is equivalent to *(a + i)

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];

An array name is an address!

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;

p = a;

q = p +1;

printf(“%d\n”, q - p);

printf(“%d\n”, (int)q - (int)p);

points to the base of the arraypoints to the base of the array

equivalent to q = &a[ 1 ]equivalent to q = &a[ 1 ]

1 is printed1 is printed

sizeof(dobule)==8 is printedsizeof(dobule)==8 is printed

Passing an array to a function

double sum(double a[], int n)

{

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?

Base address is passed call by value.Base address is passed call by value.

Strings

char s[] = “abcde” sa b c d e \0

#include <string.h>

char *strcat(char *s1, const char *s2);

int strcmp(const char *s1, const char *s2);

char *strcpy(char *s1, const char *s2);

unsigned strlen(const char *s);

An implementation example

char *strcat( char *s1, const char *s2 )

{

register char *p = s1;

while ( *p )

++p;

while ( *p++ = *s2++ ) ;

return s1;

}

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)

{

char *w[N];

char word[MAXWORD];

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);

strcpy(w[i], word);

}

an array of pointersan array of pointers

work spacework space

Check allocationCheck allocation

Lexicographical sort

n = i;

sort_words( w, n );

for ( i = 0; i < n; ++i )

printf( “%s\n”, w[i] );

return 0;

}

print the sorted wordsprint the sorted words

void sort_words( char *w[], int n )

{

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;

}

Lexicographical sort

n elements to be sortedn elements to be sorted

Arguments to main() (echo.c)

#include <stdio.h>

void main(int argc, char *argv[])

{

int i = 0;

printf( “argc = %d\n”, argc );

for ( i = 0; i < argc; ++i )

printf( “argv[%d] = %s\n”, 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 argumentsdouble 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);

int main(void)

{

printf( “%s%.7f\n%s%.7f\n”,

“ 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 *p1, const void *p2);

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("%4d", key[i]); putchar('\n');

}

// the compare function to be passed as a parameter to qosrt

int compare_int(const void *p1, const void *p2) {

const int *q1 = p1, *q2 = p2;

return ((*q1) - (*q2)); }

Linked lists typedef struct list { int data; struct list * next;} ll;

void insert( ll *p, int a ) { //assume p!=NULLstruct list *q = p->next;p->next = (ll *)malloc( sizeof( ll ) );assert(p->next != NULL);p->next->data = a;p->next->next = q;

}

data next

Linked lists

void remove( ll *p ) { //assume p,p->next != NULLll *q = p->next;p->next = q->next;free( q );

}

LINKED#include <stdio.h>

#include <stdlib.h>

#include <assert.h>

typedef char DATA;

struct linked_list

{

DATA d;

struct linked_list *next;

};

typedef struct linked_list ELEMENT;

typedef ELEMENT *LINK;

We will use chars in the exampleWe will use chars in the example

Iterative List Creation

LINK string_to_list( char s[] )

{

int i = 0;

LINK head = NULL, tail = NULL;

if ( s[0] != ‘\0’ )

{

head = ( ELEMENT* )malloc( sizeof( ELEMENT ) );

head→d = s[0];

tail = head;

String is not emptyString is not empty

for ( i=1; s[i] != ‘\0’; ++i )

{

tail→next = ( ELEMENT* )malloc( sizeof( ELEMENT ) );

tail = tail→next;

tail→d = s[i];

}

tail→next = NULL;

}

return head;

}

insert elements at the end of the listinsert elements at the end of the list

mark the end of the listmark the end of the list

List deletion (recursive)

void delete_list (LINK head)

{

if( head!= NULL ) {

delete_list( head->next );

free( head );

}

}

Free only after using the pointer

Free only after using the pointer