计算机精品课件:第7章-指针.ppt

上传人(卖家):金钥匙文档 文档编号:435647 上传时间:2020-04-05 格式:PPT 页数:160 大小:1.14MB
下载 相关 举报
计算机精品课件:第7章-指针.ppt_第1页
第1页 / 共160页
计算机精品课件:第7章-指针.ppt_第2页
第2页 / 共160页
计算机精品课件:第7章-指针.ppt_第3页
第3页 / 共160页
计算机精品课件:第7章-指针.ppt_第4页
第4页 / 共160页
计算机精品课件:第7章-指针.ppt_第5页
第5页 / 共160页
点击查看更多>>
资源描述

1、1,第7章 指针,7.1 地址和指针 7.2 指针变量的引用 7.3 指针与数组 7.4 指针与字符串 7.5 指针与函数 7.6 指向指针的指针 7.7 main函数的参数,2,指针的6个主要用途: 可以有效地表示复杂的数据结构; 在调用函数时可以得到多于1个的值; 能方便地使用字符串; 有效而方便地使用数组; 能动态地分配内存; 能直接处理内存地址;,3,指针不仅是C语言中最有用的特性之一, 也是最危险的特性。 尽管指针概念本身比较简单, 但用指针来构成的动态数据结构在语义上可能 却是含糊的,这也是指针的致命弱点。 而更常见的则是对指针的错误使用, 例如,没有初始化的指针可能会导致系统瘫痪

2、。,4,7.1.1 变量的地址和变量的值 数据在内存中是如何存储和读取的?,在源程序中通过变量名对内存单元进行存取操作; 在编译后的程序中已将变量名转换为变量的地址, 对变量值的存取是通过地址进行的。,7.1 地址和指针,5,对地址的访问方式,1)“直接访问”方式 按变量地址存取变量值的方式,语句为: i = 3;,7.1.2 间接寻址,6,2)“间接访问”方式 把变量的地址存放在另一个变量中。,语句为: i_pointer = &i;,7,2000,i,3,把3送到变量 i 所标志的单元中,2000,i_pointer,2000,i,3,把3送到变量 i_pointer 所指向的单元中,间接

3、访问,直接访问,8,指向是通过地址来体现的; 或称地址指向该变量单元;,因此在C语言中,把地址称为“指针” ; 一个变量的地址称为该变量的指针;,指向的概念,7.1.3 指针变量的定义,9,若一个变量是专门用来存放另外一个变量的地址(即指针)的,则称该变量为“指针变量” ; 指针变量的值(即指针变量中存放的值)是指针(地址)。,10,重要的概念 变量的指针和指向变量的指针变量,用*表示指向和被指向的关系,直接寻址和间接寻址: 1) i = 3 ; 2) *i_pointer=3 ;,*i_pointer是被 i_pointer所指向的变量,设:i_pointer 是指针变量,如何表示这种指向和

4、被指向的关系呢?,11,定义一个指针变量的一般形式: 基类型 *指针变量名 例如: int *point_1 , *point_2 ;,定义指针变量 指针变量也是变量,指针变量的作用是用来指向某个目标变量的。,12,例:如何使一个指针变量指向某个确定的变量 point_1 = ,通过赋值的方法, 把变量i的地址存放到指针变量point_1中, 使point_1指向变量 i ;,13,在定义指针变量时注意: 1)“ * ”是指针说明符,表示该变量为指针型变量 指针变量名是 point_1 而不是 *point_1,2)定义指针变量时必须指定基类型; 因为在进行指针运算时,要根据指针类型决定指针移

5、动的字节数; 一个指针变量只能指向同一个类型的变量; 如只有整型变量的地址才能放到整型的指针变量中,14,指针变量中不能存放任何其他非地址类的数据,7.2. 指针变量的引用,15,例7.1 定义和引用指针变量,void main() int a , b ; int *pointer_1 , *pointer_2 ; a=100 ; b=10 ; pointer_1 = ,引用时:存取内容运算符 用来表示某个被指向变量,定义时:说明符 表示可以指向某个变量,利用指针变量的指向实现对目标变量的等价访问,16,关于指针变量: 1)在定义时: *pointer_1 和 *pointer_2 表示定义了

