arrays, pointers and strings

57
Arrays, Pointers and Strings Chapter 6 in ABC

Upload: bryga

Post on 15-Jan-2016

34 views

Category:

Documents


2 download

DESCRIPTION

Arrays, Pointers and Strings. Chapter 6 in ABC. One Dimensional Arrays. # defineN100 int a[N]; for ( i = 0; i< N; ++i ) sum += a[i];. space for a[0], ..., a[99] is allocated. process element a[ i ]. One Dimensional Arrays. float f[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 }; - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Arrays, Pointers and Strings

Arrays, Pointersand Strings

Chapter 6 in ABC

Page 2: Arrays, Pointers and Strings

One Dimensional Arrays

#define N 100

int a[N];

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

sum += a[i];

space for a[0], ..., a[99] is allocatedspace for a[0], ..., a[99] is allocated

process element a[ i ]process element a[ i ]

Page 3: Arrays, Pointers and Strings

One Dimensional Arrays

float f[5] = { 0.0, 1.0, 2.0, 3.0, 4.0 };

int a[100] = { 0 };

int a[] = { 2, 3, 5, -7 };

char s[] = “abc”;

char s[] = { ‘a’, ‘b’, ‘c’, ‘\0’ };

Page 4: Arrays, Pointers and Strings

Pointers

p = 0;

p = NULL;

p = &i;

p = (int *) 1776;

equivalent to p = 0equivalent to p = 0

an absolute address in memoryan absolute address in memory

Page 5: Arrays, Pointers and Strings

a b p

1 2

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

p = &a;

b = *p; is equivalent to b = a;

a b p

1 2

Pointers

Page 6: Arrays, Pointers and Strings

Pointers

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

p = &a;

b = *p; is equivalent to b = a;

This is also correct:

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

Page 7: Arrays, Pointers and Strings

Pointers

#include <stdio.h>

int main(void)

{

int i = 7, *p;

p = &i;

printf( “%s%d\n%s%u\n”, “ Value of i: ”, *p, “Location of i: ”, p );

return 0;

}

Value of i: 7

Location of i: 251657504

The result of the printingThe result of the printing

Page 8: Arrays, Pointers and Strings

Declarations and Initializations

int i = 3, j = 5, *p = &i, *q = &j, *r;

double x;

Expression Equivalent Expression Value

p == &i p == ( &i ) 1

**&p * ( * ( &p ) ) 3

r = &x r = ( & x ) illegal

7 * *p / *q + 7 ( ( ( 7 * ( *p ) ) ) / ( *q ) ) + 7 11

*( r = &j ) *= *p ( *( r = ( &j ) ) ) *= ( *p ) 15

Page 9: Arrays, Pointers and Strings

Declarations and Initializations

DeclarationDeclaration

int *p;

float *q;

void *v;

More illegalMore illegal::

&3,

&(k + 99),

register v;

&v

Legal Assignment Illegal Assignment

p = 0; p = 1;

p = ( int* ) 1; v = 1;

p = v = q; p = q;

p = ( int* ) q;

Page 10: Arrays, Pointers and Strings

Call by Refernce#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;

} 5 3 is printed5 3 is printed

Page 11: Arrays, Pointers and Strings

Arrays and Pointers

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

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

p = a is equivalent to p = &a[0]

p = a + 1is equivalent to p = &a[1]

An array name is an address!

Pointer arithmetic ~ array indexing

Page 12: Arrays, Pointers and Strings

Arrays and Pointers

for ( p = a; p < &a[ N ]; ++p )

sum += *p;

is equivalent to:

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

sum += *( a + i );

is equivalent to:

p = a;

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

sum += p[ i ];

Page 13: Arrays, Pointers and Strings

Arrays and Pointers

Illegal expressions

a = p

++a

a += 2

&a

a = p

++a

a += 2

&a

Page 14: Arrays, Pointers and Strings

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 the arraypoints to the base the array

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

1 is printed1 is printed

8 is printed8 is printed

Page 15: Arrays, Pointers and Strings

Arrays as Function Arguments

double sum(double a[], int n)

{

int i = 0;

double sum = 0.0;

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

sum += a[i];

return sum;

}

n is the size of a[]n is the size of a[]

Page 16: Arrays, Pointers and Strings

An Example: Bubble Sort

void bubble( int a[], int n )

