1 Chapter 6 Arrays, Pointers, and Strings 2008-11-25

Preview:

Citation preview

11

Chapter 6 Chapter 6

Arrays, Pointers, and StringsArrays, Pointers, and Strings

2008-11-25

22

6.1 One-dimensional Arrays6.1 One-dimensional Arrays 6.2 Pointers6.2 Pointers 6.3 Call-by-Reference6.3 Call-by-Reference 6.4 The Relationship Between Arrays and Pointers6.4 The Relationship Between Arrays and Pointers 6.5 Pointer Arithmetic and Element Size6.5 Pointer Arithmetic and Element Size 6.6 Array as Function Arguments6.6 Array as Function Arguments 6.7 An Example: Bubble Sort6.7 An Example: Bubble Sort 6.8 Dynamic Memory Allocation With calloc() and malloc()6.8 Dynamic Memory Allocation With calloc() and malloc() 6.9 An Example: Merge and Merge Sort6.9 An Example: Merge and Merge Sort 6.10 Strings6.10 Strings 6.11 String-Handling Function in the Standard Library6.11 String-Handling Function in the Standard Library 6.12 Multidimensional Arrays6.12 Multidimensional Arrays 6.13 Arrays of Pointers6.13 Arrays of Pointers 6.14 Arguments to main()6.14 Arguments to main() 6.15 Ragged Arrays6.15 Ragged Arrays 6.16 Functions as Arguments6.16 Functions as Arguments 6.17 An Example: Using Bisection to Find the Root of a Function6.17 An Example: Using Bisection to Find the Root of a Function 6.18 Arrays of Pointers to Function6.18 Arrays of Pointers to Function 6.19 The Type Qualifiers const and volatile6.19 The Type Qualifiers const and volatile

33

6.1 One-dimensional Arrays6.1 One-dimensional Arrays

int grade0, grade1, grade2;int grade0, grade1, grade2;

int grade[3];int grade[3];

Memory

Memory

OR

44

TestTest #include <stdio.h>#include <stdio.h>

int main(void)int main(void) {{ int a=10;int a=10; int b=20;int b=20; int c=30;int c=30; int d=40; int d=40; printf(“a=%d,b=%d,d=%d,d=%d”, printf(“a=%d,b=%d,d=%d,d=%d”, a,b,c,da,b,c,d);); printf("a=%p,b=%p,c=%p,d=%p\n", printf("a=%p,b=%p,c=%p,d=%p\n", &a,&b,&c,&d&a,&b,&c,&d); ); return 1;return 1; }}

Output: a=10,b=20,c=30,d=40 a=0023FF74,b=0023FF70,c=0023FF6C,d=0023FF68

Pointer address

55

int a[size]; int a[size]; /*space for a[0],…, a[size-1] allocated/*space for a[0],…, a[size-1] allocated

• low bound = 0low bound = 0• upp bound = size - 1upp bound = size - 1• size = upper bound + 1; */size = upper bound + 1; */

00 11 22 33 44 55 66 77

low bound=0low bound=0 upper bound=7upper bound=7

int a[8]; //size=8int a[8]; //size=8

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7]

One-dimensional ArraysOne-dimensional Arrays

66

#define N 100#define N 100 int a[N];int a[N]; /* space for a[0],…,a[99] is allocated */ /* space for a[0],…,a[99] is allocated */

General version

void main(){ for (int a=0;a<100;a++) {……….}

for (int a=0;a<100;a++) {……….}

for (int a=0;a<100;a++) {……….}}

Good version

void main(){ for (int a=0;a<N;a++) {……….}

for (int a=0;a<N;a++) {……….}

for (int a=0;a<N;a++) {……….}}

77

Array InitializationArray Initialization

float f[5] = {0,1,2,3,4};float f[5] = {0,1,2,3,4};

int a[100] = {0};int a[100] = {0};

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

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

char s[]=“abc”;char s[]=“abc”;

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

88

Exercise 1Exercise 1

Trace the codes and Find out the problem in the Trace the codes and Find out the problem in the for-loopfor-loop

