Lecture 08 - 2024-1

Download as pdf or txt
Download as pdf or txt
You are on page 1of 125

1

8
C Pointers
2

課程目標
3

Introduction
Point Operators
Calling Functions by References
Pointer Expressions and Pointer Arithmetic
Pointers and Arrays
Using the const Qualifier with Pointers
Arrays of Pointers
Pointers to Functions
4

What is Pointer?
5

▪ Pointers are variables whose values are memory


addresses.
▪ Normally, a variable directly contains a specific value.
▪ A pointer, on the other hand, contains an address of a
variable that contains a specific value.
▪ In this sense, a variable name directly references a
value, and a pointer indirectly references a value
(Fig. 7.1).
▪ Referencing a value through a pointer is called
indirection.

© 1992-2010 by Pearson Education, Inc. All


Rights Reserved.
6

© 1992-2010 by Pearson Education, Inc. All


Rights Reserved.
7

CPU and Memory


8

Memory Space

▪ Program and data are stored in


some places of memory. address
00000000

▪ Addresses (Pointers) are used to 00000001


00000002
00000003

identify where the program or 00000004


00000005
00000006

data are stored. 00000007


00000008

▪ CPU accesses a piece of memory


data by emitting its address on
address bus.
FFFFFFFB
FFFFFFFC
FFFFFFFD
FFFFFFFE
FFFFFFFF
9

C Pointers
▪ Powerful, but difficult to master

▪ Simulate call-by-reference
– C only has call-by-value

▪ Close relationship with arrays and strings


– important for handling arrays and strings
10

C Program Design
C Pointers

▪Pointer Variable Definitions and


Initialization
11

Pointer Variables
Variable is a piece of memory containing a
value of a specific type (direct reference).

▪ Pointer variables contain memory addresses as


their values

▪ Indirect reference ⎯
– Typed pointers point to the address of a variable of a
specific type
– Non-typed pointers are simply addresses, i.e., they can
point to an addresses of any thing
12

Pointer Definitions

datatype *pointerName

Examples:
int *ptr1;
int *ptr2, *ptr3;
char *ptr4; Typed pointers
double *ptr5;
void *ptr6, *ptr7; Non-typed pointers
13

Pointer Definitions

datatype *pointerName
Don’t write as
Examples: int *ptr2, ptr3;

int *ptr1;
int *ptr2, *ptr3;
char *ptr4; Typed pointers
double *ptr5;
void *ptr6, *ptr7; Non-typed pointers
14

Pointer Initialization

ptr1
ptr2
ptr3
ptr4
int *ptr1; ptr5
ptr6
int *ptr2, *ptr3; ptr7
char *ptr4;
double *ptr5;
void *ptr6, *ptr7;
15

Pointer Initialization
Before pointers are actually used, it is a good
habit to initialize them to NULL, meaning that
they are pointing to nothing.

#define NULL 0
ptr1
ptr2
int *ptr1=NULL; ptr3
ptr4
int *ptr2=NULL, *ptr3=NULL;
ptr5
char *ptr4=NULL; ptr6
double *ptr5=NULL; ptr7
void *ptr6=NULL, *ptr7=NULL;
16

C Program Design
C Pointers

▪Pointer Operators
17

Point Operators
▪ Reference operator (&)
– Retrieve the address of a variable

▪ Dereference operator (*)


– Retrieve the value pointed by a pointer (address)

▪ * and & are inverses


– They cancel each other out
18

Reference Operator (*)


Nickname: address-of operator

▪ &: Returns address-of operand

int n=5;
double x=3.14; n 5
. . . . . x 3.14
int *nPtr; ..
.
double *xPtr; nPtr
xPtr
nPtr = &n;
xPtr = &x;
19

Example:

#include <stdio.h>

int n=5;
double x=3.14;

int *nPtr; 00427600


double *xPtr;
n 5
00427608
main()
x 3.14
{
/* nPtr gets address of n */ ..
nPtr = &n; .
nPtr 00427600
/* xPtr gets address of n */
xPtr = &x; xPtr 00427608

printf("Address of n is %p\n"
"Address of x is %p\n",
nPtr, xPtr);
}
20

Exercise: 1. 將上例之變數改成main之區域變數,
觀察其值,並繪製類似右側之圖。

#include <stdio.h>

int n=5;
double x=3.14;

int *nPtr; 00427600


double *xPtr;
n 5
00427608
main()
x 3.14
{
/* nPtr gets address of n */ ..
nPtr = &n; .
nPtr 00427600
/* xPtr gets address of n */
xPtr = &x; xPtr 00427608

printf("Address of n is %p\n"
"Address of x is %p\n",
nPtr, xPtr);
}
21

Dereference Operator (*)


Nickname: value-point-by operator

▪ *: Returns value point by operand

00427600
n 5
*nPtr = ? 00427608
x 3.14
..
.
*xPtr = ? nPtr
xPtr
00427600
00427608
22

Dereference Operator (*)


Nickname: value-point-by operator

▪ *: Returns value point by operand

#include <stdio.h>
00427600
int n=5; n 5
*nPtr = ?
double x=3.14;
00427608
int *nPtr;
double *xPtr; x 3.14
..
.
main()
{

*xPtr = ?
/* nPtr gets address of n */
nPtr = &n; nPtr
xPtr
00427600
00427608
/* xPtr gets address of n */
xPtr = &x;
printf("integer value in address %p is %d\n"
"double value in address %p is %lf\n",
nPtr, *nPtr, xPtr, *xPtr);
}
23

Example:
Showing that * and & are
complements of each other.

#include <stdio.h>

int main( void )


{
int a; /* a is an integer */
int *aPtr; /* aPtr is a pointer to an integer */

a = 7;
aPtr = &a; /* aPtr set to address of a */

printf( "The address of a is %p"


"\nThe value of aPtr is %p", &a, aPtr );

printf( "\n\nThe value of a is %d"


"\nThe value of *aPtr is %d", a, *aPtr );

printf( "\n\nShowing that * and & are complements of "


"each other\n&*aPtr = %p"
"\n*&aPtr = %p\n", &*aPtr, *&aPtr );
return 0; /* indicates successful termination */
} /* end main */
24

Example:
Showing that * and & are
complements of each other.

#include <stdio.h>

int main( void )