{

int i = 0, j = 0;

void swap( int *, int * );

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

for ( j = n - 1; j > i; --j )

if ( a[ j-1] > a[ j ] )

swap( &a[ j-1], &a[ j ] );

}

n is the size of a[]n is the size of a[]

Page 17: Arrays, Pointers and Strings

Another Examplevoid merge(int a[], int b[], int c[], int m, int n){

int i = 0, j = 0, k = 0;while ( i < m && j < n ){

if ( a[i] < b[j] )c[k++] = a[i++];

elsec[k++] = b[j++];

} while ( i < m )

c[k++] = a[i++];while (j < n) c[k++] = b[j++];

}

Merge a[] of size m and b[] of size n into

c[].

Merge a[] of size m and b[] of size n into

c[].

pickup any remainderpickup any remainder

Page 18: Arrays, Pointers and Strings

Mergesort#include <stdio.h>

#include <stdlib.h>

void merge(int *, int *, int *, int, int);

void mergesort(int key[], int n)

{

int j = 0, k = 0, m = 0, *w = NULL;

for ( m = 1; m < n; m *= 2 ) ;

if ( m != n )

{

printf( “ERROR: Size of the array is not a power of 2 - bye!\n” );

exit( 1 );

}

Use merge() to sort an array of size nUse merge() to sort an array of size n

no additional statements for this loop

no additional statements for this loop

Page 19: Arrays, Pointers and Strings

Mergesort

w = calloc( n, sizeof( int ) );

for ( k = 1; k < n; k *= 2 )

{

for ( j = 0; j < n - k; j += 2 * k )

merge( key + j, key + j + k, w + j, k, k );

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

key[j] = w[j];

}

free(w);

w = NULL;

}

allocate workspaceallocate workspace

merge into wmerge into w

write w back into keywrite w back into key

free the workspacefree the workspace

Page 20: Arrays, Pointers and Strings

Mergesort#include <stdio.h>

#define KEYSIZE 16

void mergesort(int *, int);

int main(void)

{

int i, key[] = { 4, 3, 1, 67, 55, 8, 0, 4, -5, 37, 7, 4, 2, 9, 1, -1 };

mergesort(key, KEYSIZE);

printf( “After mergesort:\n” );

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

printf( “%4d”, key[i] );

putchar( ‘\n’ );

return 0;

}

Page 21: Arrays, Pointers and Strings

Strings

char *p = “abcde”

printf( “%s %s\n”, p, p +1 );

char s[] = “abcde”

is equivalent to:

char s[] = {‘a’, ‘b’, ‘c’, ‘d’, ‘e’, ‘\0’};

abcde bcde is printedabcde bcde is printed

Page 22: Arrays, Pointers and Strings

Strings

char *p = “abcde” vs. char s[] = “abcde”

sp

a b c d e \0

a b c d e \0

Page 23: Arrays, Pointers and Strings

Strings

“abc”[1] and *(“abc” + 2) make sense

char *s = NULL;

int nfrogs = 0;

. . . .

s = (nfrogs == 1)? “” : “s”;

printf( “we found %d frog%s in the pond!\n”, nfrogs, s );

NULL StringsNULL Strings

Page 24: Arrays, Pointers and Strings

Count the number ofwords in a string

#include <ctype.h>

int word_cnt(char *s)

{

int cnt = 0;

while (*s != '\0')

{

while (isspace(*s))

++s;

if (*s != '\0')

{

++cnt;

while (!isspace(*s) && *s != '\0')

++s;

}

}

return cnt;

}

skip white spacesskip white spaces

found a wordfound a word

skip the wordskip the word

Page 25: Arrays, Pointers and Strings

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

String Handling Functions in the Standard Library

Page 26: Arrays, Pointers and Strings

String Handling Functions in the Standard Library

unsigned strlen( const char *s )

{

register int n = 0;

for ( n = 0; *s != '\0'; ++s )

++n;

return n;

}

Page 27: Arrays, Pointers and Strings

String Handling Functions in the Standard Library

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

{

register char *p = s1;

while ( *p )

++p;

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

return s1;

}

no more statements in this loopno more statements in this loop

Page 28: Arrays, Pointers and Strings

Multidimensional Arrays

int sum( int a[][5] )

{

int i = 0, j = 0, sum = 0;

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

for ( j = 0; j < 5; ++j )

sum += a[i][j];

return sum;

}

Page 29: Arrays, Pointers and Strings