int a[10];int a[10]; int sum=0;int sum=0; for (int i=0;i<=10;i++)for (int i=0;i<=10;i++) { { sum += a[i];sum += a[i]; }}

99

Overrunning the boundsOverrunning the bounds Overrunning the bounds of an array is a Overrunning the bounds of an array is a common common

programming errorprogramming error..

The effect of the error is The effect of the error is system-dependentsystem-dependent, and , and can be quite confusing.can be quite confusing.

One frequent result is that the value of some One frequent result is that the value of some unrelated variableunrelated variable will be returned or modified. will be returned or modified.

It is the It is the programmer’s jobprogrammer’s job to ensure that all to ensure that all subscripts to arrays stay within bounds.subscripts to arrays stay within bounds.

1010

Array elements for two-dimensional Arrays Array elements for two-dimensional Arrays

Col 1Col 1 Col 2Col 2 Col 3Col 3 Col 4Col 4 Col 5Col 5

Row 1Row 1 a[0][0]a[0][0] a[0][1]a[0][1] a[0][2]a[0][2] a[0][3]a[0][3] a[0][4]a[0][4]

Row 2Row 2 a[1][0]a[1][0] a[1][1]a[1][1] a[1][2]a[1][2] a[1][3]a[1][3] a[1][4]a[1][4]

Row 2Row 2 a[2][0]a[2][0] a[2][1]a[2][1] a[2][2]a[2][2] a[2][3]a[2][3] a[2][4]a[2][4]

int array_name[num_row][num_column];

1111

Two dimensional array initializationTwo dimensional array initialization

int my_array[2][5]=int my_array[2][5]= { { 1,2,3,4,5,1,2,3,4,5, 6,7,8,9,106,7,8,9,10 };}; printf("%d",my_array[1][3]); printf("%d",my_array[1][3]);

