最全的C语言指针详解.ppt

上传人:牧羊曲112 文档编号:4915475 上传时间:2023-05-23 格式:PPT 页数:47 大小:678KB
返回 下载 相关 举报
最全的C语言指针详解.ppt_第1页
第1页 / 共47页
最全的C语言指针详解.ppt_第2页
第2页 / 共47页
最全的C语言指针详解.ppt_第3页
第3页 / 共47页
最全的C语言指针详解.ppt_第4页
第4页 / 共47页
最全的C语言指针详解.ppt_第5页
第5页 / 共47页
点击查看更多>>
资源描述

《最全的C语言指针详解.ppt》由会员分享,可在线阅读,更多相关《最全的C语言指针详解.ppt(47页珍藏版)》请在三一办公上搜索。

1、第6章 指针,6.1 指针定义与使用6.2 指针与函数6.3 指针与数组6.4 指针与字符串6.5 指针数组与多级指针6.6 指针与动态内存分配6.7 指针的深层应用,6.1 指针的引出,一.地址与指针 1.地址与取地址运算 C程序中的变量在内存中占有一个可标识的存储区,每一个存储区是由若干个字节组成,每一个字节都有 自己的地址,而一个存储区的 地址是指该存储区中 第一个字节的地址,C语言允许在程序中使用变量的地址(通过地址运算符 数组变量 a 的地址-数组名 a,2.指针与指针变量(1)变量的访问方式 直接访问:通过变量名或地址访问变量的存储区 例:scanf(“%d”,间接访问:将一个变量

2、的地址存放在另一个变量中.如将变量 x 的地址存放在 变量p 中,访问x 时先找到p,再由p 中存放的地址找到 x,2012,1010,1010,(2)指针:一个变量的指针就是该变量的地址(指针就是地址)(3)指针变量:存放变量地址的变量,它用来指向另一个变量,二、指针变量的定义1.格式:数据类型*指针变量名;例 int*p1;char*p2;,2.说明:(1)在变量定义时,*号表示该变量是指针变量(注意:指针变量是p1,p2,不是*p1,*p2)(2)定义指针变量后,系统为其分配存储空间,用以存放 其他变量的地址,但在对指针变量赋值前,它并没有 确定的值,也不指向一个确定的变量,例:int

3、x,*p;x=5;,2012,1010,5,1234,注:指针变量p的值是随机值,此时p 和 x 并无关联,(3)使指针变量指向一个确定的变量必须进行赋值,int x,*p;x=5;p=,2012,1010,5,1010,三、指针变量的引用 1.指针运算符*(1)p与*p不同,p是指针变量,p的值是p所指向的变量的地址*p 是p 所指向的变量,*p的值是p所指向的变量的值,*p 的值为 5(*p 表示 x),而p 的值为 1010,(2)引用指针变量时的*与 定义指针变量时的*不同 定义变量时的*只是表示其后的变量是指针变量,int a,*p;p=,2012,1010,5,1010,12,让p

4、指向a,对a 重新赋值等价于 a=12,即&a,2.,*&a*(&a)*p a,&*p&(*p)&a,3.*与+,-int a=2,b=5,c,d,*p;,p 的值为a 的地址,*p 的值为2p 的值不变,*p 的值为 3,(2)c=*p+;,c=*(p+);c=*p;p+;执行后 c 的值为 3,*p 的值为 5,(3)d=*+p;,d=*(+p);+p;d=*p;执行后 d 的值为 3,*p 的值为 3,2012,1010,1010,(1)p=,(等价于 a+;),1012,3,3,1014,3,例6.2#include void main()int*p1,*p2,*p,a,b;scanf

5、(“%d%d”,&a,&b,&a,&b,&a,5,9,输出结果:a=5,b=9max=9,min=5,一、指针变量作函数参数,例:2个数按大小顺序输出#include void swap(int x,int y)int temp;temp=x;x=y;y=temp;void main()int a,b;scanf(“%d%d”,5,说明:该程序不能实现a 和b 的交换因为实参a,b 对形参x,y 是“值传递”,x 和y 的变化不影响a 和b 所以输出为:a=5,b=9,9,main,swap,5,5,9,9,5,6.2 指针与函数,例 6.3#include void swap1(int*p1

6、,int*p2)int temp;temp=*p1;*p1=*p2;*p2=temp;void main()int a,b,*pt1,*pt2;scanf(“%d%d”,&b,&a,5,说明:这种方法是交换p1和p2所指向的变量的值,即交换main函数中a 和b的值所以输出为:a=9,b=5,main,swap1,5,9,&a,&b,9,5,例 6.3#include void swap2(int*p1,int*p2)int*temp;*temp=*p1;*p1=*p2;*p2=*temp;,说明:这种方法可能会破坏系统的正常工作状态,因为temp是一个指针变量但是在函数中并没有给temp一个

7、确定的地址,这样它所指向的内存单元是不可预见的,而对*temp的赋值可能带来危害,main,&a,&b,&b,&a,swap2,?,随机值,5,5,9,5,9,例 6.3#include void swap3(int*p1,int*p2)int*p;p=p1;p1=p2;p2=p;,&a,&a,&b,这种方法是交换形参p1和p2的值,使它们的指向发生改变,但是main函数中的a和b的值并没有进行交换所以输出为:a=5,b=9,&b,&a,swap3,前面我们用到的函数,有些无返回值,有些有返回值,返回值 类型多为 int,float,char.一个函数的返回值也可以是一个指针 类型的数据(即地

8、址),定义函数:数据类型*函数名(形参表列)函数体;例:int*fun(int a,int b)函数体;说明:定义一个返回指针值的函数与以前定义函数格式基本类似,只是在函数名前加*,它表明该函数返回一个指针值,而这个指针值是指向一个 int 型数据,二、函数返回 指针,例:#include#include#define SIZE 100char bufSIZE;char*p=buf;char*alloc(int n)char*begin;if(p+n=buf+SIZE)begin=p;p=p+n;return(begin);else return(NULL);,void main()char*

9、p1,*p2;int i;p1=alloc(10);strcpy(p1,”123456789”);p2=alloc(5);strcpy(p2,”abcd”);printf(“buf=%pn”,buf);printf(“p1=%pn”,p1);printf(“p2=%pn”,p2);puts(p1);puts(p2);for(i=0;i15;i+)printf(“%c”,bufi);,buf0buf1:buf9buf10:buf14buf15:buf99,buf+10,buf,buf,buf+10,12:90,a:0,10,buf+15,buf+10,5,函数的指针:函数的入口地址 在程序执行过

10、程中调用函数时,计算机会转去执行函数体内的语句,因此计算机必须知道函数在什么地方。实际上函数在内存中也要占据一片存储单元,这片存储单元一个起始地址,我们称其为函数的入口地址,即函数的指针,这个函数的入口地址是用函数名来表示。因此我们可以定义一个指针变量,让它的值等于函数的入口地址,然后可以通过这个指针变量来调用函数,该指针变量称为指向函数的指针变量,三、指向函数的 指针,指向函数的指针变量 1.定义格式:数据类型(*指针变量名)(形参表列);int(*pt)(int arr,int n);说明:数据类型:指针变量所指向的函数的返回值类型 形参表列:即指针变量所指向的函数的形参表列 格式中的小括

11、号不能省略,2.应用(1)让指针变量指向函数 pt=add;因为函数名为函数的入口地址,所以直接将函数名 赋给指针变量即可(2)使用指针变量调用函数 格式:(*指针变量名)(实参表列),例 求一维数组中全部元素的和#include int add(int b,int n);void main()int a6=1,3,5,7,9,11,total;int(*pt)(int b,int n);pt=add;total=(*pt)(a,6);printf(“total=%d n”,total);int add(int b,int n)int i,sum=0;for(i=0;in;i+)sum=sum

12、+bi;return(sum);,定义指向函数的指针变量,令指针变量pt 指向函数add,通过pt 调用函数add,6.3 指针与数组,一.一维数组与指针 1.一维数组及元素的地址表示 int a5=1,2,3,4,5;数组的地址:a,2.用指针变量引用数组元素(1)定义指针变量 int*p,a5=1,2,3,4,5;p=a;,(2)引用数组元素,注意:指针变量也可以加下标 pk 等价于 ak 分别用三种方法输出数组元素,其效率不同,下标法与地址法的效率相同,指针法的效率较快 用指针变量访问数组元素时要注意下标是否越界,例:将数组a中全部元素加1,再输出a#include void main(

13、)int a5=1,3,5,7,9,*p,j;for(p=a;pa+5;p+)printf(“%3d”,*p);printf(“n”);for(j=0;j5;j+)aj=aj+1;for(j=0;j5;j+)printf(“%3d”,*(p+j);printf(“n”);,p=a;,aa+1a+2a+3a+4,2,4,6,8,10,可以用p+,但不能用a+因为a 代表数组的起始地址 它是地址常量,不能改变 而p 是一个指针变量,使用指针变量时要注意它的当前值,3.指向数组的指针变量作函数参数,例6.7 实参和形参都用数组名#include void inv1(int x,int n)int t

14、emp,i,j,m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;void main()int i,a6=1,3,4,6,7,9;inv1(a,6);for(i=0;i6;i+)printf(“%3d”,ai);printf(“n”);,a0a1a2a3a4a5,x0 x1x2x3x4x5,main,inv1,例6.7 实参用数组名,形参用指针变量#include void inv2(int*x,int n)int temp,m=(n-1)/2;int*p,*i,*j;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)

15、temp=*i;*i=*j;*j=temp;void main()int i,a6=1,3,4,6,7,9;inv2(a,6);for(i=0;i6;i+)printf(“%3d”,ai);printf(“n”);,a0a1a2a3a4a5,inv2,9,1,7,3,6,4,1,a+1,a+4,a+2,a+3,3,4,i和j的指向会变化,p的指向保持不变,例6.7 实参和形参都用指针变量#include void inv3(int*x,int n);void main()int*p,a6=1,3,4,6,7,9;p=a;inv3(p,6);for(p=a;pa+6;p+)printf(“%3d

16、”,*p);printf(“n”);void inv3(int*x,int n)int temp,m=(n-1)/2;int*p,*i,*j;i=x;j=x+n-1;p=x+m;for(;i=p;i+,j-)temp=*i;*i=*j;*j=temp;,例6.7 实参用指针变量,形参用数组名#include void inv4(int x,int n);void main()int*p,a6=1,3,4,6,7,9;p=a;inv4(p,6);for(p=a;pa+6;p+)printf(“%3d”,*p);printf(“n”);void inv4(int x,int n)int temp,

17、i,j,m=(n-1)/2;for(i=0;i=m;i+)j=n-1-i;temp=xi;xi=xj;xj=temp;,例6.8 求数组中最大和最小元素#include int max,min;void m1(int arr,int n)int*p,*end;end=arr+n;max=min=*arr;for(p=arr+1;pmax)max=*p;else if(*pmin)min=*p;void main()int i,a6;for(i=0;i6;i+)scanf(“%d”,a0a1a2a3a4a5,471905,4,4,7,9,1,0,二、二维数组与指针,二维数组的定义,对于二维数组a

18、,首先可以把它先理解为一个一维数组,它有3个元素:a0,a1,a2,而每一个元素又是一个一维数组,包含4个元素如a0是一维数组,它有4个元素:a00,a01,a02,a03,a34,a0,a1,a2只是一种地址表示方法,并不真的二维数组元素,可以看作是第二重一维数组的名字。,二维数组的初始化,(1)可以分行给二维数组赋初值,int a34=1,2,3,4,5,6,7,8,9,10,11,12;,1 2 3 4,5 6 7 8,910 11 12,(2)可以将所有数据写在一个花括号中,按顺序对各元素赋初值,int a34=1,2,3,4,5,6,7,8,9,10,11,12;,二维数组的初始化,

19、(3)可以对部分元素赋初值,其余元素补0,int a34=1,5,9;,int a34=1,0,6,0,0,11;,(4)如果对全部数据都赋初值,则定义时第一维的长度可以不指定,但第二维的长度不能省,int a 4=1,2,3,4,5,6,7,8,9,10,11,12;,二维数组的初始化,如果只对部分数据赋初值,第一维的长度也可以不指定,但元素必须分行赋初值,int a 4=0,0,3,0,10;,二维数组的地址,二维数组名a表示二维数组的首地址,也是第0个元素(a0)的地址,a+1代表第1个元素(a1)的地址 a+1&a1a+2代表第2个元素(a2)的地址 a+2&a2,a&a0,a0,a1

20、,a2既然是第二重一维数组名,它们就代表了相应一维数组的首地址,因此a0代表了第0行第0列元素的地址,即,二维数组的地址,a1&a10 a1+2&a12,a2&a20 a2+3&a23,a0&a00 a0+1&a01,Question,二维数组的地址,因a&a0,所以*a*(&a0),a0&a00,即*a表示元素a00的地址,*a+1表示元素a01的地址,*(a+1)表示元素a10的地址,*(a+2)+3表示元素a23的地址,二维数组的地址,小结:,二维数组名a代表二维数组的首地址,即:第0行的地址为 a&a0,第1行的地址为 a+1&a1第2行的地址为 a+2&a2,二维数组元素的地址,指向

21、二维数组元素的指针,例1:用指针变量输出二维数组中的元素,Quizp=a;p=,#includevoid main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int*p;,for(p=a0;pa0+12;p+)printf(“%d”,*p);printf(“n”);,指向二维数组元素的指针,int a34;int*p;p=a;合法吗?,int x=36,*q,*p;q=,2010,2026,p是二级指针,它指向一个整型指针变量q,而q指向一个整型变量,a是一种地址表示方法,a实际指向了第一重一维数组元素a0,而 a0是第二重一维数组,非法!,指向二维数组元素的指针

22、,定义格式:类型名(*指针变量名)数组长度;,int a34;int(*p)4;p=a;,p指向一个包含有4个整型数据的一维数组,合法!,虽然在定义p的时候只用了一个*,但p实际上是一个二级指针变量,指向二维数组元素的指针,例2:输出二维数组中的元素,#includevoid main()int a34=1,2,3,4,5,6,7,8,9,10,11,12;int(*p)4,i,j;p=a;for(i=0;i3;i+)for(j=0;j4;j+)printf(“%6d”,*(*(p+i)+j);printf(“n”);,指向二维数组元素的指针,二维数组用得较多的是“字符串数组”,配合字符串的操

23、作,使字符串处理更加方便、灵活。,char a4256=Pascal,VC,Basic,Java;,P a s c a l,V c,B a s i c,J a v a,#include#include#define MAXLEN 256#define N 4void main()int i,j;char tempMAXLEN;char nameNMAXLEN=Pascal,VC,Basic,Java;for(i=0;iN;i+)puts(namei);,/书的数量,for(i=0;i0)strcpy(temp,namei);strcpy(namei,namej);strcpy(namej,te

24、mp);,选择法排序,/书名的最大长度+1,指向二维数组元素的指针,比较两个字符串大小,复制字符串,Quiz选择法排序,Assignment,1、将数组a23中的每个元素向右移一列,最后一列换到最左一列(如右图所示)要求:必须用指针实现,2、将数组aMN中的每个元素向右移一列,最后一列换到最左一列要求:必须用指针实现,Experiment,实验题目:指向二维数组的指针编程 实验目的:深入理解如何用指针变量表示二维数组的 元素和元素的地址,学会用指向二维数组 的指针变量作函数参数实验内容:编程找出二维数组中的鞍点,二维数组的 鞍点是指在该位置上的元素在该行上最大,在该列上最小,也可能没有鞍点。要