6、两个指针变量:pointer_1、pointer_2,17,2)在引用时: *pointer_1 和 *pointer_2 则代表变量a和b, 即被 pointer_1 和 pointer_2 所指向的变量。,*在定义时代表指向,在引用时代表被指向。,18,3)在赋值时: 可以写成 pointer_1 = ,因为 a 的地址可以赋给指针变量pointer_1, 而不能赋给 *pointer_1 (即变量 a )。 即地址只能赋给指针变量。,19,1) 若有 &*pointer_1 因此 &*point_1相当于 &a,即变量 a 的地址。,与指针有关的两个运算符是: & :取地址运算符 ; *

7、 :存取内容运算符;(间接访问运算符),7.2.1 指针运算符(单目、2级、右向左),20,若又执行 pointer_2 = ,执行前,执行后,21,2) * 若有 *&a 则 *&a 相当于被 &a 所指向的变量 a。,即 *&a 和 *pointer_1 的作用相同,等价于变量 a,22,3)(*pointer_1)+; 相当于:*pointer_1+; 相当于:*(pointer_1+) 相当于:a+,23,例7.3 输入a和b两个整数,按先大后小的顺序输出,void main() int *p1 , *p2 , *p , a , b ; a=10 ; b=100 ; p1 = ,指针变

8、量p1和p2的值改变了,即所指向的变量改变了,而被指向的变量的值并未改变。,24,7.2.2 指针运算,即地址运算,运算对象是指针(地址); 指针运算的目的是移动指针; 以所指目标对象的存储空间为单位进行移动;,1.指针算术运算 (1)整数加减和自加减 +p、p+、p+=5、p=p+5、p+5 或 -p、p-、p-=5、p=p-5、p-5 (2)指针相减 q-p 相差n个元素的距离,25,2.指针关系运算 (1)两个指针值是否相等: =、!= (2)两个指针值的大小比较: 、=、= 结果为逻辑值“真”或“假”,26,7.2.3 指针变量作函数参数,指针变量作为函数的参数,它的作用是把一个变量的

9、地址传送到另一个函数中。,27,例7.4 用指针类型的数据作函数参数,void main() int a , b ; int *pointer_1 , *pointer_2 ; a=10 ; b=100 ; pointer_1 = ,28,swap( int *p1 , int *p2) int temp ; temp = *p1 ; *p1 = *p2 ; *p2 = temp ; ,虚实结合后形参p1的值为&a,即变量a的地址,而*&a是被&a指向的变量a。 被指向的变量名a、b没变,而是被指向的变量a、b的值改变了。,29,swap( int x , int y ) int temp ;

10、 temp = x ; x = y ; y = temp ; ,主函数中的a,b并未互换,即由于单向的值传递方式,使得形参值的改变无法传给实参,为使在被调函数中改变了的变量值能被主调函数使用,应该用指针变量作为函数参数,在函数执行过程中使指针变量所指向的变量值发生变化,在函数调用结束后,这些变量值的变化依然保留下来,在主调函数中使用这些改变了值。,30,不能企图通过改变指针形参的值而使指针实参的值改变。 因为实参变量和形参变量之间的数据传递是单向的“值传递”方式,指针变量作函数参数也要遵循着个规则。 swap( int *p1 , int *p2) int *p ; p = p1 ; p1 =

11、 p2 ; p2 = p ; ,p是指针变量,p1相当于&a,因此把地址赋给指针变量是允许的 但形参指针变量值的改变并不能传回实参,31,7.3 指针与数组,数组名是一个地址常量 用数组名加下标访问元素的方式变址访问方式; 用于表示下标的一对方括号“ ”是变址运算符;,由指针运算方法,通过数组名访问数组中指定元素: a 等价于 &a0, 相当于 a指向a0。 a+1 等价于 &a1, 相当于 a+1指向a1。 a+2 等价于 &a2, 相当于 a+2指向a2。 a+3 等价于 &a3, 相当于 a+3指向a3。,图7_7 数组名与元素的关系,图7_8 变址访问元素的等价关系,33,7.3.1

12、数组元素的指针,一个数组包含若干元素; 每个元素都在内存中占用存储单元; 每个单元都有地址; 指针变量可以指向变量, 指针变量也可以指向数组和数组元素(把数组起始地址或某一元素的地址放到一个指针变量中); 数组的指针是指数组的起始地址, 数组元素的指针是数组元素的地址。,34,例如: int a10 ; int * p ; p=,若数组为整型, 指针变量也应为整型,数组名代表数组首地址,但数组名a不代表整个数组,p=a的作用是把a数组的首地址赋给指针变量p,而不是把数组a各元素的值赋给p。,p = a ;,定义数组元素的指针,35,在定义指针变量时可以赋初值: int * p =,将a的首地址