Multidimensional Arrays

int sum( int a[][9][2] )

{

int i = 0, j = 0, k = 0, sum = 0;

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

for ( j = 0; j < 9; ++j )

for ( k = 0; k < 2; ++k )

sum += a[i][j][k];

return sum;

}

Page 30: Arrays, Pointers and Strings

Sort Words Lexicographically

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#define MAXWORD 50 /* max word size */

#define N 1000 /* array size */

void sort_words(char *[], int);

void swap(char **, char **);

Page 31: Arrays, Pointers and Strings

Sort Words Lexicographicallyint 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));

strcpy(w[i], word);

}

an array of pointersan array of pointers

work spacework space

number of wrods to be storednumber of wrods to be stored

Page 32: Arrays, Pointers and Strings

Sort Words Lexicographically

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

Page 33: Arrays, Pointers and Strings

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;

}

Sort Words Lexicographically

n elements to be sortedn elements to be sorted

Page 34: Arrays, Pointers and Strings

Arguments to main()

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

}

Page 35: Arrays, Pointers and Strings

Ragged Arrays

#include <stdio.h>

int main(void)

{

char a[2][15]= { “abc:”, “a is for apple” };

char *p[2] = { “abc:”, “a is for apple”};

printf( “%c%c%c %s %s\n%c%c%c %s %s\n”,

a[0][0], a[0][1], a[0][2], a[0], a[1], p[0][0], p[0][1], p[0][2], p[0], p[1] );

return 0;

}

abc abc: a is for apple

abc abc: a is for apple

Page 36: Arrays, Pointers and Strings

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 )

{

.....

Page 37: Arrays, Pointers and Strings

Functions as Arguments#include <stdio.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

Page 38: Arrays, Pointers and Strings

Find a root of f() by the bisection method

#define EPS 1e-12

double root(double f(double), double a, double b)

{

double m = (a + b) / 2.0;

if (f(m) == 0.0 || b - a < EPS)

return m;

else if (f(a) * f(m) < 0.0)

return root(f, a, m);

else return root(f, m, b);

}

epsilonepsilon

midpointmidpoint

Page 39: Arrays, Pointers and Strings

Find a root of f() by the bisection method

#include <stdio.h>

double p(double);

double root(double (*)(double), double, double);

int main(void)

{

double x = root( p, 0.0, 3.0 );

printf( “%s%.16f\n%s%.16f\n”, “Approximate root: ”, x,

“ Function value: ”, p( x ) );

return 0;

}

Page 40: Arrays, Pointers and Strings

Find a root of f() by the bisection method

double p(double x)

{

return (x * x * x * x * x - 7.0 * x - 3.0);

}

Approximate root: 1.7196280914844584

Function value: 0.0000000000000317

Page 41: Arrays, Pointers and Strings

Constconst ----- - type qualifier; comes after storage class

static const int k=3;

const int a = 7; int *p = &a; /* compiler warning */

const int a = 7; const int *p = &a; /* ok */

int a=7; int * const p = &a; /* the pointer is a constant */

int a=7; const int * const p = &a; /* both pointer and pointed int are constants. */

Page 42: Arrays, Pointers and Strings

qsort: a generic sorting procedure

qsort's prototype in stdlib.h (using size_t from stddef.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

Page 43: Arrays, Pointers and Strings

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

}

Page 44: Arrays, Pointers and Strings

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

Page 45: Arrays, Pointers and Strings

Handling nXn matrices

---------------------

// allocating the matrix

int i,j,n;

double **a;

a = calloc(n,sizeof(double *));

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

a[i] = calloc(n,sizeof(double));

...

// filling in the matrix with numbers in the range [-N,N]:

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

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

a[i][j] = rand() % (2 * N + 1) - N;

Page 46: Arrays, Pointers and Strings

...

// computing the trace

double trace(double **a, int n)

{

int i;

double sum = 0.0;

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

sum += a[i][i]; /* sum the elements on the main diagonal */

return sum;

}

Page 47: Arrays, Pointers and Strings

The trace program (Chapter 12.6)

--------------------------------

•The space for the elements of the matrix is allocated all at once.

•* Pointers are offset so that the indexing starts at 1, not 0.

-------------------------------------------------

// trace.h #include <assert.h>

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <time.h>

typedef double dbl; // could be substituted with other types

Page 48: Arrays, Pointers and Strings