{
int a; /* a is an integer */
int *aPtr; /* aPtr is a pointer to an integer */ 0012FF7C
a 7
a = 7;
aPtr = &a; /* aPtr set to address of a */

printf( "The address of a is %p"


"\nThe value of aPtr is %p", &a, aPtr );

printf( "\n\nThe value of a is %d"


"\nThe value of *aPtr is %d", a, *aPtr ); aPtr 0012FF7C

printf( "\n\nShowing that * and & are complements of "


"each other\n&*aPtr = %p"
"\n*&aPtr = %p\n", &*aPtr, *&aPtr );
return 0; /* indicates successful termination */
} /* end main */
25

1. What is the data type of &aPtr?


HW #8
2. Modify the following program to also show
the address of aPtr.

#include <stdio.h>

int main( void )


{
int a; /* a is an integer */
int *aPtr; /* aPtr is a pointer to an integer */ 0012FF7C
a 7
a = 7;
aPtr = &a; /* aPtr set to address of a */

printf( "The address of a is %p"


"\nThe value of aPtr is %p", &a, aPtr );

printf( "\n\nThe value of a is %d"


"\nThe value of *aPtr is %d", a, *aPtr ); aPtr 0012FF7C

printf( "\n\nShowing that * and & are complements of "


"each other\n&*aPtr = %p"
"\n*&aPtr = %p\n", &*aPtr, *&aPtr );
return 0; /* indicates successful termination */
} /* end main */
26

C Program Design
C Pointers

▪Calling Functions by Reference


27

C Simple Swap Program

#include <stdio.h>

main()
{
int a = 23, b = 47;
int t;

printf("Before. a: %d, b: %d\n", a, b);

t = a;
a = b;
b = t;

printf("After. a: %d, b: %d\n", a, b);


}
28

C Simple Swap Program

#include <stdio.h>

main()
{
int a = 23, b = 47;
int t;

printf("Before. a: %d, b: %d\n", a, b);

t = a;
a = b; define a function to do swapping.
b = t;

printf("After. a: %d, b: %d\n", a, b);


}
29

C Simple Swap Program

#include <stdio.h>

main()
{
int a = 23, b = 47;
void swap(int a, int b)
{
printf("Before. a: %d, b: %d\n", a, b); int t;

t = a;
swap(a, b); a = b;
b = t;
}
printf("After. a: %d, b: %d\n", a, b);
}
30

C Simple Swap Program

#include <stdio.h>

main()
{
int a = 23, b = 47;
void swap(int a, int b)
{
printf("Before. a: %d, b: %d\n", a, b); int t;

t = a;
swap(a, b); a = b;
b = t;
}
printf("After. a: %d, b: %d\n", a, b);
}
31

Calling Function by Passing References

#include <stdio.h>

main()
{
int a = 23, b = 47;
void swap(int *a, int *b)
{
printf("Before. a: %d, b: %d\n", a, b); int t;

t = *a;
swap(&a, &b); *a = *b;
*b = t;
}
printf("After. a: %d, b: %d\n", a, b);
}
32

Calling Function by Passing References

#include <stdio.h>

main()
{
int a = 23, b = 47;
void swap(int *a, int *b)
{
printf("Before. a: %d, b: %d\n", a, b); int t;

t = *a;
swap(&a, &b); *a = *b;
*b = t;
}
printf("After. a: %d, b: %d\n", a, b);
}
33

Review: Bubble Sort

void BubbleSort(int data[], int n)


