Lecture 08 - 2024-1
Lecture 08 - 2024-1
Lecture 08 - 2024-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
Memory Space
C Pointers
▪ Powerful, but difficult to master
▪ Simulate call-by-reference
– C only has call-by-value
C Program Design
C Pointers
Pointer Variables
Variable is a piece of memory containing a
value of a specific type (direct reference).
▪ 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
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;
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;
printf("Address of n is %p\n"
"Address of x is %p\n",
nPtr, xPtr);
}
21
00427600
n 5
*nPtr = ? 00427608
x 3.14
..
.
*xPtr = ? nPtr
xPtr
00427600
00427608
22
#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>
a = 7;
aPtr = &a; /* aPtr set to address of a */
Example:
Showing that * and & are
complements of each other.
#include <stdio.h>
#include <stdio.h>
C Program Design
C Pointers
#include <stdio.h>
main()
{
int a = 23, b = 47;
int t;
t = a;
a = b;
b = t;
#include <stdio.h>
main()
{
int a = 23, b = 47;
int t;
t = a;
a = b; define a function to do swapping.
b = t;
#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
#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
#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
#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
t = *a;
*a = *b;
*b = t;
}
C Program Design
C Pointers
Pointer Arithmetic
▪ Increment/decrement pointer
– ++ or –-
Pointer Arithmetic
▪ Increment/decrement pointer
– ++ or –-
Pointer Arithmetic
▪ Increment/decrement pointer (++ or –-)
▪ Add/substract an integer to a pointer (+ or += , - or -
=)
▪ Pointers may be subtracted from each other
Pointer Arithmetic
▪ Increment/decrement pointer (++ or –-)
▪ Add/substract an integer to a pointer (+ or += , - or -
=)
▪ Pointers may be subtracted from each other
Example:
Insert/Delete Data into/from Arrays
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 */
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);
#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
#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
#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
p = &m; /* ok */
q = p; /* ok */
r = p; /* warning */
}
51
Pointer Casting
p = &m; /* ok */
q = p; /* ok */
r = (char *) p; /* ok */
}
52
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';
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';
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
#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
#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
#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
#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>
Example: /* playcard.c */
#include <stdio.h>
Example: /* playcard.c */
#include <stdio.h>
C Program Design
C Pointers
▪Pointers to Functions
68
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
Example
72
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;
#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
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
/* 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}; }
C Program Design
C Arrays
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
Reading Strings
char string[BUF_SIZE]; // ensure buffer large enough
or
scanf("%s", &string[0]);
Example:Reading Strings
#include <stdio.h>
main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */
printf( "\n" );
}
90
#include <stdio.h>
main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */
printf( "\n" );
}
91
atoi
int atoi( const char[] ); // ascii to integer
int itoa( int, char[] ); // integer to ascii
val 07
2A
00
00
1075910 = 2A0716
93
int atoi( const char[] ); // ascii to integer
atoi int itoa( int, char[] ); // integer to ascii
val 07
2A
00
00
1075910 = 2A0716
94
int atoi( const char[] ); // ascii to integer
itoa int itoa( int, char[] ); // integer to ascii
len=itoa(val, str);
val 07
2A
00
00
1075910 = 2A0716
95
Example: atoi
Example: itoa
i = 0;
j = strlen(s) - 1;
// RecursiveAtoi.c
// RecursiveAtoi.c
// RecursiveAtoi.c
// RecursiveAtoi.c
return val;
val=12593019 answer val=125
else
return recursive_atoi(str, val * 10 + (str[start] - '0'), start+1);
}
// RecursiveAtoi.c
// main.c
#include//<stdio.h>
RecursiveAtoi.c
// 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
// 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
// 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
// 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
or
scanf("%s", &string[0]);
Example:Reading Strings
#include <stdio.h>
main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */
printf( "\n" );
}
111
#include <stdio.h>
main()
{
char string1[ 20 ]; /* reserves 20 characters */
char string2[] = "string literal"; /* reserves 15 characters */
int i; /* counter */
printf( "\n" );
}
112
atoi
int atoi( const char[] ); // ascii to integer
int itoa( int, char[] ); // integer to ascii
val 07
2A
00
00
1075910 = 2A0716
114
int atoi( const char[] ); // ascii to integer
atoi int itoa( int, char[] ); // integer to ascii
val 07
2A
00
00
1075910 = 2A0716
115
int atoi( const char[] ); // ascii to integer
itoa int itoa( int, char[] ); // integer to ascii
len=itoa(val, str);
val 07
2A
00
00
1075910 = 2A0716
116
#include <stdio.h>
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);
}
#include <stdio.h>
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);
}
#include <stdio.h>
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);
}
strcpy
119
/* 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
// RecursiveAtoi.c
// RecursiveAtoi.c
// RecursiveAtoi.c
// RecursiveAtoi.c
// RecursiveAtoi.c
// 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'));
}