The trace program (Chapter 12.6)

--------------------------------

•The space for the elements of the matrix is allocated all at once.

•Pointers are offset so that the indexing starts at 1, not 0.

---------------------פרוטוטייפס--------------------

void check_cmd_line(int argc, char **argv);

void fill_matrix(dbl **a, int m, int n);

dbl ** get_matrix_space(int m, int n);

void release_matrix_space(dbl **a);

dbl trace(dbl **a, int m, int n);

void wrt_info(const char *pgm_name);

void wrt_matrix(const char *s, dbl **a, int m, int n);

Page 49: Arrays, Pointers and Strings

// main.c #include "trace.h" int main(int argc, char **argv) {

int m; /* number of rows */ int n; /* number of columns */ int val; dbl **a; /* matrix */

srand(time(NULL)); /* seed the random number generator */

check_cmd_line(argc, argv); printf("%s\n", "---\n" "This program creates space for an mxn

matrix A, fills it with\n" "randomly distributed digits from -9 to +9, and then prints\n" "the matrix A and its trace.\n");

for ( ; ; ) { printf("Input m and n: "); val = scanf("%d%d", &m, &n); if (val != 2 || m < 1 || n < 1) break; putchar('\n'); a = get_matrix_space(m, n); fill_matrix(a, m, n); …

}

Page 50: Arrays, Pointers and Strings

// main.c …

srand(time(NULL)); /* seed the random number generator */ check_cmd_line(argc, argv);

printf("%s\n", "---\n" "This program creates space for an mxn matrix A, fills it with\n" "randomly distributed digits from -9 to +9, and then prints\n" "the matrix A and its trace.\n");

for ( ; ; ) { printf("Input m and n: "); val = scanf("%d%d", &m, &n); if (val != 2 || m < 1 || n < 1) break; putchar('\n'); a = get_matrix_space(m, n); fill_matrix(a, m, n); wrt_matrix("A", a, m, n); printf("trace(A) = %.1f\n\n", trace(a, m, n));

release_matrix_space(a); }

printf("\nBye!\n\n"); return 0;

}

Page 51: Arrays, Pointers and Strings

// check-cmd-line.c

#include "trace.h"

void check_cmd_line(int argc, char **argv) {

if (argc > 1 && strcmp(argv[1], "-h") == 0) { wrt_info(argv[0]); exit(1);

} if (argc > 1) {

printf("\nERROR: No command line arguments needed.\n\n"); wrt_info(argv[0]); exit(1); }

}

Page 52: Arrays, Pointers and Strings

// allocate-free.c #include "trace.h"

dbl **get_matrix_space(int m, int n) { int i; dbl *p; dbl **a; p = malloc(m * n * sizeof(dbl)); /* get the space all at once */ a = malloc(m * sizeof(dbl *)); assert(p != NULL); assert(a != NULL); /* // Offset pointers to change the indexing.*/ --a; /* index from 1, not 0 */

for (i = 1; i <= m; ++i) a[i] = p + ((i - 1) * n) - 1; /* index from 1, not 0 */ return a;}

Page 53: Arrays, Pointers and Strings

// allocate-free.c #include "trace.h"

void release_matrix_space(dbl **a) { dbl *p;

/* // The effects of offsetting the pointers // must be undone before releasing space. */

p = a[1] + 1; /* base address in memory */ free(p); free(a + 1); }

Page 54: Arrays, Pointers and Strings

// write.c #include "trace.h"

void wrt_matrix(const char *s, dbl **a, int m, int n) { int i, j; printf("%s =\n", s); for (i = 1; i <= m; ++i) {

for (j = 1; j <= n; ++j) printf("%6.1f", a[i][j]);

putchar('\n'); }

putchar('\n'); }

Page 55: Arrays, Pointers and Strings

// fill-matrix.c #include "trace.h"

void fill_matrix(dbl **a, int m, int n) { int i, j; for (i = 1; i <= m; ++i)

for (j = 1; j <= n; ++j) a[i][j] = rand() % 19 - 9; /* from -9 to +9 */

}

Page 56: Arrays, Pointers and Strings

// compute-trace .c #include "trace.h"

dbl trace(dbl **a, int m, int n) { int i; int k; dbl sum = 0.0;

k = (m < n) ? m : n; for (i = 1; i <= k; ++i)

sum += a[i][i]; return sum; }

Page 57: Arrays, Pointers and Strings