13、赋给指针变量p, (注意:不是赋给*p)。,36,若p已定义为指针变量,并已给它赋了一个元素地址,此时有语句: *p = 1 ;,表示:为p当前所指向的元素赋值(值为1)。 再有语句: p+1; 则表示指向下一个元素,而不是p的值简单地加1。,引用数组元素时指针的运算,37,例如:数组元素是实型,每个元素占4个字节; 则p+1意味着使p的值(地址)加n个字节, 以使它指向下一个元素, 此时,p+1所代表的地址实际上是p+1xd。 其中:d是一个数组元素所占的字节数。 (设:对整型:d=4;对实型:d=4;对字符型:d=1),38,39,说明:设p的初值为&a0。 1)p+i 和a+i 就是ai

14、的地址,它们指向a数组 的第i个元素; 例如: p+9 或 a+9 的值是&a9,它指向a9。,2)*(p+i)或*(a+i)是被p+i或a+i所指向的数组元素(即被指向的元素ai); 例如:*(p+5)或*(a+5)就是a5,即: *(p+5)=*(a+5)=a5,40,实际上在编译时,对数组元素 ai就是处理成 *(a+i),即按数组首地址加上相对位移量得到要找的元素地址,然后找出该单元的内容。,可见: 实际上是变址运算符, 即ai按a+i计算地址。,例如: 设 a 为整型数组,首地址为2000 则 a3的地址为 2000+3x4=2012 然后从2012中取出元素的值,41,因此: 3)

15、指向数组元素的指针变量也可以带下标。 例如: p i = *(p+i) = a i ,p并不是指针数组。 这里 pi 是先按 p+i 计算地址,然后找出此地址单元中的值。 注意与p+i的区别。,42,由上可见,引用一个数组元素, 可以有以下2种方法(3种形式): 1)下标法:如 a i 形式; 2)指针法:如 *(a+i)或 *(p+i)、pi;,其中:*(a+i) 和 *(p+i) 是元素,而 p 是指向数组的指针变量。,通过指针引用数组元素,43,(1)下标法: void main() int i ;int a10 ; for( i=0;i10;i+) scanf(“%d”, ,先通过数组

16、名计算数组元素地址, 然后从中找出元素的值。,44,(2)地址法: void main() int a10 ; int i ; for( i=0;i10;i+) scanf(“%d”, i是变量,虽然看起来像是指针,但仍然是先通过数组名计算数组元素地址,然后从中找出元素的值。,45,(3)指针法: 用指针变量指向数组元素: void main() int a10 ; int *p , i ; for( i=0;i10;i+) scanf(“%d”, ,a+10相当于a10 p+相当于p+1, *p 是被指向的元素,46,对3种方法的比较: 1)方法1、2的执行效率相同。C编译将ai转换为*(a

17、+i)处理,此种方法在寻找元素时要费时; 2)方法3速度快,用指针变量直接指向元素,不必每次重新计算地址; 3)方法1(下标法),比较直观, 方法2(地址法)和方法3(指针变量法)不容易判断出当前处理的是哪一个元素。,47,使用指针变量时要注意: 1)指针变量可以实现使本身的值改变; 例如:p+ 使 p 的值不断改变。 2)注意不能使 a 变化,因为 a 只代表数组的首地址,而首地址是不变的(常量)。 例如:for(p=a;a(p+10);a+),3) 要注意指针变量当前的值。,48,例:7.6 通过指针变量输入/出a数组的10个元素。,在第一个循环后,p 指向数组的末端,在第二个循环开始时,

18、p 的起始值不是&a0,而是a+10,应在第二个循环前增加一个语句p=a ;,void main() int *p ; i ; a10 ; p=a ; for(i=0 ; i10 ;i+) scanf(“%d”,p+) ; printf(“n”) ; for(i=0 ;i10 ;i+ ,p+) printf(“%d” , *p ) ; ,p=a;,49,4)可以用 p 指向当前数组的元素,但实际上p可以指向数组以后的内存单元。 因此在上例程序中引用数组元素 a10时,编译系统并不认为非法,而是把它按照 *(a+10)处理,即先找出(a+10)的值(是一个地址),然后找出它指向的单元的内容。,5

