配色: 字号:
《C语言程序设计教程》第八章指针
2023-05-23 | 阅:  转:  |  分享 
  
第6章 数 组 8.1 指针的基本概念8.2 指针变量的使用与指针运算8.3 指针与数组8.4 字符串与指针8.5 用数组名作
函数参数第八章 指针关键字: 指针变量 数组指针 指针数组 C语言把内存单元地址也看作一种数据类型。由于地址起到指向
某个存储单元的作用,因此常称地址为“指针”。于是把一个地址存放在某个变量里面,那么就称这个变量为指针变量。 那么
在C语言中,如何定义一个指针型变量?在程序中如何使用指针型变量?这些都将是我们关心的问题。 在本章里,读者将学到指针的基本概念、指
针的使用及运算、指针与数组、指向字符串的指针及指针数组等内容。8.1 指针的基本概念 在计算机中,所有的数据
都是存放在存储器中的。 一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符量
占1个单元等。为了正确地访问这些内存单元, 必须为每个内存单元编上号。 根据一个内存单元的编号即可准确地找到该内存单元。内存单元的
编号也叫做地址。根据内存单元的地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。 在C语言中, 允许用一个变量来
存放指针,这种变量称为指针变量,因此,指针变量是专门用于存储其它变量地址的变量。 变量 存储单元地址
存储单元内容 x 2000 3 px
3000 2000 严格地说,一个指针是一个地址, 是一个常量。而一个
指针变量却可以被赋予不同的指针值,是变量。 但是常把指针变量简称为指针。为了避免混淆,我们认为:“指针”是指地址, 是常量,“指针
变量”是指取值为地址的变量, 指针与指针变量的区别,就是变量值与变量的区别。定义指针的目的是为了通过指针去访问内存单元。8.2指针
变量的使用与指针运算 8.2.1指针变量的定义 指针变量和普通变量一样,必须先定义后使用。 格式为:类型说明符 指针变量
名 其中,是指针说明符,用来说明后面的变量是指针类型变量,类型说明符表示指针变量所指向的变量的数据类型。
int p1,p2,p3; /p1,p2,p3均是指向整型变量的指针变量/ 注意:一个指针变量只能指向同类型的变量。
8.2.2指针变量的初始化 在定义指针的同时给指针一个初始值,称为指针变量初始化。初始化时可以将已经定义的变量的地址赋给指
针变量,或者赋空值。 例如: int a,p=&a; /定义了一个指针变量p,并将变量a的地址值赋给了指针
p/注意:指针变量的类型应该与所指地址的变量的数据类型一致。8.2.3指针的两个运算 C语言提供了两种与指针有关的运算符
:取地址运算符 & 和访问地址运算符 格式: &任意变量 取变量的地址 指针变
量 取指针变量所指向的变量的内容 例如: int y=50,p,x;p=&y; 注意:取地址运算符
“&”是取变量的地址而不是取其值。程序文本main(){int a=5,p=&a;printf("%d",p);}结果是:58
.2.4指针变量的引用 一、指针变量赋值 1.用变量的地址给指针变量赋值 例int a,b,p
;p=&a; 2.用相同类型的指针变量赋值 例int a;int p1,p2;p1=&a;p2
=p1; 3.赋空值NULL或0 例char p=NULL 或int p=0; 二、通过指针
变量访问所指变量 通过指针变量访问所指变量时需要经历两步,第一步让指针变量指向被访问的变量;第二步通过指针访问变量;
程序 int a=8,b,p; p=&a; /将指针变量p指向变量a/
b=p; /从指针变量p所指变量a中取内容给变量b/ p=100; /将100存给指针变量所指变
量a/8.2.5指针的算术运算、关系运算 一、指针的算术运算(加减运算) 由于指针是一个整数,所以指针可以加、减
一个整数n,其结果与指针所指对象的数据类型有关。指针变量的值应该增加或减少“n×sizeof(指针类型)”,即指针变量加1,即向后
移动1个位置表示指针指向下一个数据元素的首地址,而不是原地址基础上加1。 例如: float a[10],pa=a;
pa=pa+3; /实际上pa加上34个字节赋给pa,pa指向数组的第三个分量/ 程序main(){int a=10,
b=20,s,t,pa,pb; pa=&a; pb=&b; s=pa+pb; t=pap
b; printf("a=%d\nb=%d\na+b=%d\nab=%d\n",a,b,a+b,ab); printf("s
=%d\nt=%d\n",s,t); }结果是:a=10b=20a+b=30ab=200s=30t=200 二、指针的
关系运算 与普通变量一样,指针可以进行关系运算,指向同一数组的两个指针变量进行关系运算可表示它们所指数组元素之间的关系。
例如: 有下面两个指针变量: p1==p2; /表示p1和p2指向同一数组元素/
p1>p2; /表示p1处于高地址位置/ p1 / 注意:指针在进行关系运算之前,指针必须指向确定的变量或存储区域,即指针有初始值;另外,只有相同类型的指针才能进行比较
。 main(){ int a,b,c,pmax,pmin;printf("input three
numbers:\n"); scanf("%d%d%d",&a,&b,&c); if(a>b)
{ pmax=&a; pmin=&b;} else {pmax=&b; pmin=&
a;} if(c>pmax) pmax=&c;
if(c pmin); }输入 10 30 20↙结果是: max=30 min=108.3指针与数组8.3.1指针与一维数组
指针变量是用于存放地址的变量,可以指向变量,当然也可以存放数组的首地址或数组元素的地址,这就是说,指针变量可以指向数组或数组元素
。数组名是数组的首地址,也就是数组的指针。当指针变量中存放数组的首地址时,则说此指针变量为指向该数组的指针变量。
数组指针变量说明的一般形式为: 类型说明符 指针变量名; 其中,“类型说明符
”表示指针变量所指数组的类型;“”表示其后的变量是指针变量。从数组指针变量的一般形式可看出,指向数组的指针变量和指向普通变量的指
针变量的说明是相同的。 数组名就是指向此数组第1个元素的指针(首地址) 例如: int a[10],p;则p
=a等价于p=&a[0] 数组名(数组的指针)与指向数组首地址的指针变量不同,数组的指针是常量。 p,a,&a[0]均指
向同一单元,它们是数组a的首地址,也是0 号元素a[0]的首地址。应该说明的是p是变量,而a,&a[0]都是常量。 某一元
素的地址:p=&a[i];用指针引用此元素:p等价于a[i] 某一元素的地址:p=&a[i];用指针引用此元素:
p等价于a[i] 数组元素的下标在内部实现时,统一按“基地址+位移” 的方式处理 故表示数组元素的地址可以用
p+i 或 a+i来表示。 表示数组元素的内容可以用下标法 a[i] 指针法 (p+i)
(a+i) 下面举例说明使用不同方法输出数组中的全部元素 程序1(下标法)main(){
int a[10],i; for(i=0;i<10;i++) a[i
]=i; for(i=0;i<5;i++) printf("a[%d]=%-2
d",i,a[i]);}结果是:a[0]=0 a[1]=1 a[2]=2 a[3]=3 a[4]=4程序2(数组指针法:
通过数组名计算元素的地址,找出元素的值)main(){ int a[4],i;
for(i=0;i<4;i++) (a+i)=i; for(i=0;i<4;i
++) printf("a[%d]=%d\n",i,(a+i));} 结果是:a[0]=0a[
1]=1a[2]=2a[3]=3程序3(用指针变量指向元素)main(){ int a[4],i,p;
p=a; for(i=0;i<4;i++) (p+i)=i; for(i=0;i<4;i++)
printf("a[%d]=%d\n",i,(p+i));}结果是:a[0]=0a[1]=1a[2]=2a[3
]=38.3.2指针与二维数组一、二维数组地址的表示方法: 设有整型二维数组b[2][2] int b[2][2],可以看成
是b数组有二行二列,共有4个元素。 b-----二维数组的首地址,即第0行的首地址 b+i-----第i行的首地址 b
[i] ? (b+i)------第i行第0列的元素地址 b[i]+j ? (b+i)+j -----第i行第j列的元素地
址 (b[i]+j) ? ((b+i)+j) ? b[i][j] b+i=&b[i]=b[i]=(a+i)=&a[
i][0], 值相等,含义不同 b+i ? &b[i],表示第i行首地址,指向行 b[i] ? (b+i) ? &b[
i][0],表示第i行第0列元素地址,指向列二、二维数组的指针变量 把二维数组b分解为一维数组b[0]、b[1]
之后,如果设p为指向二维数组的指针变量。则int (p)[2]表示p是一个指针变量,它指向二维数组b或指向第一个一维数组b[0]
,其值等于b、b[0]、&b[0][0]的值。从上面的图中分析可得知“(p+i)+j”是二维数组i行j列的元素的地址,而“((
p+i)+j)”则是i行j列元素的值。 二维数组指针变量说明的一般形式为:类型说明符 (指针变量名)[长度];
其中“类型说明符”为所指数组的数据类型。“”表示其后的变量是指针变量类型。“长度”表示二维数组分解为多个一维
数组时,数组的长度,也就是二维数组的列数。注意:“(指针变量名)”两边括号不可少,若缺少括号则表示是指针数组,意义就完全不同了。
main (){static int a[3][4]={0,1,2,3,4,5,6,7,8,9,10,11};int (p)[4
];int i,j;p=a;for(i=0;i<3;i++)for(j=0;j<4;j++)printf("%3d",((p+
i)+j));}结果是:0 1 2 3 4 5 6 7 8 9 10 118.4字符串与指针一.字符串的表示
形式在C语言中,可以用两种方法访问一个字符串。1、用字符数组存放一个字符串,然后输出该字符串。【程序文本.8.10】main(){
char string[]="I love China! "; printf("%s\n",string);}结果是: I
love China!2、用字符串指针指向一个字符串。 C语言的字符串是以''\0''作结束符的字符序列,一般用字
符数组来存放字符串(即含''\0''的字符数组可以看作字符串) 字符串指针就是字符数组的首地址 如:char
a[]="apple"; char b[]={''s'', ''o '', ''r'', ''r'', ''y''};
定义字符串指针变量的一般形式 char 指针变量 如:char p,q="haha ";
p="this is my bag"; char p,c[8];p=c; 注意:p“
指向”字符串的首地址,不是“存放”字符串。二、字符数组与字符串指针变量比较1、存储内容不同字符数组可以存放字符串,存的是字符;字符
指针变量存的是字符串在内存的首地址;2、赋值方式不同:字符数组只能对各个元素赋值字符指针变量只能赋值一次,赋的是地址。如:char
a[10],p;p="china";3、当没有赋值时字符数组名代表了一个确切的地址;字符指针变量中的地址是不确定的。char
a[10],p;sacanf("%s",a);4、字符数组名不是变量,不能改变其值,而字符指针变量可以改变值。如:char a[
]="I am xiao ming",p=a;p++;5、可以象数组那样用下标形式引用指针变量所指字符串中的字符如:char p
="abcd ";putchar(p[3]);p[2]= ''a'';程序(输出字符串中n个字符后的所有字符)。main(){ ch
ar ps="this is a book"; int n=10; ps=ps+n; printf("%s\n",ps);
}结果是:book在程序中对ps初始化时,即把字符串首地址赋予ps,当ps= ps+10之后,ps指向字符"b",因此输出为"bo
ok"。8.5用数组名作函数参数 在前面章节中曾经介绍过用数组名作函数的实参和形参的问题。在学习指针变量之后就更容易理解
这个问题了。 数组名就是数组的首地址,实参向形参传送数组名实际上就是传送数组的地址, 形参得到该地址后也指向同一数组。 这就好象同
一件物品有两个彼此不同的名称一样。同样,指针变量的值也是地址, 数组指针变量的值即为数组的首地址,当然也可作为函数的参数使用。
归纳起来,如果有一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种: 1、形参和实参都是数组名。 2、实参、形参都用指针变量。 3、实参为指针变量,形参为数组名。4、实参数组,形参用指针变量本章小结 一、 变量的指针和指向变量的指针变量变量的指针即变量的地址。指向变量的指针变量即用来存放变量地址的地址变量。 (一) 指针变量的定义 形式:类型标识符 标识符 如:int pointer; (二)指针变量的引用 两个有关的运算符: & 取地址运算符 &a 就代表变量a的地址 指针运算符   a 就代表变量a的值二、 数组的指针和指向数组的指针变量 数组的指针指数组的起始地址,数组元素的指针指数组元素的地址。三、 字符串的指针和指向字符串的指针变量 (一)字符串的表示形式c中字符串有两种表示形式:一种是数组,一种是字符指针 (二)字符串指针作函数参数实际上字符串指针就是数组的首地址。 (三)字符指针变量与字符数组的区别
献花(0)
+1
(本文系昵称1689447...首藏)