- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
指针变量的重要作用之一 ——作为函数的参数,实现地址传递
例 函数调用中的值传递
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; 传递数据采用“值传递”, } 形参单独占用内存单元,交
变量的访问方式
(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)赋值
多维数组的指针——以二维数组为例
例:声明数组 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]
P.259-263 例8.20各种不同的表达方式 8.4.3节 分析一些容易发生的错误
指向函数的指针
——指向函数代码的起始地址。
若声明一个指针变量存放该地址,则可通过此 例:P.267 改写的代码
指针变量来调用该函数。
作用:可用同样的语句调用不同函数
<=> 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]
(*p)++(P.236-237)
参见P.378 运算符的 优先级与结合性
若定义数组a[5]和指针变 量*p=a,则a[6]等价于 p+6,指针指向数组之后 的地址,故不报错
通过指针引用数组元素
例
教材 P.233-234 例8.6
三种表达方式 P.235 例8.7 ——不能达到目的
数组名作为函数的参数
例. 分析以下程序运行结果
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); 了它们的值,也就
n2_p指向n2。
和n2_p的值改变了,也就是指向改变了。 指针变量n1_p指向n2,指针变量n2_p指向 n1。
掌握几个重要概念
内存 内存单元 区别两个 *p 内存单元的地址 int *p; 变量的首地址 p=&a; 指针 *p=3; 指针变量 指针变量的指向 直接访问与间接访问
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; }
内存地址是二进制数, 通常写成十六进制
short int a; a=500;
内存地址──内存中存储单元的编号
计算机内存由大量存储单元 (memory unit) 组成。 每个存储单元容量为1字节(byte) 。
每个存储单元有编号,即存储单元的“地址” (address) 。 存储单元中可存放数据(data)。
二维数组的列指针:以指针变量表示
通过指针引用字符串
字符串是在内存中连续存放的一组字符
以变量形式保存字符串需要声明字符数组
或声明一个指针变量访问字符串或字符数组
(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);
变量的地址
定义变量时,系统分配给变量的内 存单元的起始地址
变量值的存取通过变量在内存中的
地址进行
变量的地址称为“指针”(pointer)
变量的访问方式
(1)直接访问──直接利用变量的地址进 行存取 例:short int a; a=500; 在符号表中检索变量名a,找到其起 始地址(例如13A6);将数值500(的二进 制形式)送到内存单元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]
换对实参无影响。
例 通过指针变量实现地址传递的效果
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; }
二维数组的行指针:以二维数组名表示
多维数组的指针——以二维数组为例
例:声明数组 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
p是普通的变量 注意这两个*p1的 含义不同,前者说 明p1为指针变量, 后者表示p1所指向 的变量。
void swap(int *p1,int *p2) { int p; p=*p1; *p1=*p2; *p2=p; }
指针变量作为函数的参数
指针作实参,对应的形参是指针变量。 C语言的参数传递是“值传递”。 指针变量做参数时,由于其值为变量的地址,
数组的指针:数组在内存中的起始地址,
即首元素(下标为0的元素)的首地址 数组元素的指针:数组元素在内存中的 起始地址 数组名:代表数组首元素的地址(指针) 指向数组的指针变量:存储数组某个元 素的地址,即指向某个元素
定义指向数组的指针变量
int array[5], *pointer = array;
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