19、0,5)注意对指针变量的运算。 p = a ; p+; (或p+=1;) printf(“%d”,*p);即输出 a1的值。, 若写为:printf(“%d”,*p+) ;,此时 + 和 * 优先级相同,结合方向为自右向左 因此等价于 *(p+)。 作用是先得到 p 指向的变量的值(即 *p), 然后再使 p+1 送 p 。(先用后加),51,注意 *(p+)与 *(+p)是不同的 *(p+)是先取*p的值,后使p+1; *(+p)是先使p+1,再取*p的值。 (*p)+表示p所指向的元素值加1,即(a0)+。 例如若 a0=3 , 则(a0)+的值4。,52,如果 p 当前指向 a 数组中的

20、第 i 个元素, 则: *(p-) 相当于 ai- , 先对 p 进行 * 运算,再使 p 自减; *(+p) 相当于 a+i , 先使 p 自加,再作 * 运算; *(-p) 相当于 a-i, 先使 p 自减,再作 * 运算。,53,7.3.2 指向二维数组的指针,数组a的二维逻辑结构和 一维物理存储结构 指向二维数组的指针变量 与指向变量的指针变量间并无本质上的区别,图7.11 二维数组的物理结构,54,例7.7 指向二维数组元素的指针变量。 #include #define N 3 #define M 4 int main() int *p; int aNM=3,5,7,9,10,20,

21、30,40,100,200,300,400; for(p= ,用指针变量访问二维数组元素,55,1. 二维数组的地址,用数组名访问二维数组元素,a,2000,56,a0,a1,a2,一维数组a,行地址,列地址,元素地址,57,几个概念: 1)关于行的地址 a 二维数组名,整个二维数组的首地址; a+i 指向二维数组的第i行的首地址; 因此称数组名为行指针。,a0,a1,a2,a,a+1,a+2,58,(1)在一维数组时,是先找出(a+0)的值(此值地址),然后找出它所指向的元素的值(单元的值)。,注意: ai 等价于 *(a+i),(2)在二维时: a0 二维数组中的0行,一维数组名; 二维数

22、组中第0列元素的地址:&a00。,因此称:a0的值为地址:&a00,注意a0(或a+i)只代表数组名(并不是一个实际的变量),本身不占实际内存单元,因此也不存放元素的值,它只是一个地址;,59,(3)此时理解*(a+i)则不象在一维数组时是元素的值(或单元的内容),而是一个地址,即: *(a+i) 的 值 也是 地址 (4)因此:*(a+i) 等价于 a i (是地址),60,2)关于列的地址 同理: a0+0 代表第0行、第0列的地址:&a00。 ai+j 代表第i行、第j列的地址:&aij。,由上述可知: ai+j 等价于 *(a+i)+j 等价于 &aij,61,3)关于元素的值 由于

23、ai+j 等价于 *(a+i)+j 是地址, 因此用指针法表示时: *(ai+j) 就是被指向的元素的值。 因为列的地址用 *(a+i) 表示, 所以:*(*(a+i)+j) 也就是元素 aij的值。,特别提醒: *(a+i) 等价于 ai。,62,4)关于指针的指向 二维数组名是指向行的,如 a+i 一维数组名是指向列的,如 ai+j,由于: *(a+i) 等价于 ai 因此,在行指针前加“*”,就转换为列指针, 如:*(a+1)指向a数组第1行第0列的元素; 在列指针前加“&”,就转换为行指针, 如:&a0 等价于 &*a ,指向二维数组的0行。,二维数组: a 数组名 a+i 行地址 a

24、i 一维数组名,是地址 *(a+i)=ai= *(a+i)+j 第j列元素的地址 *(*(a+i)+j) 第i行第j列元素的值,一维数组: a 数组名 a+i=p+i 元素ai的地址 ai 元素名(值) *(a+i) 元素(值) *(a+i)= *(p+i)=ai 是a+i或p+i所指向元素的值, 即ai。 *(p+i)和ai 无条件等价,64,例7.8 输出二维数组有关的值,指向行。 输出0行首地址,加“*”后指向列。 输出0行0列元素地址,#define FORMAT “%d,%dn” void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23;

