- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
例如: int x,p=&x;
int x,*p=&x;
int x; float *p=&x;
可以用赋值语句给指针变量赋值:
float y, *py; py=&y;
指针变量的引用
引用指针变量的指针值与引用其它 类型的变量一样直接用它的变量名
引用指针变量所指向的变量时, 用“*指针变量名” 注意: ①指针变量的值与它所指向变量的值之间的差别 ②指针变量只有正确赋值后才能通过它访问指向的变量。
main()
{int a[4]={1,2,3,4},b,c,d,e;
int *p=a;
b=*p++;
printf(“\n%d,%d,”,b,*p);
c=*++p;
d=++*p; printf(“%d,%d”,c,d); }
运行结果 1,2,3,4
通过指针引用数组元素
在 int a[10],*p=a; 定义的情况下:
如果已定义
float a, *p=&a ;
则 *p 是变量 a &*p 是变量a的地址 p &*p 等价于 p
而 &a 是变量a的地址 p *&a 是p所指向的变量 a *&a 等价于a
注意
(1). 指针变量定义和引用指向变量的“*”含义有差别。 (2).不能引用没有赋值的指针变量,不要误认为p定义后
C语言中规定数组名是指针类型的符号常量, 该符号常量值等于数组首元素的地址 ( 简称数 组首地址) ,它的类型是指向数组元素的指针类型。 即数组名是指向该数组首元素的指针常量。
指向数组元素的指针
1.定义指向数组元素的指针变量
定义指向数组元素的指针变量与定义指向变量的指针变量的
方法相同.如: int a[10];
该内存单元的内容就是变量的值。
2206
int i=3;
float j=6;
2214
double k=9;
3 变量i 6.0 变量j
9.0 变量k
直接访问和间接访问
直接访问:用变量名直接从它对应的地址存取内容。
如: int x=5,y=8,z=0; z =x+y;
直接从 x 和 y 对应的地址2200和2202 2200 5
变量x
取出内容5和8然后相加将结果13存入
2202
8
变量y
变量 z 对应的地址2204的单元中。
2204 103 变量z
间接访问
定义一个存放地址的变量p (p的地址1500), 将x的地址 2200存放在变量 p 中。通过 变量p取出地址2200, 再按此 地址存取其中的内容, 就间接 的完成了对x的存取。
如: int a[10],*p; p=a; p++; p+=3;
注意: 指针变量的运算顺序。
++*p,*p++,*(++p),(*p)++ 四者之间的差别: ++*p 先给p指向的变量加1,然后取其值 (*p)++ 先取p指向的变量值, 然后该变量值加1 *p++ 取p所指向变量的值, 然后p增1 *++p P先增1, 然后取p所指向变量的值
第9章 指 针
特点
能直接对内存地址操作, 使用灵活 实现动态存储管理 可以使程序简洁、紧凑、高效 用间接访问的方式改变数据的逻辑顺序 调用函数时可实现变量的引用传递
地址和指针的概念
变量的地址和变量的值
程序中定义的变量, 系统根据它的 类型给它分配一定长度的内存单元,
2200 2202
该内存单元的起始地址即为变量的地址。
p1=p2;
p2=p; }
&&yx
8
p2
y
&&xy
6
printf("min=%d, max=%d\n",*p1,*p2); }
运行结果: min=6, max=8
指针变量作为函数的参数
以指针类型为函数的参数,作用是将变量的地址传入函数。
swap(int *p1,int *p2)
{ int p; p=*p1; *p1=*p2; *p2=p;
printf("\n");
printf("%d", *p);
for(i=0;i<10;i++) ③ for(p=a;p<(a+10);p++)
printf("%d", a[i]); printf("%d",*p);
}
用字符型指针访问字符数组和字符串
【例9.5】用字符型数组名和字符指针变量 两种方法整体输入/输出字符串。
变量*p就已存在,必须给p正确赋值后,变量*p才存在。 (3).p=&a;是给指针变量p 赋值, *p=3; 是给p指向的变量
赋值。两者含义完全不同。
(4).给指针变量赋值必须用同类型的指针。 (5).指针变量只存放地址, 地址值是无符号整数, 但不能直
接用整型量(或其它非地址量)赋值给指针变量。
int *p1=2200;
scanf("%d %d",p,&n); printf("m=%d &m=%X\n",m,&m); printf("*p=%d p=%X\n",*p,p); printf("n=%d &n=%X\n",n,&n); printf("*q=%d q=%X\n",*q,q); }
运行结果:
Input m,n: 123 456
m=123 &m=FFD6 *p=123 p=FFD6 n=456 &n=FFD8 *q=456 q= FFD8
例:通过交换指针变量值按大小顺序输出 main( )
{ int x,y;
int *p, *p1, *p2;
p
x=8; y=6;
&x
p1=&x; p2=&y;
p1
x
if ( x>y ) { p=p1;
实质都是地址值的传递
【例9.7】通过调用函数, 将整型数组的所有元素 加10。参数传递用四种方法实现。
vvooiiddaadddd((iinntt*b*pp[,,]i,innitntntn)n) ) {{ iinntt*i*p;peenndd==pp++nn;;
ffoorr((;i;=pp0<<;ppie<enndd;;;ip+p++++)+)) *b*p[pi+]++===111000;;;
(4) 注意p与a的差别,p是变量a是符号常量,不能给a赋值, 语句a=p; a++; 都amp;a[0]
a[0]
1)下标法,如a[i],p[i]。 p+1,a+1
a[1]
2) 指针法,如*(p+i)或
p+2,a+2
a[2]
*(a+i),其中p是指向数组
a的元素的指针变量。 p+i,a+i
字符指针变量和字符数组的区别
(1) 存储的内容不同: 字符数组存储着字符串的内容, 而字符指针变量 存放的是字符串首元素的地址,不是它的内容。
(2) 分配的内存单元不同: 字符数组分配一段有确定地址的内存。而指针变 量只分配存放地址的内存单元,该指针变量可以 指向一个字符型数据,但若未赋初值,则它并未指向 一个明确的地址。此时它指向的变量并不存在。
功能: (1)定义该指针变量名为指向基类型的指针变量,为 该变量分配存储单元, 其长度等于存储地址的字节数。 (2) 基类型确定用指针变量“间接”存取数据的存储单 元个数和存储形式。该变量只能指向基类型数据。
指针变量的初始化
用 =&变量名 来给指针变量赋初值。选项中的变量名必须
是已定义过的,其类型必须与基类型一致。表示将它对应的地 址值赋给所定义的指针变量。
当p的内容改为2202时, 通过 变量p取出地址2202, 再按此 地址, 存取的就是变量y的内 容。
p就是指针变量
1500
22002 变量p
2200 2202 2204
5
变量x
8
变量y
0
变量z
指针变量的定义
一般形式: 基类型名 *指针变量名
说明: 基类型名: 指针变量所指向的变量的类型名称
指针变量名: 所定义的指针变量的名称 *: 表示它后面的变量名是指针类型
int x; int *p; p=&x; *p=5;
p
x
&x
5 *p
指针变量的运算
1. &: 取地址运算符, 取右边变量的地址 &a是变量a的地址
2. * : 指向运算符(间接访问运算符), 访问指针变量右边所指向的变量。 *p 是指针变量p指向的变量。
说明: “&”和“*”都是单目运算符, 它们的优先级 相同, 按自右而左方向结合。
}}} mmmaaaiiinnn((())) {{{ iiinnntttiii,,,aaa[[[111000]]]==={{{111,2,,22,3,,33,4,,44,5,,55,6,,66,7,,77,8,,88,9,,99,1,,11000}}};;;
ianidnt dt*(q*aq=,1=a0;a);; }}} affafodoodrpdrrpp(d((ri(rrii(=qi==qiin0,nn001,t;1ttf;;0ff(0i)((ii<")<<;"";%111%%0004;44;;diddii+"++""+,++a,,)aa))[[[iii]]])));;;