25、求必 须用指针实现。编写一个找鞍点的函数,用指向二维数组 的指针变量作函数参数,6.4 指针与字符串,一、字符指针 1.定义指向字符串的指针变量 char*p=“China”;说明:这里没有定义字符数组,但字符串在内存中还是以数组形式存放的.字符串在内存中占有一片连续的存储单元,以0结束,注意:赋值只是把字符串的首地址赋给p,而不是把字符串赋给 p,p 是一个指针变量,它不能存放一个字符串,只能存放一个地址,246024612462246324642465,将字符串的首地址赋给p,2.输出字符串:printf(“%sn”,p);输出字符串时,先输出p 指向的第一个字符,然后系统自动执行p+,使

26、p 指向下一个字符,再输出该字符,直到遇到0 为止也可以用循环逐个输出字符串中的字符:for(;*p!=0;p+)printf(“%c”,*p);,246024612462246324642465,2461,2462,2463,2464,2465,二、字符数组与字符指针变量的区别 char s=“C Language”;char*p=“C Language”;,1.存储方式不同:s 存放的是字符串中的字符和0 p 存放的是字符串的首地址,2.虽然s 和p 都能代表字符串的首地址,但s是数组名,是一个常量,而p是一个指针变量,因此 s+的 写法是错的,而p+的写法是对的,char*p1,*p2=

27、“abcd”;p1=“China”;,char s12,str=“good”;s12=“China”;s=“China”;,4.定义数组s 时,系统会给s 分配一片连续的存储单元 定义指针变量p 时,只给p 分配一个存储单元,三、字符串指针作函数参数,例6.20 实现字符串复制 void copystr(char from,char to)int i=0;while(fromi!=0)toi=fromi;i+;toi=0;void mani()char a=“cat”,b=“tiger”;puts(a);puts(b);copystr(a,b);puts(a);puts(b);,a,b,c,a,t,0,相当于bi=ai,例 6.20 void copystr(char*from,char*to)for(;*from!=0;from+,to+)*to=*from;*to=0;void main()char*a=“cat”,*b=“tiger”;puts(a);puts(b);copystr(a,b);puts(a);puts(b);,a,b,c,a,t,0,a+1,b+1,a+2,b+2,a+3,b+3,

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

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号