25、printf ( FORMAT , a , *a ) ;,65,printf ( FORMAT , a0 , *(a+0) ) ; printf ( FORMAT , ,一维数组名指向列;二维数组名指向行,加*后指向列。,66,#include void main() int a55=1,2,3,4,5; int i=2; printf(“%otn“, ,67,例:输出数组元素的值,void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p;,12代表12个元素的字节数。,(1)指向二维数组元素的指针变量,for(p=a0;pa0+12

26、;p+) if(p-a0)%4=0) printf(“n”) ; printf ( “%4d”, *p ) ; ,指向二维数组的指针变量,就是指向普通目标变量的指针变量,68,计算某个指定元素a i j 在数组中的相对位置的公式为: i*m+j 其中m为二维数组的列数。 可以用 (p+i*m+j)表示aij元素在数组中的相对地址。,69,(2)指向由m个元素组成的一维数组的指针变量,使p不是指向目标变量,而是指向一个包含m个元素的一维数组。 此时如果p先指向a0 (即p=&a0) 则p+1不是指向a01,而是指向a1。 p的增值以一维数组的长度为单位。,指向行的指针变量的定义形式: 基类型 (

27、*p)m;,70,例7.9 输出二维数组任一行任一列元素的值,p是一个指针变量,它指向包含4个元素(列)的一维数组。,void main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int (*p)4 ,i ,j ; p=a ; scanf(“i=%d,j=%d”,&i,&j); printf(“a%d,%d=%dn”,i,j,*(*(p+i)+j);,p+i是二维数组a的i行地址,因此p不能指向某个元素,*(p+2)+3是a的第2行第3列元素地址,是指向列的指针;*(*(p+2)+3)是a23的值。,71,数组的地址可以作为函数参数传递。 (地址作参数

28、见例7.4) 用指针变量作形参来接受实参数组名传递来的地址时, 有2种情形: 1)用指向变量的指针变量; (列指针) 2)用指向一维数组的指针变量。(行指针),7.3.3 指向数组的指针作函数参数,72,例7.10 有3名学生,各学4门课,计算总平均分数。,void main() void average(float *p,int n); float score34=65,67,70,60, 80,87,90,81,90,99,100,98; average(*score,12); ,指向变量的指针变量score0,是一个地址,指向元素score00,一维数组,73,void average(

29、float *p,int n) float *p_end ; float sum=0,aver ; p_end=p+n-1; for( ; p=p_end ; p+) sum=sum+(*p) ; aver=sum/n ; printf(“average=%5.2fn” ,aver);,形参p被声明为指向实型变量的指针变量。用p指向二维数组的各个元素,p每加1,就改为指向下一个元素。,74,void main() int array10 ; f(array,10) ; ,f( int arr , int n ) ,用数组名作参数时,只传递首地址,因此实参arrayn和形参arrn是同一单元。所

30、以形参数组中各元素的值发生变化,则实参数组元素的值随之变化,用数组名作函数参数,75,由于实参数组名代表该数组的首地址,而形参是用来接收从实参传来的数组首地址的; 因此:形参必须是一个指针变量(只有指针变量才能存放地址); 实际上,编译系统都是把形参数组作为指针变量来处理的。 例如: f ( int arr , int n ) 在编译时处理成: f ( int *arr , int n ),76,&array0,arr,array i arr i,array0 arr0,arr,array,arr+i,*arr,*(arr+i),77,当 arr 接收了实参数组的首地址后: arr 指向实参的

31、首地址,即指向了 array0 ; 因此: *arr 就是 array0 的值。 由此可以看出: arr0 、 *arr 、 array0 都是数组 array 的第0个元素。 即: arr i 、*(arr+i)是无条件等价的。,78,实参数组代表一个固定的地址(即:指针型常量) 形参数组并不是一个固定的地址值。,形参数组作为指针变量: 在函数调用开始时,它的值等于实参数组起始地址,但在函数执行期间,它可以被再赋值。 例如: f(arr , int n ) printf(“%dn” , *arr ) ; arr=arr+3 ; printf(“%dn” , *arr ) ; ,79,f (

32、int x , int n) ,1)形参和实参都用数组名,如: void main() int a10 ; f ( a , 10); ,用地址作函数参数有4种形式,一维数组有4种函数声明和调用形式,80,2)实参用数组名,形参用指针变量,如: void main() int a10 ; f ( a , 10); ,f ( int *x , int n) ,81,3)实参和形参都用指针变量,如: void main() int a10 , *p ; p = a ; f ( p , 10) ; ,f ( int *x , int n) ,82,4)实参为指针变量,形参为数组名,如: void ma

