C语言程序设计第四版PPT 谭浩强
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
(*p)++(P.236-237)
参见P.378 运算符的 优先级与结合性
若定义数组a[5]和指针变 量*p=a,则a[6]等价于 p+6,指针指向数组之后 的地址,故不报错
通过指针引用数组元素
例
教材 P.233-234 例8.6
三种表达方式 P.235 例8.7 ——不能达到目的
ຫໍສະໝຸດ Baidu组名作为函数的参数
产生“地址传递”的效果。
数组做函数的参数时,也是“地址传递”。 被调用函数不能改变实参指针变量的值,但
可以改变实参指针变量所指向的变量的值。
指针变量
阅读例8.2-例8.5,上机调试,观察结果,分
析掌握。
要求能够熟练地掌握指针变量及其指向的变
化过程,能够在纸上画图表达分析过程。
访问数组——指针的又一重要用途
p是普通的变量 注意这两个*p1的 含义不同,前者说 明p1为指针变量, 后者表示p1所指向 的变量。
void swap(int *p1,int *p2) { int p; p=*p1; *p1=*p2; *p2=p; }
指针变量作为函数的参数
指针作实参,对应的形参是指针变量。 C语言的参数传递是“值传递”。 指针变量做参数时,由于其值为变量的地址,
换对实参无影响。
例 通过指针变量实现地址传递的效果
int main() { void swap(int *p1,int *p2); int a,b; int *a_p=&a, *b_p=&b; scanf("%d,%d",&a,&b); if(a<b) swap(a_p,b_p); printf("%d,%d\n",a,b); return 0; }
第8章 指针
关于指针
指针是C语言的一个重要特色; 正确而灵活地运用指针可以:
有效表示复杂的数据结构;
能动态分配内存;
方便地使用字符串;
有效而方便地使用数组; 在调用函数时能获得1个以上的结果; 能直接处理内存单元的地址 可以使程序简洁、紧凑、高效
内存储器
由内存单元组成,每个单元有地址, 存放一字节数据 变量a 0000000111110100 13A5 13A6 13A7
<=> <=> <=> <=>
&a[0][0] &a[0][1] &a[1][2] &a[1][1]
二维数组的列指针:以一维数组名表示
多维数组的指针——以二维数组为例
例:声明数组 int a[3][4] a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] int *p; p=a; p++; p=p+5; p => a[0][0] p => a[0][1] p => a[1][2]
P.259-263 例8.20各种不同的表达方式 8.4.3节 分析一些容易发生的错误
指向函数的指针
——指向函数代码的起始地址。
若声明一个指针变量存放该地址,则可通过此 例:P.267 改写的代码
指针变量来调用该函数。
作用:可用同样的语句调用不同函数
二维数组的行指针:以二维数组名表示
多维数组的指针——以二维数组为例
例:声明数组 int a[3][4] a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3]
a[0] a[0]+1 a[1]+2 a[0]+5
指针变量的重要作用之一 ——作为函数的参数,实现地址传递
例 函数调用中的值传递
int main() void swap(int p1,int p2) { void swap(int p1,int p2); { int p; int a,b; p=p1; p1=p2; p2=p; scanf("%d,%d",&a,&b); } if(a<b) swap(a,b); printf("%d,%d\n",a,b); 运行结果:a,b没有交换。 原因:C语言中,实参向形参 return 0; 传递数据采用“值传递”, } 形参单独占用内存单元,交
数组的指针:数组在内存中的起始地址,
即首元素(下标为0的元素)的首地址 数组元素的指针:数组元素在内存中的 起始地址 数组名:代表数组首元素的地址(指针) 指向数组的指针变量:存储数组某个元 素的地址,即指向某个元素
定义指向数组的指针变量
int array[5], *pointer = array;
多维数组的指针——以二维数组为例
例:声明数组 int a[3][4] a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3]
a <=> &a[0][0] a+1 <=> &a[1][0] a+2 <=> &a[2][0]
n2_p指向n2。
和n2_p的值改变了,也就是指向改变了。 指针变量n1_p指向n2,指针变量n2_p指向 n1。
掌握几个重要概念
内存 内存单元 区别两个 *p 内存单元的地址 int *p; 变量的首地址 p=&a; 指针 *p=3; 指针变量 指针变量的指向 直接访问与间接访问
二维数组的列指针:以指针变量表示
通过指针引用字符串
字符串是在内存中连续存放的一组字符
以变量形式保存字符串需要声明字符数组
或声明一个指针变量访问字符串或字符数组
(P.257图8.28)——不是字符串变量
char *string; string="Work hard!"; printf("%s\n",string); printf("%c\n",*string++); printf("%c\n",*(string+5)); printf("%s\n",string);
内存地址是二进制数, 通常写成十六进制
short int a; a=500;
内存地址──内存中存储单元的编号
计算机内存由大量存储单元 (memory unit) 组成。 每个存储单元容量为1字节(byte) 。
每个存储单元有编号,即存储单元的“地址” (address) 。 存储单元中可存放数据(data)。
int array[5], *pointer;
pointer = array; int array[5], *pointer = &array[0];
使用指针访问数组元素,能使目标程 序占用内存少、运行速度快。
通过指针引用数组元素
例 int main( )
{ int a[5]={12,6,18,23,9}; int *p; p=a; printf("%d,%x\n",*p,p); printf("%d,%x\n",*(p+2),p+2); p++; printf("%d,%x\n",*p,p); p=p+2; printf("%d,%x\n",*p,p); return 0; }
是交换了指向
printf("n1=%d, n2=%d\n", n1, n2); printf("*n1_p=%d, *n2_p=%d\n", *n1_p, *n2_p); printf("n1_p=%o, n2_p=%o\n", n1_p, n2_p); pointer=n1_p; n1_p=n2_p; n2_p=pointer;
相当于 char *p; p="China"; 而不是 char *p; *p="China";
P.256例8.18数组名指针的应用(字符型)
P.256例8.19指针变量访问字符型数组
通过指针引用字符串
字符指针作函数参数 实参 数组名 数组名 指针变量 指针变量 形参 数组名 指针变量 指针变量 数组名
变量的地址
定义变量时,系统分配给变量的内 存单元的起始地址
变量值的存取通过变量在内存中的
地址进行
变量的地址称为“指针”(pointer)
变量的访问方式
(1)直接访问──直接利用变量的地址进 行存取 例:short int a; a=500; 在符号表中检索变量名a,找到其起 始地址(例如13A6);将数值500(的二进 制形式)送到内存单元13A6和13A7中 //分配内存地址
例. 分析以下程序运行结果
int main() { int n1,n2; int *n1_p=&n1, *n2_p=&n2, *pointer; printf("Input n1:"); scanf("%d",n1_p); 两个指针变量交换 printf("Input n2:"); scanf("%d",n2_p); 了它们的值,也就
通过指针引用数组元素
对于数组a和指向该数组首元素的指针变量p
p+i
和 a+i 均表示元素a[i]的地址
*(p+i),
*(a+i), a[i] 均表示元素a[i]的值
p+1的含义是指向下一个元素地址
可以p++,不能a++——首元素地址不能改变
注意区别*p++(等价于*(p++)),
*(++p)和
++在后,先取p值,再 ++,p用于*p 请对照*(++p)
通过指针引用字符串
P.255 例8.16 使用字符数组存放字符串 使用字符数组名输出字符串
使用字符数组下标访问数组元素
通过指针引用字符串
P.256 例8.17 使用基类型为字符的指针 变量保存字符串首元素地址,从而访问 字符串 char *p="China"; printf("%s",p);
short int a[3]; a[2]=6; a[0]
2000
元素的值
数组元素
a[1]
2002
a[2]
2004
xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx xxxxxxxxxxxxxxxx 0000000000000110
元素的地址 数组的首地址
元素的地址
数组和指针的相关概念
printf("n1=%d, n2=%d\n", n1, n2); printf("*n1_p=%d, *n2_p=%d\n", *n1_p, *n2_p); printf("n1_p=%o, n2_p=%o\n", n1_p, n2_p); }
上页代码要点
开始时指针变量n1_p指向n1,指针变量 变量n1和n2的值并没有改变,但n1_p
进一步分析——用指针访问数组
实参 数 组 名 数 组 名 指针变量 指针变量 形参 数 组 名 指针变量 指针变量 数 组 名
数组名 指针变量
数组名作为函数的参数—以指针表示
P.239 例8.8 数组元素逆序排列 ——形参:数组名;实参:数组名 P.241 例8.8 程序修改 ——形参:指针变量 P.242 例8.9 数组元素逆序排列 ——形参:指针变量;实参:指针变量 P.244 例8.10 选择排序 ——形参:数组;实参:指针变量 P.245 例8.10 函数修改 ——形参:指针变量
变量的访问方式
(2)间接访问──通过指针变量访问变量
地址 定义一种特殊的变量,用来存放其
它变量的地址(指针),这种变量称为
指针变量,它指向一个普通的变量。
指针变量的定义和调用
定义一个指针变量
例:
它指向一个整型变量(基类型) 给指针变量赋值
int a; 指针变量的值是 int *a_pointer; 另一个变量的地址 73 a = 500; 页输 指针变量所指向的 出格 a_pointer = &a; 变量即a的值 式 printf("%d\n",*a_pointer); 指针变量的值, printf("%x\n",a_pointer); 即a的地址 *a_pointer = 3; 对指向的变量(即a)赋值
<=> a[0] <=> a[1] <=> a[2]
二维数组的行指针:以二维数组名表示
多维数组的指针——以二维数组为例
例:声明数组 int a[3][4] a[0][0] a[0][1] a[0][2] a[0][3] a[1][0] a[1][1] a[1][2] a[1][3] a[2][0] a[2][1] a[2][2] a[2][3] int *p=a; p=a+1; p=a+2; p => a[0][0] p => a[1][0] p => a[2][0]