int now_value = 0;int now_value = 0; for (int y=0;y<2;y++)for (int y=0;y<2;y++) {{ for (int x=0;x<5;x++for (int x=0;x<5;x++ my_array[y][x] = 1; my_array[y][x] = 1; now_value += 1;now_value += 1; }} printf(“%d”,now_value);printf(“%d”,now_value);

int my_array[2][5]=int my_array[2][5]= { { {1,2,3,4,5},{1,2,3,4,5}, {6,7,8,9,10}{6,7,8,9,10} };}; printf("%d",my_array[1][3]); printf("%d",my_array[1][3]);

1212

Exercise 2Exercise 2 Print out the sum of Print out the sum of each roweach row of two dimensional array of two dimensional array

respectively by using respectively by using for-loopfor-loop instruction. instruction.

#define num_row 4#define num_row 4 #define num_col 6#define num_col 6 int my_array[num_row][num_col];int my_array[num_row][num_col]; // ………initial the value of my_array// ………initial the value of my_array int row_sum=0;int row_sum=0; for (int a=0 ; a<num_row ; a++)for (int a=0 ; a<num_row ; a++) {{ for (int b=0 ; b<num_col ; b++)for (int b=0 ; b<num_col ; b++) {{ row_sum += my_array[a][b];row_sum += my_array[a][b]; }} printf(“The sum of %d row is %d”,row_sum);printf(“The sum of %d row is %d”,row_sum); row_sum = 0;row_sum = 0; }}

1313

【實例探討】某學生之功課表如下,【實例探討】某學生之功課表如下, (( 每個課程名稱皆以代碼表示每個課程名稱皆以代碼表示 )) ,使,使用者輸入星期幾及第幾節課,輸出課程名稱。用者輸入星期幾及第幾節課,輸出課程名稱。

  一 二 三 四 五1   2   2  

2 1 4 1 4 1

3 5   5   5

4          

5 3   3   3

6           

課程名稱 代碼計算機概論 1

離散數學 2

資料結構 3

資料庫概論 4

上機實習 5

1414

void main()void main() {{ int course[6][5] = { 0, 2, 0, 2, 0, /* int course[6][5] = { 0, 2, 0, 2, 0, /* 課程定義 課程定義 */*/ 1, 4, 1, 4, 1,1, 4, 1, 4, 1, 5, 0, 5, 0, 5,5, 0, 5, 0, 5, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 3, 0, 3, 0, 3,3, 0, 3, 0, 3, 0, 0, 0, 0, 0 }; 0, 0, 0, 0, 0 }; int week; /* int week; /* 星期資料變數 星期資料變數 */ */ int class; /* int class; /* 第幾節課的變數 第幾節課的變數 */ */ int class_no; /* int class_no; /* 課程代碼變數 課程代碼變數 */  */ 

printf("printf(" 請輸入星期請輸入星期 (1 (1 到 到 5). ==> "); 5). ==> "); scanf("%d",&week); /* scanf("%d",&week); /* 讀取星期資料 讀取星期資料 */ */ printf("printf(" 請輸入第幾節課請輸入第幾節課 (1 (1 到 到 6). ==> ");6). ==> "); scanf("%d",&class); /* scanf("%d",&class); /* 讀取第幾節課 讀取第幾節課 */ */

class_no = course[class-1][week-1]; /* class_no = course[class-1][week-1]; /* 課程查詢 課程查詢 */ */

1515

switch ( class_no ) /* switch ( class_no ) /* 印出課程名稱 印出課程名稱 */ { */ { case 0: case 0: printf("printf(" 這節沒課這節沒課 \n"); \n"); break; break; case 1: case 1: printf("printf(" 計算機概論計算機概論 \n"); \n"); break; break; case 2: case 2: printf("printf(" 離散數學離散數學 \n"); \n"); break; break; case 3: case 3: printf("printf(" 資料結構資料結構 \n"); \n"); break; break; case 4: case 4: printf("printf(" 資料庫概論資料庫概論 \n"); \n"); break; break; case 5: case 5: printf("printf(" 上機實習上機實習 \n"); \n"); break; break; }} } }

1616

6.2 Pointers6.2 Pointers Pointers Pointers are used in programs to access memory and are used in programs to access memory and

manipulate addresses.manipulate addresses.

If v is a variable, then If v is a variable, then &v&v is the location, or address, in memory is the location, or address, in memory of its stored value.of its stored value.

Pointer variables can be declared in programs and then used to Pointer variables can be declared in programs and then used to take addresses as valuestake addresses as values..

The declaration The declaration int *p;int *p; declares p to be of type pointer to declares p to be of type pointer to int.int.

Its legal range of values always includes the special address 0 Its legal range of values always includes the special address 0 and a set of positive integers that are interpreted as and a set of positive integers that are interpreted as machine machine addressesaddresses on the given C system. on the given C system.

1717

ExampleExample

int a=100; /* 在記憶體中,要一塊空間來儲存數值,至於實際的位址, 使用者不知道。 */

100int

int *p; /* 在記憶體中,要一塊空間來儲存別人的”位址”。 */

位址 ?int

p = &a; /* 將 a 的位址儲存在 p 中 */

a 的位址int

a

p

p

1818

*p = 200; /* 將 200 儲存到 p 所指的位址裡。 */

100->200int

a 的位址int

ap

printf(“%d”,a); 200

printf(“%d”,*p); 200

printf(“%p”,p); 0023FF74

printf(“%p”,&a); 0023FF74 4,294,967,296 = 4G bytes

1919

Pointer AssignmentPointer Assignment

int a;int a; int *p;int *p;

• p = 0;p = 0;• p = NULL; p = NULL; /*equivalent to p=0 */ /*equivalent to p=0 */

• p = &a;p = &a;• p = (int *) 1776; p = (int *) 1776; /*an absolute address in memory *//*an absolute address in memory */

int *p (p is a pointer to int)int *p (p is a pointer to int)

2020

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

1 2aa bb pp

??

p = &a;p = &a;

1 2aa bb pp

*p = 1

2121

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

3i

5j *p *q *r

?

x

2222

Warning 1Warning 1

int a=10;int a=10;

int *p = &a;int *p = &a;

*p = &a;*p = &a;DifferentDifferent

printf("%d",*p);

illegal: &3, &(k+99), register v; &v;

Warning 2Warning 2

2323

Exercise 3Exercise 3

#include <stdio.h>#include <stdio.h>

void main()void main() {{ int a;int a; int *b;int *b; b = &a;b = &a; *b = 100;*b = 100; printf("\na=%d",a);printf("\na=%d",a); }}

Output: a=100

2424

ExampleExample

2525

example: locate.cexample: locate.c /* printing an address, or location. *//* printing an address, or location. */

#include <stdio.h>#include <stdio.h> int main(void)int main(void) {{ int i=7, *p=&i;int i=7, *p=&i; printf(“%s%d\n%s%p”,”Value of i: “,*p,”Location of i: “,p);printf(“%s%d\n%s%p”,”Value of i: “,*p,”Location of i: “,p); return 0;return 0; }}

Value of i: 7Value of i: 7 Location of i: effffb24 Location of i: effffb24 (!depend on compiler)(!depend on compiler)

2626

6.3 Call-by-Reference6.3 Call-by-Reference

Whenever variables are passed as arguments to a Whenever variables are passed as arguments to a function, their values are copied to the corresponding function, their values are copied to the corresponding function parameters, and the variables themselves function parameters, and the variables themselves are are not changednot changed in the calling environment. in the calling environment.

To change the values of variables in the calling To change the values of variables in the calling environment, other languages provide the environment, other languages provide the “call-by-“call-by-reference”reference” mechanism. mechanism.

2727

Example for call-by-value and call-by-referenceExample for call-by-value and call-by-reference

a 的位址int

c100

inta

void fun_1(int *c){ *c = 300;}

void main( ){ int a = 100; func_1(&a); printf(“a=%d”,a);}

300int

c100int

a

void fun_1(int c){ c = 300;}

void main( ){ int a = 100; func_1(a); printf(“a=%d”,a);}

Output: a=100 Output: a=300

2828

ExampleExample

void swap(int *p, int *q)void swap(int *p, int *q) {{ int tmp;int tmp; tmp = *p;tmp = *p; *p = *q;*p = *q; *q = tmp;*q = tmp; }}

#include <stdio.h>#include <stdio.h> void swap(int *, int *);void swap(int *, int *);

int main (void)int main (void) {{ int i=4,j=5;int i=4,j=5; swap(&i,&j);swap(&i,&j); printf(“i=%d,j=%d”,i,j);printf(“i=%d,j=%d”,i,j); return 0;return 0; }}

3i

5j

*p *q

tmp

Output: i=5,j=4

2929

The effect of “call-by-reference” is The effect of “call-by-reference” is accomplished byaccomplished by

1. Declaring a 1. Declaring a function parameterfunction parameter to be a pointer. to be a pointer.

2. Using the 2. Using the dereferenced pointerdereferenced pointer in the function in the function body.body.

3. 3. Passing an addressPassing an address as an argument when the as an argument when the function is calledfunction is called

3030

6.4 The Relationship Between Arrays and Pointers6.4 The Relationship Between Arrays and Pointers

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

a[0] a[1] a[2] a[3] a[4] a[5]

&a[0]&a[0] &a[1]&a[1] &a[2]&a[2] &a[3]&a[3] &a[4]&a[4] &a[5]&a[5]

p=&a[0]p=&a[0] a 的位址int

p

// p=a; is equivalent to p =&a[0];// p=a; is equivalent to p =&a[0];// p=a+1; is equivalent to p =&a[1];// p=a+1; is equivalent to p =&a[1];

3131

Different between arrays and pointersDifferent between arrays and pointers

An array name by itself is an address, or pointer An array name by itself is an address, or pointer value, and pointers, as well as arrays, can be value, and pointers, as well as arrays, can be subscripted. Although pointers and arrays are subscripted. Although pointers and arrays are almost synonymous in terms of how they are used almost synonymous in terms of how they are used to access memory, there are differences.to access memory, there are differences.

A A pointer variablepointer variable can take can take different addressesdifferent addresses as as values. values.

In contrast, an In contrast, an array namearray name is an address, or is an address, or pointer, that is pointer, that is fixedfixed..

3232

Exercise 4Exercise 4

int main(void)int main(void) {{ int a[10];int a[10]; int *p = a;int *p = a; int i;int i; a[0] = 3;a[0] = 3; for (i=1;i<10;i++)for (i=1;i<10;i++) a[i] = a[i-1] * 2;a[i] = a[i-1] * 2;

printf("%d\n",*p); //3printf("%d\n",*p); //3 printf(“%d\n”,*p+1); //4 printf(“%d\n”,*p+1); //4 printf("%p\n",a); //0023FF40printf("%p\n",a); //0023FF40 printf(“%p,%p\n”,a,(a+1)); //0023FF40,0023FF44printf(“%p,%p\n”,a,(a+1)); //0023FF40,0023FF44 }}

3333

Three ways to calculate the sumThree ways to calculate the sum

#define N 6#define N 6 int a[N], iint a[N], i,*p,*p, sum=0;, sum=0;

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

for (i = 0;i < N; ++i)for (i = 0;i < N; ++i) sum += *(a+i);sum += *(a+i);

p=a;p=a; for (i = 0; i < N; ++i)for (i = 0; i < N; ++i) sum += p[i];sum += p[i];

3434

6.5 Pointer Arithmetic and Element Size6.5 Pointer Arithmetic and Element Size

Pointer arithmetic is one of the powerful features of C. If Pointer arithmetic is one of the powerful features of C. If the variable p is a pointer to a particular type, then the the variable p is a pointer to a particular type, then the expression p+1 yields the correct machine address for expression p+1 yields the correct machine address for storing or accessing the next variable of that type. storing or accessing the next variable of that type.

10

*p*p *(p+1)*(p+1)

20 40 80

*(p+2)*(p+2) *(p+3)*(p+3)

3535

ContinueContinue Pointer expressions such as Pointer expressions such as p+ip+i and and ++p++p and and p+=1p+=1 all all

make sense. If p and q are both pointering to elements of make sense. If p and q are both pointering to elements of an array, then an array, then p-qp-q yields the int value representing the yields the int value representing the number of array elements between p and q.number of array elements between p and q.

double a[2], *p, *q;double a[2], *p, *q; p = a; //points to base of arrayp = a; //points to base of array q = p + 1; //equivalent to q=&a[1]q = p + 1; //equivalent to q=&a[1] printf(“%d\n”,q-p); //1 is printedprintf(“%d\n”,q-p); //1 is printed printf(“%d\n”,(int)q – (int)p); //8 is printedprintf(“%d\n”,(int)q – (int)p); //8 is printed

On most machines, a double is stored in 8 bytes. Because p On most machines, a double is stored in 8 bytes. Because p points to a double and q points to the next double, the points to a double and q points to the next double, the difference in terms of array elements is 1, but the difference in terms of array elements is 1, but the difference is memory location is 8.difference is memory location is 8.

3636

6.6 Array as Function Arguments6.6 Array as Function Arguments

In a function definition, a formal parameter that is In a function definition, a formal parameter that is declared as an array is actually a pointer. declared as an array is actually a pointer.

Corresponding to this, when an array is passed as Corresponding to this, when an array is passed as an argument to a function, the an argument to a function, the base addressbase address of of the array is passed the array is passed “call-by-value.”“call-by-value.”

The The array elementsarray elements themselves themselves are not copiedare not copied. .

3737

ConceptConcept

void fun_sum ( void fun_sum ( double b[], int length_b double b[], int length_b )) {{ …… …… }}

int main()int main() {{ int array[10];int array[10]; …… …… fun_sum(fun_sum(arrayarray,10),10) …… …… …… …… }}

3838

ExampleExample double fun_sum(double a[], int n)double fun_sum(double a[], int n) {{ int i;int i; double sum=0;double sum=0; for (i = 0; i < n ;i++)for (i = 0; i < n ;i++) sum += a[i];sum += a[i]; return sum;return sum; }}

int main(void)int main(void) {{ double my_array[10];double my_array[10]; double s;double s; int a;int a; for(a=0;a<10;a++)for(a=0;a<10;a++) my_array[a] = a;my_array[a] = a; s = fun_sum(my_array,10);s = fun_sum(my_array,10); printf("\nsum=%.0f",s);printf("\nsum=%.0f",s); }}

3939

s = fun_sum(v,100);s = fun_sum(v,100);• v[0]+v[1]+…+v[99]v[0]+v[1]+…+v[99]

s = fun_sum(v,88);s = fun_sum(v,88);• v[0]+v[1]+…+v[87]v[0]+v[1]+…+v[87]

s = fun_sum(&v[7],k-7);s = fun_sum(&v[7],k-7);• v[7]+v[8]+…+v[k-1]v[7]+v[8]+…+v[k-1]

s = fun_sum(v+7,2*k);s = fun_sum(v+7,2*k);• v[7]+v[8]+…+v[2*k+6]v[7]+v[8]+…+v[2*k+6]

4040

6.7 An Example: Bubble Sort6.7 An Example: Bubble Sort

由第零個元素開始 , 與下一個元素比較 , 如果比下一個元素大 , 二者對調 , 直到最後一個 .

對於 n 個元素 , 此步驟需要進行 n-1 次 , 第一次 pass 完成後 , 最大的元素會落於第 n-1 個位置 , 即最大的元素已經排序好了 , 接下來 , 第 2 個 pass 完成後 , 次大的元素會排在第 n-2 個位置 . 依此方式即可將該陣列排序好 .

n = 7 20 3040 7090 80 50

0 32 51 4 6

4141

n = 7 20 3040 7090 80 50

0 32 51 4 6

n = 7 20 3040 7090 80 50

0 32 51 4 6

k = n-1 = 6

j = 0, a[0] = 20 < 90 = a[1]

n = 7 20 3090 7040 80 50

0 32 51 4 6

j = 1, a[1] = 90 > 40 = a[2]

4242

n = 7 20 3090 7040 80 50

0 32 51 4 6

j = 2, a[2] = 90 > 30 = a[3]

n = 7 20 9030 7040 80 50

0 32 51 4 6

j = 3, a[3] = 90 > 80 = a[4]

n = 7 20 8030 7040 90 50

0 32 51 4 6

4343

n = 7 20 8030 7040 90 50

0 32 51 4 6

j = 4, a[4] = 90 > 70 = a[5]

n = 7 20 8030 9040 70 50

0 32 51 4 6

j = 5, a[5] = 90 > 50 = a[6]

n = 7 20 8030 5040 70 90

0 32 51 4 6

4444

n = 7 20 8030 5040 70 90

0 32 51 4 6

pass 1:

n = 7 20 7040 8030 50 90

0 32 51 4 6

pass 2:

n = 7 20 5040 8030 70 90

0 32 51 4 6

pass 3:

n = 7 20 3040 7090 80 50

0 32 51 4 6

n = 7 20 5040 8030 70 90

0 32 51 4 6

pass 4:

4545

Another version of Bubble SortAnother version of Bubble Sort

4646

Bubble SortBubble Sort

void swap(int *, int *);void swap(int *, int *);

void bubble(int a[], int n)void bubble(int a[], int n) {{ int i,j;int i,j; for (i=0;i<n-1;++i)for (i=0;i<n-1;++i) for (j=n-1;j>i;--j)for (j=n-1;j>i;--j) {{ if (a[j-1] > a[j])if (a[j-1] > a[j]) swap(&a[j-1], &a[j]);swap(&a[j-1], &a[j]); }} }} ………….... int a[] = {7, 3, 66, 3, -5, 22, -77, 2};int a[] = {7, 3, 66, 3, -5, 22, -77, 2}; bubble(a,8);bubble(a,8); …………

4747

7 3 66 3 -5 22 -77 2

n=8

for (i=0;i<n-1;++i)for (i=0;i<n-1;++i) for (j=n-1;j>i;--j)for (j=n-1;j>i;--j) {{ if (a[j-1] > a[j])if (a[j-1] > a[j]) swap(&a[j-1], &a[j]);swap(&a[j-1], &a[j]); }}

j=n-1

Page:258

i=0

4848

Time complexity of bubble sortTime complexity of bubble sort

A bubble sort is very inefficient. If the size of the A bubble sort is very inefficient. If the size of the array is array is nn, then the number of comparisons , then the number of comparisons performed is proportional to performed is proportional to nn22. .

Recommended