33、in() int a10 , *p ; p = a ; f ( p , 10) ; ,f ( int x , int n) ,83,例 将数组arr中 n 个整数按相反顺序存放。 如下图:,84,算法: 先将arr0与arrn-1对换,再将arr1与arrn-2对换 直到将 arr(n-1)/2与arrn-int(n-1)/2)-1对换,设计过程: (使用循环) 设2个位置指示变量 i=0 ,j=n-1 。 将 arr i 与 arr j 交换; 然后使 i +1 ; 使 j 1 , 再将 arr i 与 arr j 对换 ; 直到 i=(n-1)/2 为止 。,85,void main()

34、int i ,arr10=3,7,9,11,0,6,7,5,4,2 ; for( i=0 ; i10 ; i+) printf(“%d , ”,arr i ) ; printf(“n”) ; inv ( arr , 10 ) ; for( i=0 ; i10 ; i+) printf(“%d , ”,arr i ) ; printf(“n”) ; ,形式1:实参为数组名,86,void main() int i , arr10 , *p=arr ; for ( i=0 ; i10 ; i+ , p+ ) scanf ( “%d” , p ) ; printf(“n”) ; p=arr ; in

35、v ( p ,10 ) ; for ( p=arr ; parr+10 ; p+ ) printf( “%d” , *p ) ; printf(“n” ) ; ,形式2:实参为指针变量,87,void inv ( int x , int n ) ; int temp , i , j , m=(n-1)/2 ; for( i=0 ; i=m ; i+) j=n-1-i ; temp=x i ; x i =x j ; x j =temp ; return ;,形式1:形参为数组名,88,void inv(int *x,int n) ; int *p , temp , *i , *j , m=(n-

36、1)/2 ; i = x ; j = x+n-1 ; p = x+m ; for( ; i=p ; i+ , j - - ) temp = *i ; *i=*j ; *j=temp ; return ;,定义指针变量,引用指针变量,引用被指针变量所指向的元素。,注意:用指针变量作实参,必须先使指针变量有确定值,指向一个已定义的数组。,形式2:形参为指针变量,89,i, x,*i,90,例: 求10个数中的最大值和最小值,void main() extern Max,Min; int i , number10 ; for( i=0 ; i10 ; i+) scanf(“%d” , ,91,1)

37、用数组名作形参: int Max , Min ; void max_min_value( int array , int n ) int *p , *array_end ; array_end = array + n ; Max = Min = *array ; for( p=array+1 ; pMax) Max = *p ; else if ( *pMin) Min = *p ; ,被指针变量所指向的,92,93,2) 用指针变量作实参和形参。 void main() int i , number10 , *p ; p=number ; for( i=0 ; i10 ; i+,p+ ) s

38、canf(“%d” , p ) ; for( p=number , i=0 ; i10 ; i+ , p+ ) printf(“%d” , *p) ; p=number ; max_min_value ( p , 10) ; printf(“nMax=%d,Min=%dn” , Max ,Min ) ; ,经过p+后,p的值已经改变,要重新赋值。,94,int Max , Min ; void max_min_value( int *array , int n ) int *p , *array_end ; array_end = array + n ; Max = Min = *array

39、; for( p=array+1 ; pMax) Max = *p ; else if ( *pMin) Min = *p ; return ; ,95,二维数组,行指针和列指针是两个不同的概念, 函数的声明和调用形式与一维数组略有不同。,例7.11:有3名学生,各学4门课,计算总平均分数; 输出第n个学生的成绩。,96,void main() void average(float *p,int n); void search(float (*p)4,int n); float score34=65,67,70,60, 80,87,90,81,90,99,100,98; average(*sc

40、ore,12); search(score,2); ,指向一维数组的指针变量0行的首地址。,指向变量的指针变量score0,是一个地址,指向元素score00,97,void average(float *p,int n) float *p_end ; float sum=0,aver ; p_end=p+n-1; for( ; p=p_end ; p+) sum=sum+(*p) ; aver=sum/n ; printf(“average=%5.2fn” ,aver);,形参p被声明为指向实型变量的指针变量。用p指向二维数组的各个元素,p每加1,就改为指向下一个元素。,98,void se