{
int tmp, i, j;

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


for(j=0; j<n-i-1; j++)
if(data[j] > data[j+1]){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
34
void swap(int *a, int *b)
Bubble Sort {
int t;

t = *a;
*a = *b;
*b = t;
}

void BubbleSort(int data[], int n)


{
int i, j;

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


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

Pointers vs. Arrays

void swap(int *a, int *b)


{
int t;
t = *a; *a = *b; *b = t;
}

void BubbleSort(int data[], int n)  BubbleSort(&vals[0], 5);


{
int i, j;
int * int *

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


for(j=0; j<n-i-1; j++)
if(data[j] > data[j+1])
swap(&data[j], &data[j+1]);
vals
} 0 100
main()
1 30
{ 2 20
int vals[5]={100, 30, 20, 75, 15};
3 75
BubbleSort(vals, 5); 4 15
/* ............................ */
} int *
36

Pointers vs. Arrays

void swap(int *a, int *b)


{
int t;
t = *a; *a = *b; *b = t;
}

void BubbleSort(int data[], int n)


*data, int n)  BubbleSort(&vals[0], 5);
{
int i, j; int *

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


for(j=0; j<n-i-1; j++)
if(data[j] > data[j+1])
swap(&data[j], &data[j+1]);
vals
} 0 100
main()
1 30
{ 2 20
int vals[5]={100, 30, 20, 75, 15};
3 75
BubbleSort(vals, 5); 4 15
/* ............................ */
} int *
37

C Program Design
C Pointers

▪Pointer Expressions and Pointer


Arithmetic
38

Pointer Arithmetic

▪ Increment/decrement pointer
– ++ or –-

▪ Add/substract an integer to a pointer


– + or += , - or -=

▪ Pointers may be subtracted from each


other
39

Pointer Arithmetic

▪ Increment/decrement pointer
– ++ or –-

▪ Add/substract an integer to a pointer


– + or += , - or -=

▪ Pointers may be subtracted from each


other
40

Pointer Arithmetic
▪ Increment/decrement pointer (++ or –-)
▪ Add/substract an integer to a pointer (+ or += , - or -
=)
▪ Pointers may be subtracted from each other

int data[10]; data data[0] 0


int i; data[1] 1
data[2] 2
for(i=0; i<10; i++) data[3] 3
data[i] = i; data[4] 4
data[5] 5
data[6] 6
int data[10];
data[7] 7
int i, *p;
data[8] 8
data[9] 9
for(i=0, p=data; i<10; i++){
*p = i;
p++;
}
41

Pointer Arithmetic ▪ Increment/decrement pointer (++ or –-)


▪ Add/substract an integer to a pointer (+ or += , - or -
=)
▪ Pointers may be subtracted from each other

int data[10]; data data[0] 0


int i; data[1] 1
data[2] 2
for(i=0; i<10; i++) data[3] 3
data[i] = i; data[4] 4
data[5] 5
data[6] 6
int data[10];
data[7] 7
int i, *p;
data[8] 8
data[9] 9
for(i=0, p=data; i<10; i++){
*p = i;
p++;
}
42

Pointer Arithmetic ▪ Increment/decrement pointer (++ or –-)


▪ Add/substract an integer to a pointer (+ or += , - or -
=)
▪ Pointers may be subtracted from each other

int data[10]; data


int i, *p; data[0] 0
data[1] 1
data[2] 2
for(i=0, p=data; i<10; i++)
data[3] 3
*p++ = i;
data[4] 4
data[5] 5
data[6] 6
int data[10];
data[7] 7
int i, *p;
data[8] 8
data[9] 9
for(i=0, p=data; i<10; i++){
*p = i;
p++;
}
43

Pointer Arithmetic
▪ Increment/decrement pointer (++ or –-)
▪ Add/substract an integer to a pointer (+ or += , - or -
=)
▪ Pointers may be subtracted from each other

int data[10]; data


int i, *p; data[0] 0
data[1] 1
data[2] 2
for(i=0, p=data; i<10; i++)
data[3] 3
*p++ = i;
data[4] 4
data[5] 5
data[6] 6
data[7] 7
int data[10]; data[8] 8
int i, *p; data[9] 9

for(i=0, p=data; i<10; *p++ = i++)


;
44

Example:
Insert/Delete Data into/from Arrays

void insertAt(int array[], int size, int at, int val);


void deleteAt(int array[], int size, int at);

data 0 1 2 3 4 5 6 7 8 9
insertAt(data, 10, 3, 5);

data 0 1 2 5 3 4 5 6 7 8
deleteAt(data, 10, 5);

data 0 1 2 5 3 5 6 7 8 8
45

Example:
Insert/Delete Data into/from Arrays

/* arrayOp.c */

/* insertAt: insert an element into an int array */


void insertAt(int array[], int size, int at, int val)
{
int *p, *q; data 0 1 2 3 4 5 6 7 8 9
p = &array[at];
insertAt(data, 10, 3, 5);
q = &array[size-1];
while(q > p){ data 0 1 2 5 3 4 5 6 7 8
*q = *(q-1);
deleteAt(data, 10, 5);
q--;
} data 0 1 2 5 3 5 6 7 8 8
*p = val;
}

/* deleteAt: delete an element from an int array */


void deleteAt(int array[], int size, int at)
{
int *p, *q;
p = &array[at];
q = &array[size-1];
while(p < q){
*p = *(p+1);
p++;
}
}
46

Example:
Insert/Delete Data into/from Arrays

/* main.c */
void insertAt(int array[], int size, int at, int val);
void deleteAt(int array[], int size, int at);
void listElements(int array[], int size);

main() data 0 1 2 3 4 5 6 7 8 9
{
int data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; insertAt(data, 10, 3, 5);

data 0 1 2 5 3 4 5 6 7 8
printf("Origin data:\n");
deleteAt(data, 10, 5);
listElements(data, 10);
data 0 1 2 5 3 5 6 7 8 8
insertAt(data, 10, 3, 5);
printf("After calling insertAt(data, 10, 3, 5):\n");
listElements(data, 10);

deleteAt(data, 10, 5);


printf("After calling deleteAt(data, 10, 5):\n");
listElements(data, 10);
}
47

Example: Pointer Arithmetic

#include <stdio.h>

main() data
data[0] 0
{
int data[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; data[1] 1
int *p, *q; data[2] 2
data[3] 3
printf("data[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}\n\n");
data[4] 4
p = q = data; data[5] 5
printf("p = q = data => p = q = %p\n", data);
printf("q - p = %d\n\n", q - p);
data[6] 6
data[7] 7
p++; q += 5; data[8] 8
printf("p++; q += 5 => p = %p, q = %p\n", p, q);
printf("q - p = %d\n\n", q - p);
data[9] 9

p -= 3; q--;
printf("p -= 3; q-- => p = %p, q = %p\n", p, q);
printf("q - p = %d\n\n", q - p);
}
48

Example: Pointer Arithmetic

#include <stdio.h>

main() data
data[0] 0
{
int data[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}; data[1] 1
int *p, *q; data[2] 2
data[3] 3
printf("data[]={0, 1, 2, 3, 4, 5, 6, 7, 8, 9}\n\n");
data[4] 4
p = q = data; data[5] 5
printf("p = q = data => p = q = %p\n", data);
printf("q - p = %d\n\n", q - p);
data[6] 6
data[7] 7
p++; q += 5; data[8] 8
printf("p++; q += 5 => p = %p, q = %p\n", p, q);
printf("q - p = %d\n\n", q - p);
data[9] 9

p -= 3; q--;
printf("p -= 3; q-- => p = %p, q = %p\n", p, q);
printf("q - p = %d\n\n", q - p);
}
49

Pointer Comparison

▪ <, <=, ==, >=, >


– Usually, they apply to pointers of array’s element
– p  q is true iff p - q  0 is true, e.g.,
p < q is true iff p – q < 0 is true
p > q is true iff p – q > 0 is true

▪ NULL == p ⎯ Test the validity of p, e.g.,

#define NULL 0
int *p = NULL;
/* p may point to somewhere in the following */
. . . . . . . . . . . . . . .
if (NULL==p) printf("p is an invalid pointer");
else printf("%d\n", *p);
50

Pointer Casting

▪ Pointers of the same type can be assigned to


each other
– If not the same type, a cast operator must be used
▪ Example:
main()
{
int m=5;
int *p, *q;
char *r;

p = &m; /* ok */
q = p; /* ok */
r = p; /* warning */
}
51

Pointer Casting

▪ Pointers of the same type can be assigned to


each other
– If not the same type, a cast operator must be used
▪ Example:
main()
{
int m=5;
int *p, *q;
char *r;

p = &m; /* ok */
q = p; /* ok */
r = (char *) p; /* ok */
}
52

Example: Pointer Casting

main()
{ ff →00
int m; m 01
00
int *p, *q; 00
char *r;

m = 0x1ff; /* 511 */
printf("integer m = %d\n\n", m);
p
p = &m; /* ok */
q = p; /* ok */
r = (char *) p; /* ok */ q
printf("p, q, r all point to m:\n");
printf("p=%p, q=%p, r=%p\n", p, q, r); r
printf("*p=%d, *q=%d, *r=%d\n\n", *p, *q, *r);

*r = '\0';

printf("After setting the 1st byte of m zero, then\n");


printf("*p=%d, *q=%d, *r=%d\n", *p, *q, *r);
}
53

Example:Pointer Casting

main()
{ ff →00
int m; m 01
00
int *p, *q; 00
char *r;

m = 0x1ff; /* 511 */
printf("integer m = %d\n\n", m);
p
p = &m; /* ok */
q = p; /* ok */
r = (char *) p; /* ok */ q
printf("p, q, r all point to m:\n");
printf("p=%p, q=%p, r=%p\n", p, q, r); r
printf("*p=%d, *q=%d, *r=%d\n\n", *p, *q, *r);

*r = '\0';

printf("After setting the 1st byte of m zero, then\n");


printf("*p=%d, *q=%d, *r=%d\n", *p, *q, *r);
}
54

Non-Typed Pointer ⎯ void *

▪ Generic pointer, represents any type


▪ No casting needed to convert a pointer to void pointer
▪ void pointers cannot be dereferenced, e.g.,

int m=5, n; int m=5, n;


char c='a', d; char c='a', d;
void *p; void *p;

p = &m; /* ok */ p = &m; /* ok */
n = *p; /* invalid */ n = *(int *) p; /* ok */

p = &c; /* ok */ p = &c; /* ok */
d = *p; /* invalid */ d = *(char *) p; /* ok */
55

C Program Design
C Pointers

▪Pointers and Arrays


56

Pointers vs. Arrays


▪ Arrays and pointers closely related
– Array name like a constant pointer
– Pointers can do array subscripting operations
57

Example:Pointers vs. Arrays (I)


▪ Arrays and pointers closely related
– Array name like a constant pointer
– Pointers can do array subscripting
operations

#include <stdio.h>

main()
{
int data[]={2, -1, 60, 90, 35};
int *p, i;

p = data; /* or p = &data[0] */
printf("p = &data[0]\n");
for(i=0; i<5; i++)
printf("data[%d]=%d\tp[%d]=%d\t\t*(p+%d)=%d\n", i, data[i], i, p[i], i, *(p+i));
}

data[i] == p[i]
p == &data[0] 
data[i] == *(p+i)
pointer-offset notation
58

Example:Pointers vs. Arrays (II)


▪ Arrays and pointers closely related
– Array name like a constant pointer
– Pointers can do array subscripting
operations

#include <stdio.h>

main()
{
int data[]={2, -1, 60, 90, 35};
int *p, i;

p = data; /* or p = &data[0] */
printf("p = &data[0]\n");
for(i=0; i<5; i++, p++)
printf("data[%d]=%d\tp=%p\t*p=%d\n", i, data[i], p, *p);
}
59

Example: Pointers vs. Arrays (III)


▪ Arrays and pointers closely related
– Array name like a constant pointer
– Pointers can do array subscripting
operations

#include <stdio.h>

main()
{
int data[]={2, -1, 60, 90, 35};
int *p, i;

p = data; /* or p = &data[0] */
printf("p = &data[0]\n");
for(i=0; i<5; i++)
printf("data[%d]=%d\tp=%p\t*p++=%d\n", i, data[i], p, *p++);
}
60

Example:Pointers vs. Arrays (IV)


▪ Arrays and pointers closely related
– Array name like a constant pointer
– Pointers can do array subscripting
operations

#include <stdio.h>

main()
data data[0] 2
{ data[1] -1
int data[]={2, -1, 60, 90, 35};
int *p, i; data[2] 60
data[3] 90
p = data; /* or p = &data[0] */
printf("p = &data[0]\n"); data[4] 35
for(i=0; i<5; i++, data++, p++)
printf("*data=%d\t*p=%d\n",*data, *p); p
}
61

C Program Design
C Pointers

▪Arrays of Pointers
62

Arrays of Pointers
▪ Arrays can contain pointers
▪ For example: an array of strings
– char *suit[ 4 ] = {
"Hearts", "Diamonds", "Clubs", "Spades“
};
– Strings are pointers to the first character
– char * ⎯ each element of suit is a pointer to a char
– The strings are not actually stored in the array suit,
only pointers to the strings are stored
63

Arrays of Pointers
▪ Arrays can contain pointers
▪ For example: an array of strings
– char *suit[ 4 ] = {
"Hearts", "Diamonds", "Clubs", "Spades“
};
– Strings are pointers to the first character
– char * ⎯ each element of suit is a pointer to a char
– The strings are not actually stored in the array suit,
only pointers to the strings are stored
64

Example: /* playcard.c */
#include <stdio.h>

void showCard(int card)


{
static const char *suit[4] = {
"Hearts", "Diamonds", "Clubs", "Spades“
};
static const char *face[13] = {
"Ace", "Deuce", "Three", "Four",
"Five", "Six", "Seven", "Eight",
"Nine", "Ten", "Jack", "Queen", "King"
};

printf("%5s of %-8s", face[card%13], suit[card/13]);


}

void shuffle(int deck[])


{
int i, n, t;

for(i=52; i > 1; i--){


n = rand() % i;
t = deck[n];
deck[n] = deck[i-1];
deck[i-1] = t;
}
}
65

Example: /* playcard.c */
#include <stdio.h>

void showCard(int card)


{
static const char *suit[4] = {
#include <stdio.h> "Hearts", "Diamonds", "Clubs", "Spades“
#include <stdlib.h> };
#include <time.h> static const char *face[13] = {
"Ace", "Deuce", "Three", "Four",
void shuffle(int[]); "Five", "Six", "Seven", "Eight",
void showCard(int); "Nine", "Ten", "Jack", "Queen", "King"
};
int deck[52];
printf("%5s of %-8s", face[card%13], suit[card/13]);
main() }
{
int i; void shuffle(int deck[])
{
srand( (unsigned)time( NULL
int )i,);n, t;
for(i=0; i<52; i++) deck[i]=i;
for(i=52; i > 1; i--){
shuffle(deck); n = rand() % i;
t = deck[n];
for(i=0 ; i<52; i++){ deck[n] = deck[i-1];
showCard(deck[i]); deck[i-1] = t;
printf("%s", i % 2 ? }"\n" : "\t");
} }
}
66

Example: /* playcard.c */
#include <stdio.h>

void showCard(int card)


{
static const char *suit[4] = {
#include <stdio.h> "Hearts", "Diamonds", "Clubs", "Spades“
#include <stdlib.h> };
#include <time.h> static const char *face[13] = {
"Ace", "Deuce", "Three", "Four",
void shuffle(int[]); "Five", "Six", "Seven", "Eight",
void showCard(int); "Nine", "Ten", "Jack", "Queen", "King"
};
int deck[52];
printf("%5s of %-8s", face[card%13], suit[card/13]);
main() }
{
int i; void shuffle(int deck[])
{
srand( (unsigned)time( NULL
int )i,);n, t;
for(i=0; i<52; i++) deck[i]=i;
for(i=52; i > 1; i--){
shuffle(deck); n = rand() % i;
t = deck[n];
for(i=0 ; i<52; i++){ deck[n] = deck[i-1];
showCard(deck[i]); deck[i-1] = t;
printf("%s", i % 2 ? }"\n" : "\t");
} }
}
67

C Program Design
C Pointers

▪Pointers to Functions
68

Array Names and Function Names

int data[10]; data Array’s name denotes the starting


address of the array’s data
int main()
{
. . . . .
} main Function’s name denotes the starting
address of the function’s code
int fun()
{
. . . . . fun
}
69

Array Names and Function Names

int data[10]; data Array’s name denotes the starting


address of the array’s data
int main()
{
. . . . .
} main Function’s name denotes the starting
address of the function’s code
int fun()
{
. . . . . fun
}
70

Pointers to Functions
▪ Pointer to function
– A variable contains the address of function
– Similar to how array name is address of first element
– Function name is starting address of code that
defines function

▪ Function pointers can be


– Passed to functions
– Assigned to other function pointers
– Stored in arrays
71

Example
72

Example: Bubble Sort

void bubbleSort(int data[], int n)


{
int tmp, i, j;

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


for(j=0; j<n-i-1; j++)
if(data[j] > data[j+1]){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
73

Example: Bubble Sort

void bubbleSort(int data[], int n)


{
int tmp, i, j; Sort the array into
ascendant order

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


for(j=0; j<n-i-1; j++)
if(data[j] > data[j+1]){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
74

Example: Bubble Sort

void bubbleSort(int data[], int n)


{
int tmp, i, j;

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


for(j=0; j<n-i-1; j++)
if(data[j]
compare> data[j+1]){
if( compare(data[j], data[j+1]) ){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
75

Example: Bubble Sort

void bubbleSort(int data[], int n)


{ How? What type is it?
int compare
tmp, i,isj;
a function pointer, i,e., it represents the starting
address of a function which has the following prototype
for(i=0; i<n-1; i++)
int xxx(int, int);
for(j=0; j<n-i-1; j++)
if(data[j]
compare> data[j+1]){
if( compare(data[j], data[j+1]) ){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
76

Example: Bubble Sort

void bubbleSort(int data[], int n, int (*compare)(int,


compare int))
{
int compare
tmp, i,isj;
a function pointer, i,e., it represents the starting
address of a function which has the following prototype
for(i=0; i<n-1; i++)
int xxx(int, int);
for(j=0; j<n-i-1; j++)
if(data[j]
compare> data[j+1]){
if( compare(data[j], data[j+1]) ){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
77

Example: Bubble Sort

Some syntax variations


void bubbleSort(int data[], int n, int (*compare)(int,
compare int))
{
int compare
tmp, i,isj;
a function pointer, i,e., it represents the starting
address of a function which has the following prototype
for(i=0; i<n-1; i++)
int xxx(int, int);
for(j=0; j<n-i-1; j++)
if( (*compare)(data[j],
compare data[j+1]) ){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
78

Example: Bubble Sort

Some syntax variations


void bubbleSort(int data[], int n, int compare(int,
compare int))
{
int tmp, i, j;

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


for(j=0; j<n-i-1; j++)
if( compare(data[j],
compare data[j+1]) ){
tmp = data[j];
data[j] = data[j+1];
data[j+1] = tmp;
}
}
79

Example: Bubble Sort

void bubbleSort(int data[], int n, int (*compare)(int, int))


{
int tmp, i,
#include j;
<stdio.h>

int compare_ascending(int
for(i=0; i<n-1; i++) a, int b)
{
for(j=0;
return a j<n-i-1;
> b; j++)
} if( (*compare)(data[j], data[j+1]) ){
tmp = data[j];
int compare_descending(int a, int b)
data[j] = data[j+1];
{
data[j+1]
return a < b; = tmp;
} }
}
void listElements(int vals[], int size)
{
int i;

for(i=0; i<size; i++) printf("%d ", vals[i]);


printf("\n");
}
80

Example: Bubble Sort

void bubbleSort(int data[], int n, int (*compare)(int, int))


{ #include <stdio.h>
int tmp, i, j;
#include <stdio.h>
void bubbleSort(int data[], int n, int (*compare)(int, int));
int compare_ascending(int
int compare_ascending(int a, int b) a, int b);
for(i=0; i<n-1; i++)
{ int compare_descending(int a, int b);
for(j=0; j<n-i-1;
return void
a > b; j++)
listElements(int vals[], int size);
} if( (*compare)(data[j], data[j+1]) ){
main()
tmp = data[j];
{
int compare_descending(int a, int b)
data[j]
int = data[j+1];90, 25, 64, 55, 102, 5, 70, 35, 12};
data[]={10,
{
return adata[j+1]
< b; = tmp;
} } printf("Before sorting:\n");
listElements(data, sizeof(data)/sizeof(int));
}
void listElements(int vals[], int size)
{ BubbleSort(data, sizeof(data)/sizeof(int), compare_ascending
compare_ascending);
int i; printf("sort in ascending order:\n");
listElements(data, sizeof(data)/sizeof(int));
for(i=0; i<size; i++) printf("%d ", vals[i]);
printf("\n");BubbleSort(data, sizeof(data)/sizeof(int), compare_descending
compare_descending);
} printf("sort in descending order:\n");
listElements(data, sizeof(data)/sizeof(int));
}
81

Example: Bubble Sort

void bubbleSort(int data[], int n, int (*compare)(int, int))


{ #include <stdio.h>
int tmp, i, j;
#include <stdio.h>
void bubbleSort(int data[], int n, int (*compare)(int, int));
int compare_ascending(int
int compare_ascending(int a, int b) a, int b);
for(i=0; i<n-1; i++)
{ int compare_descending(int a, int b);
for(j=0; j<n-i-1;
return void
a > b; j++)
listElements(int vals[], int size);
} if( (*compare)(data[j], data[j+1]) ){
main()
tmp = data[j];
{
int compare_descending(int a, int b)
data[j]
int = data[j+1];90, 25, 64, 55, 102, 5, 70, 35, 12};
data[]={10,
{
return adata[j+1]
< b; = tmp;
} } printf("Before sorting:\n");
listElements(data, sizeof(data)/sizeof(int));
}
void listElements(int vals[], int size)
{ BubbleSort(data, sizeof(data)/sizeof(int), compare_ascending);
int i; printf("sort in ascending order:\n");
listElements(data, sizeof(data)/sizeof(int));
for(i=0; i<size; i++) printf("%d ", vals[i]);
printf("\n");BubbleSort(data, sizeof(data)/sizeof(int), compare_descending);
} printf("sort in descending order:\n");
listElements(data, sizeof(data)/sizeof(int));
}
82

Exercise (HW #9):


1. 若一Sorting之應用需要所有奇數均排在所有偶數前面,
且所有奇數與所有偶數均由小而大排列,試撰寫一程
式,利用此節中之bubbleSort()函式完成之。
83

Example: Say Tone

#include <stdio.h>

/* shouting */
void say_loud(char *a_message)
{
printf("\"%s!!!\" you shout.\n", a_message);
}

/* whispering */
void say_soft(char *a_message)
{
printf("\"%s\" you whisper.\n", a_message);
}
84

Example: Say Tone

void say_loud(char *a_message)


void say_soft(char *a_message)

/* say function pointer */


void (*say)(char *a_message) = NULL;

int main(void)
{
/* shout */
say = say_loud; /* or say = &say_loud; */
say("WHAT"); /* or (*say)("WHAT"); */

/* whisper */
say = say_soft; /* or say = &say_soft; */
say("I know a secret!"); /* or (*say)("I know a secret!"); */
}
85

Example: Array of Function Pointers

/* arith.c */
#include <stdio.h> int sum(int a, int b)
#include "arith.h" {
return a + b;
int (*arith[4])(int x, int y)={sum, substract, mul, div}; }

main() /* arith.h */ int subtract(int a, int b)


{ int sum(int a, int b); {
int val1, val2, op; int subtract(int a, int b); return a - b;
int mul(int a, int b); }
printf("Enter two numbers: "); int div(int a, int b);
scanf("%d %d", &val1, &val2); int mul(int a, int b)
{
printf("0: Add, 1: Subtract, 2: Multiply, 3: Divide\n"); return a * b;
do { }
printf("Enter number of operation: ");
scanf("%d", &op); int div(int a, int b)
} while(op<0 || op>3); {
if(b) return a / b;
printf("%d", (*arith[op])(val1, val2)); else return 0;
} }
86

C Program Design
C Arrays

▪Strings and String Functions


87

Strings in C
▪ Null-terminated string ⎯ In C, a string is a character
array terminated with a '\0' to mark the end.

sizeof(str) = 7

Example: str h (68) str[0]


e (65) str[1]
l (6C) str[2]
char str[]="hello\n"; l (6C) str[3]
o (6F) str[4]
\n (0A) str[5]
\0 (00) str[6]

char str[]={'h', 'e', 'l', 'l', 'o', '\n', '\0'};


88

Reading Strings
char string[BUF_SIZE]; // ensure buffer large enough

scanf("%s", string); // not &string

or
scanf("%s", &string[0]);

▪ Reads characters until white character encountered.

▪ Be careful not to write past end of array, as it is


possible to do so.
89

Example:Reading Strings
#include <stdio.h>

main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */

/* read string from user into array string1 */


printf( "Enter a string: " );
scanf( "%s", string1 ); /* input ended by whitespace character */

/* output string1 and string2 */


printf( "string1 is: %s\nstring2 is: %s\n", string1, string2 );

/* output space separated string for string1 */


printf( "string1 with spaces between characters is:\n" );
for ( i = 0; string1[ i ] != '\0'; i++ )
printf( "%c ", string1[ i ] );

printf( "\n" );
}
90

Example: Reading Strings

#include <stdio.h>

main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */

/* read string from user into array string1 */


printf( "Enter a string: " );
scanf( "%s", string1 ); /* input ended by whitespace character */

/* output string1 and string2 */


printf( "string1 is: %s\nstring2 is: %s\n", string1, string2 );

/* output space separated string for string1 */


printf( "string1 with spaces between characters is:\n" );
for ( i = 0; string1[ i ] != '\0'; i++ )
printf( "%c ", string1[ i ] );

printf( "\n" );
}
91

atoi and itoa

int atoi( const char[] ); // ascii to integer

int itoa( int, char[] ); // integer to ascii


92

atoi
int atoi( const char[] ); // ascii to integer
int itoa( int, char[] ); // integer to ascii

str '1' char str[]="10759";


'0'
'7' int val;
'5'
'9'
'\0' val = atoi(str);

val 07
2A
00
00
1075910 = 2A0716
93
int atoi( const char[] ); // ascii to integer
atoi int itoa( int, char[] ); // integer to ascii

Byte order: Big-Endian & Little-Endian

str '1' char str[]="10759";


'0'
'7' int val;
'5'
'9'
'\0' val = atoi(str);

val 07
2A
00
00
1075910 = 2A0716
94
int atoi( const char[] ); // ascii to integer
itoa int itoa( int, char[] ); // integer to ascii

str '1' char str[6];


'0'
'7' int val=10759;
'5'
'9'
int len; // >> 5
'\0'

len=itoa(val, str);
val 07
2A
00
00
1075910 = 2A0716
95

Example: atoi

/* atoi: convert decimal string s to integer */


int atoi(const char s[])
{
int i=0, val=0, sign;

sign = s[i] == '-' ? -1 : 1; /* record sign */


if(s[i] == '+' || s[i] == '-') i++; /* skip sign if existent */

while(s[i] >= '0' && s[i] <= '9') /* non-numeric terminated */


val = 10 * val + (s[i++] - '0');

return val * sign;


}
96

Example: itoa

/* itoa: convert n to characters in s and return length */


int itoa(int n, char s[])
{
int i, negative;
n = (negative = (n < 0)) ? –n : n; /* record sign */
/* make n positive */
i = 0;
do { /* generate digits in reverse order */
s[i++] = n % 10 + '0'; /* get next digit */
} while ((n /= 10) > 0); /* delete it */
if (negative) s[i++] = '-';
s[i] = '\0';
reverse(s);
return i;
}
97

Example: strlen, reverse

/* strlen: return the string length of s */


int strlen(const char s[])
{
int i=0;
while(s[i]) i++;
return i;
}

/* reverse: reverse sting s */


void reverse(char s[])
{
int i, j, temp;

i = 0;
j = strlen(s) - 1;

while(i < j){


temp = s[i]; s[i] = s[j]; s[j] = temp;
i++; j--;
}
}
98

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str) from index (start)


// into an integer with heading value (val)
int recursive_atoi(const char str[], int val, int start)
{
if(str[start] == '-')
start=3
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else str
if(str[start]=='\0')
'1' '2' '5' '9' '3' '0' '1' '9' '\0'
return val;
else
return val=125
recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0, 0);
}
99

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str) from index (start)


// into an integer with heading value (val)
int recursive_atoi(const char str[], int val, int start)
{
if(str[start] == '-')
start=0
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else str
if(str[start]=='\0')
'1' '2' '5' '9' '3' '0' '1' '9' '\0'
return val;
else
val=0
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0, 0);
}
100

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str) from index (start)


// into an integer with heading value (val)
int recursive_atoi(const char str[], int val, int start)
{
if(str[start] == '-')
start=8
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else str
if(str[start]=='\0')
'1' '2' '5' '9' '3' '0' '1' '9' '\0'
return val;
else
val=12593019
return recursive_atoi(str, val  answer
* 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0, 0);
}
101

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str) from index (start)


// into an integer with heading value (val)
int recursive_atoi(const char str[], int val, int start)
{
if(str[start] == '-')
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+') start=8 start=3
return recursive_atoi(str, val, start+1);
if(str[start]=='\0') str '1' '2' '5' '9' '3' '0' '1' '9' '\0' str '1' '2' '5' '9' '3' '0' '1' '9' '\0'

return val;
val=12593019  answer val=125
else
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0, 0);
}
102

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str) from index (start)


// into an integer with heading value (val)
int recursive_atoi(const char str[], int val, int start)
{
if(str[start] == '-')
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else if(str[start]=='\0')
return val;
else
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0, 0);
}
103

Example: atoi (recurive version)

// main.c
#include//<stdio.h>
RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str) from index (start)


int atoi(char[]);
// into an integer with heading value (val)
main() int recursive_atoi(const char str[], int val, int start)
{ {
if(str[start] == '-')
char str[20];
return
printf("Enter -recursive_atoi(str,
a numeric string:"); val, start+1);
else str);
scanf("%s", if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else value
printf("The if(str[start]=='\0')
you type is:%d\n", atoi(str));
} return val;
else
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0, 0);
}
104

Example: itoa (recurive version)

// RecursiveItoa.c

// recursive_itoa: itoa之輔助函式
// 將n值轉為十進制字串,將結果從s矩陣之start處開始擺放
// 傳回值為轉換後之字串長度
int recursive_itoa(int n, char s[], int start)
{
int len = 0; start
if(n/10) len = recursive_itoa(n/10, s, start);
s[start+len] = n % 10 + '0';
returnslen+1;
x x x x x x x x x
}

// itoa: convert integer (n) into string (s) and return length
int itoa(int n, char s[])
{
int i=0;
if(n<0){
s[i++]='-';
n = -n;
}
i += recursive_itoa(n, s, i);
s[i]='\0';
return i;
}
105

Example: itoa (recurive version)

// RecursiveItoa.c

// recursive_itoa: itoa之輔助函式
// 將n值轉為十進制字串,將結果從s矩陣之start處開始擺放
// 傳回值為轉換後之字串長度
int recursive_itoa(int n, char s[], int start)
{
int len = 0; start
if(n/10) len = recursive_itoa(n/10, s, start);
s[start+len] = n % 10 + '0';
returnslen+1;
x x ‘1’
x ‘0’x ‘2’x ‘4’
x x x x n=1024
}
Return 4
// itoa: convert integer (n) into string (s) and return length
int itoa(int n, char s[])
{
int i=0;
if(n<0){
s[i++]='-';
n = -n;
}
i += recursive_itoa(n, s, i);
s[i]='\0';
return i;
}
106

Example: itoa (recurive version)

// RecursiveItoa.c

// recursive_itoa: itoa之輔助函式
// 將n值轉為十進制字串,將結果從s矩陣之start處開始擺放
// 傳回值為轉換後之字串長度
int recursive_itoa(int n, char s[], int start)
{
int len start
= 0;
if(n/10) len = recursive_itoa(n/10, s, start);
s[start+len] = n % 10 + '0';
returnslen+1;
x x x x x x x x x
}

// itoa: convert integer (n) into string (s) and return length
int itoa(int n, char s[])
{
int i=0;
if(n<0){
s[i++]='-';
n = -n;
}
i += recursive_itoa(n, s, i);
s[i]='\0';
return i;
}
107

Example: itoa (recurive version)

// RecursiveItoa.c

// recursive_itoa: itoa之輔助函式
// 將n值轉為十進制字串,將結果從s矩陣之start處開始擺放
// 傳回值為轉換後之字串長度
int recursive_itoa(int n, char s[], int start)
{
int len = 0;
if(n/10) len = recursive_itoa(n/10, s, start);
s[start+len] = n % 10 + '0';
return len+1;
}

// itoa: convert integer (n) into string (s) and return length
int itoa(int n, char s[])
{
int i=0;
if(n<0){
s[i++]='-';
n = -n;
}
i += recursive_itoa(n, s, i);
s[i]='\0';
return i;
}
108

String Functions

<stdlib.h>

<string.h>
109

Reading Strings
char string[BUF_SIZE]; // ensure buffer large enough

scanf("%s", string); // not &string

or
scanf("%s", &string[0]);

▪ Reads characters until white character encountered.

▪ Be careful not to write past end of array, as it is


possible to do so.
110

Example:Reading Strings
#include <stdio.h>

main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */

/* read string from user into array string1 */


printf( "Enter a string: " );
scanf( "%s", string1 ); /* input ended by whitespace character */

/* output string1 and string2 */


printf( "string1 is: %s\nstring2 is: %s\n", string1, string2 );

/* output space separated string for string1 */


printf( "string1 with spaces between characters is:\n" );
for ( i = 0; string1[ i ] != '\0'; i++ )
printf( "%c ", string1[ i ] );

printf( "\n" );
}
111

Example: Reading Strings

#include <stdio.h>

main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */

/* read string from user into array string1 */


printf( "Enter a string: " );
scanf( "%s", string1 ); /* input ended by whitespace character */

/* output string1 and string2 */


printf( "string1 is: %s\nstring2 is: %s\n", string1, string2 );

/* output space separated string for string1 */


printf( "string1 with spaces between characters is:\n" );
for ( i = 0; string1[ i ] != '\0'; i++ )
printf( "%c ", string1[ i ] );

printf( "\n" );
}
112

atoi and itoa

int atoi( const char[] ); // ascii to integer

int itoa( int, char[] ); // integer to ascii


113

atoi
int atoi( const char[] ); // ascii to integer
int itoa( int, char[] ); // integer to ascii

str '1' char str[]="10759";


'0'
'7' int val;
'5'
'9'
'\0' val = atoi(str);

val 07
2A
00
00
1075910 = 2A0716
114
int atoi( const char[] ); // ascii to integer
atoi int itoa( int, char[] ); // integer to ascii

Byte order: Big-Endian & Little-Endian

str '1' char str[]="10759";


'0'
'7' int val;
'5'
'9'
'\0' val = atoi(str);

val 07
2A
00
00
1075910 = 2A0716
115
int atoi( const char[] ); // ascii to integer
itoa int itoa( int, char[] ); // integer to ascii

str '1' char str[6];


'0'
'7' int val=10759;
'5'
'9'
int len; // >> 5
'\0'

len=itoa(val, str);
val 07
2A
00
00
1075910 = 2A0716
116

Example: String Copy (I)

#include <stdio.h>

void stringCopy(char* dest, const char* source);

main()
{
char string1[10]; /* create a string buffer of size 10 */
char *string2="Hello"; /* create a string using pointer notation */
char string3[10]; /* create a string buffer of size 10 */
char string4[]="Good Bye"; /* create a string using array notation */

stringCopy(string1, string2);
printf("string1=%s\n", string1);

stringCopy(string3, string4);
printf("string3=%s\n", string3);
}

void stringCopy(char* dest, const char* source)


{
while(*source!='\0'){
*dest = *source;
dest++; source++;
}
*dest='\0';
}
117

Example: String Copy (II)

#include <stdio.h>

void stringCopy(char* dest, const char* source);

main()
{
char string1[10]; /* create a string buffer of size 10 */
char *string2="Hello"; /* create a string using pointer notation */
char string3[10]; /* create a string buffer of size 10 */
char string4[]="Good Bye"; /* create a string using array notation */

stringCopy(string1, string2);
printf("string1=%s\n", string1);

stringCopy(string3, string4);
printf("string3=%s\n", string3);
}

void stringCopy(char* dest, const char* source)


{
while(*source)
*dest++ = *source++;
*dest='\0';
}
118

Example: String Copy (III)

#include <stdio.h>

void stringCopy(char* dest, const char* source);

main()
{
char string1[10]; /* create a string buffer of size 10 */
char *string2="Hello"; /* create a string using pointer notation */
char string3[10]; /* create a string buffer of size 10 */
char string4[]="Good Bye"; /* create a string using array notation */

stringCopy(string1, string2);
printf("string1=%s\n", string1);

stringCopy(string3, string4);
printf("string3=%s\n", string3);
}

void stringCopy(char* dest, const char* source)


{
while(*dest++ = *source++);
}

strcpy
119

Example: String Length

/* non-recursive version */
int stringLength(const char *s)
{
int len=0;

while(*s++) len++;
return len;
}

/* recursive version */
int recursiveStringLength(const char *s)
{
if(*s=='\0') return 0;
return recursiveStringLength(++s) + 1;
}
120

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str)


// into an integer with leading value (leading_val)
int recursive_atoi(const char *str, int leading_val)
{
if(str[start] == '-')
str
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else if(str[start]=='\0')
'1' '2' '5' '9' '3' '0' '1' '9' '\0'
return val;
else
leading_val=125
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char *str)
{
return recursive_atoi(str, 0, 0);
}
121

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str)


// into an integer with leading value (leading_val)
int recursive_atoi(const char *str, int leading_val)
{
if(str[start] == '-')
returnstr
-recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else if(str[start]=='\0')
'1' '2' '5' '9' '3' '0' '1' '9' '\0'
return val;
else
leading_val=0
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char *str)
{
return recursive_atoi(str, 0);
}
122

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str)


// into an integer with leading value (leading_val)
int recursive_atoi(const char *str, int leading_val)
{
if(str[start] == '-')
str
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+')
return recursive_atoi(str, val, start+1);
else if(str[start]=='\0')
'1' '2' '5' '9' '3' '0' '1' '9' '\0'
return val;
else
leading_val=12593019
return recursive_atoi(str, val * 10 + answer
(str[start] - '0'), start+1);
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char *str)
{
return recursive_atoi(str, 0);
}
123

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str)


// into an integer with leading value (leading_val)
int recursive_atoi(const char *str, int leading_val)
{
if(str[start] == '-')
return -recursive_atoi(str, val, start+1);
else if(str[start] == '+') str str
return recursive_atoi(str, val, start+1);
'1' '2' '5' '9' '3' '0' '1' '9' '\0' '1' '2' '5' '9' '3' '0' '1' '9' '\0'
if(*str =='\0')
return leading_val;
leading_val=12593019  answer leading_val=125
else
return recursive_atoi(++str, leading_val * 10 + (*str - '0'));
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char str[])
{
return recursive_atoi(str, 0);
}
124

Example: atoi (recurive version)

// RecursiveAtoi.c

// recursive_atoi: convert a decimal string (str)


// into an integer with leading value (leading_val)
int recursive_atoi(const char *str, int leading_val)
{
if(*str == '-')
return -recursive_atoi(++str, leading_val);
else if(*str == '+')
return recursive_atoi(++str, leading_val);
else if(*str =='\0')
return leading_val;
else
return recursive_atoi(++str, leading_val * 10 + (*str - '0'));
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char *str)
{
return recursive_atoi(str, 0);
}
125

Example: atoi (recurive version)

// main.c
#include//<stdio.h>
RecursiveAtoi.c

// recursive_atoi:
int atoi(const char*); convert a decimal string (str)
// into an integer with leading value (leading_val)
main() int recursive_atoi(const char *str, int leading_val)
{ {
if(*str == '-')
char str[20];
return
printf("Enter -recursive_atoi(++str,
a numeric string:"); leading_val);
else str);
scanf("%s", if(*str == '+')
return recursive_atoi(++str, leading_val);
else value
printf("The if(*str
you=='\0')
type is:%d\n", atoi(str));
} return leading_val;
else
return recursive_atoi(++str, leading_val * 10 + (*str - '0'));
}

// atoi: convert a decimal string str into an integer


// assume str is error free
int atoi(const char *str)
{
return recursive_atoi(str, 0);
}

You might also like

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy