Presentation is loading. Please wait.

Presentation is loading. Please wait.

第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习.

Similar presentations


Presentation on theme: "第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习."— Presentation transcript:

1 第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习

2 指针极大地丰富了C语言的功能,学习指针是学习C语言中最重要的一环,能否正确理解和使用指针是我们是否掌握好C语言的一个标志。指针是C语言中广泛使用的一种数据类型。 运用指针编程是C语言最主要的风格之一。利用指针变量可以表示各种数据结构,能很方便地使用数组和字符串,并能象汇编语言一样处理内存地址,从而编出精练而高效的程序。

3 ● 8.1 指针简介 1.指针的基本概念 在计算机中,所有的数据都是存放在存储器中的。一般把存储器中的一个字节称为一个内存单元,不同的数据类型所占用的内存单元数不等,如整型量占2个单元,字符型占1个单元等,在第2章中已有详细的介绍。 为了正确地访问这些内存单元,必须为每个内存单元编上号,根据一个内存单元的编号即可准确地找到该内存单元,内存单元的编号也叫做地址。既然根据内存单元的编号或地址就可以找到所需的内存单元,所以通常也把这个地址称为指针。内存单元的指针和内存单元的内容是两个不同的概念, 1000 10 P x

4 2.指针变量的类型说明 指针变量定义的一般形式为: 类型说明符 *变量名; 其中,“*”表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示本指针变量所指向的变量的数据类型,即指针变量的基类型。 下面对指针变量作几点说明: (1)指针变量名前的“*”表示该变量为指针变量,而指针变量名不包含该“*”。 (2)一个指针变量只能指向同一类型的变量。 (3)指针变量中只能存放地址,而不能将数值型数据赋给指针变量。 (4)只有当指针变量中具有确定地址后才能被引用。 (5)与一般的变量一样,也可以对指针变量进行初始化。 例如: int *p1; 表示p1是指向整型变量的指针变量

5 8.2 指针变量的操作 指针变量可以指向任何一种数据类型,例如可以指向基本类型的变量,也可以指向数组、结构体、共用体以及另外的指针等。指针变量同普通变量一样,使用前需要定义、赋初值,通过指针还可以引用存储单元,指针指向不同的变量类型其操作方法也有所不同。 8.2.1 指针变量的赋值 指针变量同普通变量一样,使用之前不仅要定义说明,而且必须赋予具体的值。指针变量的赋值只能赋予地址, 决不能赋予任何其它数据,否则将引起错误。 在C语言中,变量的地址是由编译系统分配的,用户不知道变量的具体地址。C语言中提供了地址运算符&来表示变量的地址。

6 1.给指针变量赋地址 一般形式为: &变量名; 如&a变示变量a的地址,&b表示变量b的地址,变量a、b必须预先说明。设有指向整型变量的指针变量p,如要把整型变量a 的地址赋予p可以有以下两种方式: (1)指针变量初始化的方法 : int a; int *p=&a; (2)赋值语句的方法 : int a,*p; p=&a; 2.给指针变量赋“空”值 p= NULL; 或 p=‘\0’; 或 p=0; 这时,指针p并不是指向地址为0的存储单元,而是具有一个确定的值“空”。

7 8.2.2 指针变量的运算 指针变量可以进行某些运算,但其运算的种类是有限的,它只能进行赋值运算和部分算术运算及关系运算。 1. 指针运算符 (1) 取地址运算符(&) 取地址运算符“&”是单目运算符,其结合性为自右至左,其功能是取变量的地址。在scanf函数及前面介绍指针变量赋值中,我们已经了解并使用了“&”运算符。 (2)取内容运算符(*) 取内容运算符“*”是单目运算符,其结合性为自右至左,用来表示指针变量所指的存储单元中的值。

8 程序演示 例8.1 通过指针输出变量的值 void main() { int a=5,*p=&a; printf ("a=%d",*p);
getch(); } 程序演示

9 2. 指针变量的运算 (1) 赋值运算 指针变量的赋值运算有以下几种形式: ① 指针变量初始化赋值,int a, *pa=&a; ② 把一个变量的地址赋予指向相同数据类型的指针变量。 int a,*pa; pa=&a; /* 把变量a的地址赋予整型指针变量pa */ ③ 把一个指针变量的值赋予指向相同类型变量的另一个指针变量。如: int a,*pa=&a,*pb; pb=pa; /* 把a的地址赋予指针变量pb,pa、pb指向同一个存储单元 */ pa,pb均为指向整型变量的指针变量,可以相互赋值。 ④ 把数组的首地址赋予指针变量。 例如: int a[5],*pa; pa=a; ⑤ 把字符串的首地址赋予指向字符类型的指针变量。 例如: char *pc; pc="CHINA";

10 (2) 指针变量移动(加减一个整数) 对于指向连续的存储单元的指针变量,可以加上或减去一个整数n(运算后的值不要超出连续的存储单元的范围,否则没有意义)。设pa是指向数组a的指针变量,则pa+n,pa-n,pa++,++pa,pa--,--pa 运算都是合法的。 指针变量加或减一个整数n的意义是,把指针指向的当前位置向前或向后移动n个位置。应该注意,数组指针变量向前或向后移动一个位置和地址加1或减1 在概念上是不同的。因为数组可以有不同的类型,各种类型的数组元素所占的字节长度是不同的。如指针变量加1,即向后移动1 个位置,表示指针变量指向下一个数据元素的首地址,而不是地址值加1。 例如: int a[5],*pa=a; pa=pa+2; /* pa指向数组元素a[2],即pa的值为&a[2] */

11 (3) 两个指针变量之间的运算只有指向同一连续存储单元的两个指针变量之间才能进行, 否则运算毫无意义。
以指向数组元素的指针为例: ① 两指针变量相减 两个指针变量相减所得之差是两个指针所指数组元素之间相差的元素个数。实际上是两个指针值(地址) 相减之差再除以该数组元素的长度(字节数)。 例如:float b[10],*pf1,*pf2; 设pf1和pf2 是指向同一浮点数组b的两个指针变量, pf1的值为2010H,pf2的值为2000H,而浮点数组每个元素占4个字节,所以pf1-pf2的结果为(2010H-2000H)/4=4,表示pf1和 pf2之间相差4个元素,即pf1-pf2=4。 两个指针变量不能进行加法运算。 ② 两指针变量进行关系运算 指向同一连续存储单元的两指针变量进行关系运算可表示它们所指数组元素之间的关系。

12 程序演示 例8.2 指针应用:通过指针求两个数的和与积。 void main() {
例8.2 指针应用:通过指针求两个数的和与积。 void main() { int a=10,b=20,s,t,*pa,*pb; /* pa,pb为整型指针变量*/ pa=&a; /* pa指向变量a */ pb=&b; /* pb指向变量b */ s=*pa+*pb; /*求a+b之和,(*pa就是a,*pb就是b)*/ t=*pa**pb; /*求a*b之积*/ printf("a=%d b=%d a+b=%d a*b=%d\n",a,b,a+b,a*b); printf("s=%d t=%d\n",s,t); getch(); } 程序演示

13 8.3 数组与指针  一个变量对应一个起始地址,一个数组包含若干个数组元素,这若干个数组元素在内存中占用的存储单元的地址是连续的。引用数组元素可以用下标法(如a[1]),也可以用指针法,即通过指向数组元素的指针引用数组元素,使用指针法能使目标程序质量更高(占内存少,运行速度快)。 8.3.1 一维数组与指针 引入指针变量后,就可以用两种方法来访问数组元素了。 第一种方法为下标法,即用a[i]形式访问数组元素,在第6章中介绍数组时都是采用这种方法。 第二种方法为指针法,即采用*(p+i)形式,用间接访问的方法来访问数组元素。

14 程序演示 例8.3 通过指针引用数组元素 void main() { int a[5],i,*pa;
例8.3 通过指针引用数组元素 void main() { int a[5],i,*pa; pa=a; /* pa指向数组a的首地址,即&a[0]*/ for(i=0;i<5;i++) *pa=i; /* 给指针pa指向地址赋内容,即给a[i] 赋值*/ pa++; /* 指针加1,即指针pa指向下一个数组元素 */ } pa=a; /* 指针pa回到数组a的首地址 */ printf(“a[%d]=%d\n”,i,*(pa+i)); /* 通过指针pa输出数组 a的所有元素值*/ 程序演示

15 8.3.2 字符串与指针 在C语言中,既可以用字符数组表示字符串,也可用字符指针变量来表示;引用时,既可以逐个字符引用,也可以整体引用。 对指向字符变量的指针变量应赋予该字符变量的地址。如: char c,*p=&c;表示p是一个指向字符变量c的指针变量。而: char *s="C Language";则表示s是一个指向字符串的指针变量,把字符串的首地址赋予s。 1. 逐个引用 例8.4 使用字符指针变量表示和引用字符串。 void main() { char *string=”I am a chinese.”; for(; *string!=’\0’; string++) printf(“%c”, *string); printf(“\n”); getch(); } 程序演示

16 程序演示 2. 整体引用 例8.5 采取整体引用的办法,改写例8.4。 /*程序功能:使用字符指针变量表示和引用字符串*/
void main() { char *string=”I am a chinese.”; printf(“%s\n”,string); getch(); } 程序演示

17 程序演示 8.3.3 用数组名作函数参数 在指针做函数的参数的传递过程中,实参要传变量的地址,形参要定义成指针变量。
例8.6 指针做函数的参数 float aver(float *pa); void main() { float score[5],av,*sp; int i; sp=score; printf("\ninput 5 scores:\n"); for(i=0;i<5;i++) scanf("%f",&score[i]); av=aver(sp); printf("average score is %5.2f",av); } float aver(float *pa) { int i; float av,sum=0; for(i=0;i<5;i++) sum=sum+*(pa+i); /* 求和 */ av=sum/5; /* 求平均值 */ return av; } 程序演示

18 8.4 二维数组与指针 8.4.1 二维数组的地址 假设一个二维数组int s[3][4]。
s数组是一个3x4(3行4列)的二维数组。可以将它想象为一个矩阵(详见第6章)。各个数组元素按行存储,即先存储s[0]行各个元素(s[0][0],...s[0][3]),再存储s[1]行各个元素(s[1][0],...s[1][3]),最后存储s[2]行各个元素(s[2][0],...s[2][3])。 二维数组s可以看成由三个一维数组作为数组元素的数组: 在这个一维数组中每个数组元素表示为:s[0],s[1],s[2]。 二维数组任何一个元素s[i][j]的地址可以表示为: (1)&s[i][j] (2)s[i]+j (3)*(s+i)+j (4)&s[0][0]+4*i+j (5)s[0]+ 4*i+j

19 8.4.2 行指针变量 行指针变量即指向由n个元素组成的一维数组的指针变量。 1.定义格式
类型说明符 (*指针变量)[n]; /* n是常量表达式 */ 注意:“*指针变量”外的括号不能缺,否则成了指针数组(即数组的每个元素都是一个指针──指针数组)。 2.赋值 行指针变量 = 二维数组名; 若有以下定义: int a[3][4],(*p)[4]; p=a; 可以通过以下形式来引用a[i][j]: (1)p[i][j] /* 与a[i][j] 对应 */ (2)*(p[i]+j) /* 与*(a[i]+j)对应 */ (3)*(*(p+i)+j) /* 与*(*(a+i)+j) 对应 */ (4)(*(p+i))[j] /* 与(*(a+i))[j]对应 */

20 8.4.3指针数组 1.定义格式 指针数组说明的一般形式为: 类型说明符 *数组名[数组长度] 其中类型说明符为指针值所指向的变量的类型。
类型说明符 *数组名[数组长度] 其中类型说明符为指针值所指向的变量的类型。 2.赋值 若有以下定义: int a[3][4], *p[3]; 让p指向数组a需要用以下语句: for(i=0;i<3;i++) p[i]=a[i]; 可以通过以下形式来引用a[i][j]: (1)p[i][j] /* 与a[i][j] 对应 */ (2)*(p[i]+j) /* 与*(a[i]+j)对应 */ (3)*(*(p+i)+j) /* 与*(*(a+i)+j) 对应 */ (4)(*(p+i))[j] /* 与(*(a+i))[j]对应 */

21 ●本章小结 1、指针与数组 2、 指针的运算 (1)取地址运算符&:求变量的地址。 (2)取内容运算符*:表示指针所指变量的值。
(3)赋值运算 (4)加减运算 对指向数组、字符串的指针变量可以进行加减运算,如p+n,p-n,p++,p--等。对指向同一数组的两个指针变量可以相减。 (5)关系运算 指向同一数组的两个指针变量之间可以进行大于、 小于、 等于比较运算。指针可与0比较, p==0表示p为空指针。

22 ●本章练习 1、教材第8章课后习题。 2、上机练习指针的定义、赋值、引用等。


Download ppt "第8章 指针 ● 8.1 指针简介 ● 8.2 指针变量的操作 ● 8.3 数组与指针 ● 8.4 二维数组与指针 ●本章小结 ●本章练习."

Similar presentations


Ads by Google