41、arch(float (*p)4 ,int n) int j ; printf(“the score of No.%d are:n”,n) ; for( j=0;j4;j+) printf(“%5.2f ”,*(*(p+n)+j) ; ,形参p是指向包含4个元素的一维数组的指针变量。,函数调用时,把实参score的值(即数组0行的首地址)传给p,则p+n是一维数组scoren的首地址,*(p+n)+i是scorenj的地址,因此*(*(p+n)+j)是scorenj值。,p+n,p,99,7.4 指针与字符串,字符串的逻辑结构和物理结构都是一维的。,100,7.4.1 字符指针与字符数组,字符

42、串是存放在字符数组中的。 有两种方法可引用一个字符串。 (1) 用数组名和格式声明“%s”输出字符串,或用数组名和下标引用串中一个字符。 (2) 用字符指针变量指向一个字符串常量,并通过指针变量引用字符串常量。,101,#include int main() char string=“I am a boy。”; printf(“%sn”,string); printf(“%cn”,string7); return 0; ,用数组名和%s符,用数组名和 下标引用元素,例7.13 定义一个字符数组,在其中存放字符串 “I am a boy。”,输出该串和第8个字符。,字符数组,102,#inclu

43、de int main() char *string=“I am a boy。”; printf(“%sn”,string); return 0; ,char *string; string=” I am a boy。”;,例7.14 用字符指针变量输出一个字符串。,指针变量,103,把上例改写为: #include int main() char *pc=“I am a boy.”; pc=pc+2; printf(“n%cn”,*(pc+5); printf(“n%sn”,pc+5); printf(“n%sn”,pc); return 0; ,把上例改写为: #include int m

44、ain() char *pc=“I am a boy.”;,指针变量,/* while(*pc) printf(“%c”,*pc+); */,104,注意:字符指针变量和字符数组,1)字符数组由若干个元素组成,每个元素中存放一个字符; 字符指针变量中存放的是地址,不能把字符串放到字符指针变量中去。,105,2)对字符数组,只能对各个元素赋值, 不能用以下方法对字符数组赋值: char str14 ; str=“I love China” X,对字符指针变量,可以采用下面方法赋值: char *a ; a=“I love China” ; ,106,3)对字符指针变量赋初值: char *a=“

45、I love China”; 等价于 char *a; a=“I love China”;,数组可以在定义变量时整体赋初值,但不能在赋值语句中整体赋初值。,而对数组的初始化: char str14=“I love China”; 不等价于 char str14; str =“I love China” ;,107,4)若定义了字符数组,编译时为它分配单元,有确定的地址; 而定义一个字符指针变量时,给指针变量分配了单元,其中可以存放地址。 即:该指针变量可以指向一个字符型数据,但如果未对它赋予一个地址值,则它并未指向一个确定的字符数据。例如: 正确用法: char str10 ; scanf(“

46、%s”,str) ; 危险用法: char *a ; scanf(“%s”,a);,108,5)指针变量的值是可以改变的,如: void main() char *a=“I love China”; a=a+7; printf(“%s”,a); 而数组名虽然代表地址,但它的值不能改变。 错误的用法: char str =“I love China” ; str=str+7 printf(“%s”,str);,109,例7.15 用指针变量复制字符串。,解题思路: 定义两个指针变量p1和p2,分别指向字符数组a和b。 改变指针变量p1和p2的值,使它们顺序指向数组中的各元素,进行对应元素的复制。,110,#include int main() char a=“I am a boy.“,b20,*p1,*p2; p1=a; p2=b; for( ; *p1!=0; p1+,p2+) *p2=*p1; *p2=0; printf(“string a is:%sn”,a); printf(“string b is:%sn”,b); r

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 中职 > 电脑技术
版权提示 | 免责声明

1,本文(计算机精品课件:第7章-指针.ppt)为本站会员(金钥匙文档)主动上传,163文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。
2,用户下载本文档,所消耗的文币(积分)将全额增加到上传者的账号。
3, 若此文所含内容侵犯了您的版权或隐私,请立即通知163文库(发送邮件至3464097650@qq.com或直接QQ联系客服),我们立即给予删除!


侵权处理QQ:3464097650--上传资料QQ:3464097650

【声明】本站为“文档C2C交易模式”,即用户上传的文档直接卖给(下载)用户,本站只是网络空间服务平台,本站所有原创文档下载所得归上传人所有,如您发现上传作品侵犯了您的版权,请立刻联系我们并提供证据,我们将在3个工作日内予以改正。


163文库-Www.163Wenku.Com |网站地图|