下载本文档
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第11章 指 针,知识点: 指针的定义 指针变量的使用 各种指针的使用 重点: 指针的概念及C语言指针使用的特点 指针变量的定义、引用 数组的指针、字符串的指针、函数的指针、指向指针的指针的使用 难点: 指针的运算和使用 指针在数组中的使用及使用特点,指针是C语言中的一个重要的概念,也是C语言的一个重要特色。 可以表示复杂的数据结构 能动态分配内存 能方便地使用字符串 有效而方便地使用数组 在调用函数时能得到多于1个的值 能直接处理内存地址等,第11章 指 针,11.1 地址和指针的概念,“直接访问”方式 按变量地址存取变量值的方式,int x,y,z;,x=20,y=40;,z=x+y;,编
2、译系统把变量名转换为变量的地址,对变量值的存取通过地址进行的。,内存,11.1 地址和指针的概念,“间接访问”方式 通过存放变量地址的变量去访问变量,int x,*x_point;,x_point=,*x_point=20;,11.1 地址和指针的概念,k=x; /*直接访问*/,x_pointer= /*间接访问*/,10,10,变量的指针 就是变量的地址 指针变量 存放变量地址的变量 用来指向另一个变量 用“*”符号表示“指向”,11.2 变量的指针和指向变量的指针变量,定义一个指针变量 指针变量不同于整型变量和其他类型的变量,它是用来专门存放地址的。 必须将指针变量定义为“指针类型”。
3、一般形式 基类型 *指针变量名; 基类型:指针变量所指向的变量的类型。 例 float *pointer1; int *pointer2; char *pointer3; 指针变量的定义是通过*进行的 定义后的指针变量只能赋值指针,不能赋值为一般数据类型,11.2 变量的指针和指向变量的指针变量,指针变量的引用 int *pointer_1,*pointer_2; a=100;b=10; pointer_1= ,100,10 100,10,指针变量的初始化 一般形式 基类型 *指针变量名=初始地址值;,11.2 变量的指针和指向变量的指针变量,例 int i; int *p=,例 int i;
4、 int *p=,例 int *p=,用已初始化指针变量作初值,11.2 变量的指针和指向变量的指针变量,指针变量使用前必须先初始化或赋初值,例 main() int i=10, *p; *p=i; printf(“%d”,*p); ,结果:10,危险!,例 main( ) int i=10,k, *p; p= ,零指针与空类型指针 零指针:(空指针) 定义:指针变量值为零 表示: int * p=0;,11.2 变量的指针和指向变量的指针变量,p指向地址为0的单元, 系统保证该单元不作他用(不存放有效数据) 表示指针变量值没有意义,NULL在stdio.h中定义,原型为#define NUL
5、L 0 int *p=NULL; 用途: 避免指针变量的非法引用 在程序中常作为状态比较,例 int *p; . while(p!=NULL) . ,11.2 变量的指针和指向变量的指针变量,空类型指针 定义:指针变量不指向哪一种类型数据 表示: void *p; 使用时要进行强制类型转换,表示不指定p2是指向哪一种 类型数据的指针变量,例 char *p1; void *p2; p1=(char *)p2; p2=(void *)p1;,11.2 变量的指针和指向变量的指针变量,main() int a; int *pa= ,a=10,*pa=10 ,x_pointer=,y_pointer
6、=,y_pointer=,y=*, temp=*p1; *p1=*p2; *p2=temp; main() int a,b,*pointer_1,*pointer_2; scanf(%d,%d,5,9,9,5,11.2 变量的指针和指向变量的指针变量,swap(int *p1,int *p2) int *temp,x; temp=,5,9,9,5,11.2 变量的指针和指向变量的指针变量,swap(int *p1,int *p2) int *temp; temp=p1; p1=p2; p2=temp; main() int a,b,*pointer_1,*pointer_2; scanf(%d
7、,%d,5,9,5,9,想通过函数调用得到n个要改变的值,可以: 在主调函数中设n个变量,用n个指针变量指向它们 将指针变量作实参,将这n个变量的地址传给所调用的函数的形参 通过形参指针变量,改变该n个变量的值 主调函数中就可以使用这些改变了值的变量,11.2 变量的指针和指向变量的指针变量,11.2 变量的指针和指向变量的指针变量,例:输入a、b、 c3个整数,按大小顺序输出。,main() int a,b,c,*p1,*p2,*p3; scanf(%d,%d,%d, ,swap(int *pt1, int *pt2) int temp; temp=*pt1; pt1=*pt2; *pt2=
8、temp; ,exchange(int *q1, int *q2, int *q3) if(*q1*q2) swap(q1,q2); if(*q1*q3) swap(q1,q3); if(*q2*q3) swap(q2,q3); ,数组的指针是指数组的起始地址 数组元素的指针是数组元素的地址 指向数组元素的指针 用法与指向变量的指针变量相同 int,a5,*p,*q; p=,11.3 数组与指针,由于数组名是数组的首地址(常量) p=a; /*相当于p=,a,指针变量与指针的运算 指针变量的赋值运算 p= 出现编译警告,但可以执行,11.3 数组与指针,指针的算术运算 p+/+p 指针后移一个
9、单元(元素) p-/-p 指针前移一个单元(元素) p+n 指向p指针下的n个单元(元素) p-n 指向p指针上的n个单元(元素) p-q 求两指针之间单元(元素)个数 单元(元素)大小与指针的具体数据类型有关,如当指针变量的基类型为整型时,一个单元(元素)的大小为2bytes;当指针变量的基类型为浮点型时,一个单元(元素)大小为4bytes。,11.3 数组与指针,11.3 数组与指针,例:,int a5, *p,*q; q=,p+;,p-;,p+2;,q-1;,q-p;,=4,*(p+1)或*(a+1);,=a1,指针的关系运算 实质是两个地址之间的比较,地址大的指针大,地址小的指针小 p
10、q p=q pq p=q p=q p!=q,11.3 数组与指针,引用数组元素的方法 int a5,*p; p=a;,11.3 数组与指针,下标法 ai和pi,指针法 *(a+i)和* (p+i),例 输出数组中的全部元素,11.3 数组与指针,main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (i=0;i10;i+) printf(“%4d”,ai); ,用下标法引用数组元素,main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (i=0;i10;i+) printf(“%4d”,*(a+i); ,11.3 数组
11、与指针,用指针法引用数组元素 数组名a在计算过程中代表数组的首地址 对ai进行变址运算,转化为*(a+i),main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (p=a;p(a+10);p+) printf(“%4d”,*p); ,11.3 数组与指针,p的初值为数组a的起始地址 计算过程中使用了指针加法 数组名a在计算过程中代表数组的首地址,main() int a10=1,2,3,4,5,6,7,8,9,10,*p,i; for (p=a,i=0;i10;i+) printf(“%4d”, pi); ,11.3 数组与指针,用下标法引用数组元素 p的
12、初值为数组a的起始地址,11.3 数组与指针,main() int i,*p,a10; p=a; for(i=0;i10;i+) scanf(%d,p+); printf(n); for(i=0;i10;i+,p+) printf(%d,*p); ,1 2 3 4 5 6 7 8 9 0,22153 234 0 0 30036 25202 11631 8259 8237 28483,p=a;,1 2 3 4 5 6 7 8 9 0,例 通过指针变量输出a数组的10个元素,main() int a =5,8,7,6,2; int y,*p= ,11.3 数组与指针,6,5 6,例:,用数组名作函
13、数参数 数组名作函数实参,传递给形参的是地址(地址传递) 传递的地址是数组的首地址,形参接收的是数组的首地址 形参定义时为数组,形参数组的维数可省略(一维数组) 实际上,编译系统把形参数组名作为指针变量来处理,11.3 数组与指针,前面已经分析,指向数组的指针变量可以通过指针法,也可以通过下标法引用数组元素,所以,11.3 数组与指针,void f(int b ) printf(len of b is %dByten,sizeof(b); printf(a1=%d,b1); main() int a3=1,2,3; f(a);,len of b is 2Byte a1=2,例:,void f(
14、int *b) printf(a1=%d,*(b+1);,数组名作函数参数,实参与形参的对应关系,11.3 数组与指针,例 将数组a中n个整数按相反顺序存放,11.3 数组与指针,算法: 设两个“位置指示变量”i和j,i的初值为0,j的初值为n-1 将ai与aj交换 使i的值加1,j的值减1 再将ai与aj对换,直到i=(n-1)/2为止,main() int i,a10=3,7,9,11,0,6,7,5,4,2; printf(The original array:n); for(i=0;i10;i+) printf(%d,ai); printf(n); inv(a,10); printf(
15、The array has been inverted:n); for(i=0;i10;i+) printf(%d,ai); printf(n); ,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=xi; xi=xj; xj=temp; ,11.3 数组与指针,i,j,void inv(int *x,int n) int *p,temp,*i,*j,m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i=p;i+,j-) temp=*i; *i=*j; *j=temp;
16、,11.3 数组与指针,多维数组与指针 多维数组的地址 int a34=1,3,5,7,9,11,13,15,17,19,21,23; 可以把a看作是一维数组,有3个元素:a0,a1,a2 a0,a1,a2可以分别认为是包含4个元素的一维数组 二维数组是数组的数组,11.3 数组与指针,11.3 数组与指针,11.3 数组与指针,a-二维数组的首地址,即第0行的首地址 a+i-第i行的首地址 ai *(a+i)-第i行第0列的元素地址 ai+j *(a+i)+j -第i行第j列的元素地址 *(ai+j) *(*(a+i)+j) aij,a+i= printf(FORMAT,a,*a); pri
17、ntf(FORMAT,a0,*(a+0); printf(FORMAT,11.3 数组与指针,例 输出二维数组有关的值。,ffb8,ffb8 ffb8,ffb8 ffb8,ffb8 ffc0,ffc0 ffc0,ffc0 ffc8,ffc8 ffc8,ffc8 9,9,11.3 数组与指针,11.3 数组与指针,指向多维数组元素的指针变量 指向数组元素的指针变量,main() int a34=1,3,5,7,9,11,13,15,17,19,21,23; int *p; for(p=a0;pa0+12;p+) if(p-a0)%4=0) printf(n); printf(%4d,*p); ,
18、1 3 5 7 9 11 13 15 17 19 21 23,11.3 数组与指针,在int anm数组中求aij的首地址, 一维数组指针变量维数和二维数组列数必须相同,11.3 数组与指针,用指向多维数组的指针作函数参数 指针变量作形参接受实参数组名传递来的地址时,可以 用指向变量的指针变量 用指向一维数组的指针变量 例 有一个班,3个学生,各学4门课,计算总平均分数,以及第n个学生的成绩。,11.3 数组与指针,11.3 数组与指针,main() void average(float *p,int n); void search(float (*p)4,int n); float scor
19、e34=65,67,70,60,80,87,90,81,90,99,100,98; average(score,12); search(score,2); getch(); 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(naverage= %5.2f n,aver); void search(float (*p)4,int n) i
20、nt i; printf(the score of No.%d are:n,n); for(i=0;i4;i+) printf(%5.2f , *(*(p+n)+i); ,字符串的表示形式,11.4 字符串与指针,用字符数组实现,main() char string =I love China!; printf(%sn,string); printf(%sn,string+7); ,I love China! China!,数组名是数组的首地址,11.4 字符串与指针,用字符指针实现 字符指针变量初始化:把字符串首地址赋值给字符指针变量,main( ) char *string=“I love
21、 China!”; printf(“%sn”,string); string+=7; while(*string) printf(%c,*string); string+; ,I love China! China!,11.4 字符串与指针,字符串指针作函数参数 例:字符串的复制,11.4 字符串与指针,用字符数组作参数,void copy_string(char from , char to ) int i=0; while(fromi!=0) toi=fromi; i+; toi=0; main() char a =I am a teacher.; char b =you are a st
22、udent.; printf(string a=%snstring b=%sn,a,b); copy_string(a,b); printf(nstring a=%snstring b=%sn,a,b); getch(); ,11.4 字符串与指针,用字符指针变量作参数,void copy_string(char *from,char *to) for(;*from!=0;from+,to+) *to=*from; *to=0; main() char *a=I am a teacher.; char *b=You are a student.; printf(string_a=%snstri
23、ng_b=%sn,a,b); copy_string(a,b); printf(nstring_a=%snstring_b=%sn,a,b); getch(); ,字符指针变量和字符数组的区别 字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址(字符串的首地址),决不是将字符串放到字符指针变量中。 赋值方式。对字符数组只能对各个元素赋值,不能用以下办法对字符数组赋值。 char str14; str=I love China!; 而对字符指针变量,可以采用下面方法赋值: char*a; a=I love China!; 但注意赋给a的不是字符,而是字符串的首地址。,1
24、1.4 字符串与指针,对字符指针变量赋初值: char *a=I love China!;等价于 char *a; a=I love China!; 对数组的初始化: char str14=I love China!;不能等价于 char str14; str =I love China!; 即数组可以在变量定义时整体赋初值,但不能在赋值语句中整体赋值。,11.4 字符串与指针,编译系统在编译时为定义的字符数组分配内存单元,它有确定的地址。为定义一个字符指针变量分配内存单元,在其中可以放一个地址值,但地址值不确定。 char a9,*p;,11.4 字符串与指针,地址确定,字符指针变量的值可以
25、改变,字符数组名(地址常量)不可以改变。 p+; a+; ,用函数指针变量调用函数 函数指针变量可以指向一个函数。 函数在编译时被分配给一个入口地址,即函数的指针。 函数指针变量存储函数的指针。 函数名是函数的入口地址,即函数指针变量,11.5 指向函数的指针,函数返回值的数据类型,专门存放函数入口地址,可指向返回值类型相同的不同函数,( )不能省,使用函数指针变量 定义形式 数据类型 (*指针变量名)(); 如 int (*p)();,函数指针变量赋值:如p=max;,函数指针变量指向的函数必须有函数说明,函数调用形式: c=max(a,b); c=(*p)(a,b); 对函数指针变量pn,
26、 p+, p-无意义,main() int max(int ,int); int (*p)(); int a,b,c; p=max; scanf(%d,%d, ,11.5 指向函数的指针,11.5 指向函数的指针,用指向函数的指针作函数参数 例 用函数指针变量作参数,求最大值、最小值和两数之和。,定义形式 类型名 *函数名(参数列表) int *f(int x,int y) 函数返回值的类型是指向整型数据的指针(地址),11.6返回指针值的函数,例 求两个int型变量中居于较大值的变量的地址。,11.6返回指针值的函数,!不能把形参或局部变量的地址作函数返回值,11.7指针数组和指向指针的指针
27、,指针数组的概念 数组中的元素为指针变量 定义形式 数据类型 *数组名数组长度 int *p4;char *name5;,(元素)指针变量所指数据的数据类型,区分int *p4与int (*p)4,用指针数组执行若干字符串,可以节省内存单元以及处理灵活,用二维数组,浪费存储空间,#include void sort(char *name,int n) char *temp; int i,j,k; for(i=0;i0) k=j; if(k!=i) temp=namei; namei=namek; namek=temp; main() char *name=Follow me,BASIC, Gr
28、eat Wall,FORTRAN,Computer ; int n=5; sort(name,n); print(name,n); ,例:将若干字符串按字母顺序(由小到大)输出,11.7指针数组和指向指针的指针,指向指针的指针 指向指针数据的指针变量(即指针变量存放的是指针变量的地址) 定义形式 数据类型 *指针名,最终目标变量的数据类型,例: int c=5,*p,*q; p=,printf(%d,%d,%d,c,*p,*q); 5,5,5,11.7指针数组和指向指针的指针,main() char *a=hello,world,China,*p; int i; for (p=a,i=0;i3
29、;i+) printf(n*a%d=%s,i,*(p+i); ,*a0=hello,*a1=world,*a2=China,11.7指针数组和指向指针的指针,main() char *a=hello,world,China,*p; int i; p=a; for (i=0;i3;i+,p=a+i) printf(n*a%d=%s,i,*p); ,指针数组作main函数的形参 命令行:在操作系统状态下,为执行某个程序而键入的一行字符 命令行一般形式:命令名 参数1 参数2参数n C:TC copy.exe source.c temp.c,11.7指针数组和指向指针的指针,有3个字符串参数的命令行
30、,带参数的main函数形式:,main(int argc, char *argv) ,元素指向命令行参数中各字符串首地址,命令行中参数个数,命令行参数传递,第一个参数: main所在的可执行文件名,11.7指针数组和指向指针的指针,/*test.c*/ main(int argc, char *argv) while(argc1) argv=argv+1; printf(%sn,*argv); -argc; ,编译、链接test.c,生成可执行文件test.exe 在DOS状态下运行(test.exe所在路径下) C:TC test.exe hello world!,hello world!,
31、例,指向结构体变量的指针 定义形式 struct 结构体名 *结构体指针名;,11.8 指向结构体的指针,例 struct student int num; char name20; char sex; int age; float score; char addr30; ; struct student s,*p; p=,指向结构体数组的指针,11.8 指向结构体的指针,printf(%5d %-20s %2c %4dn, p-num, p-name, p-sex, p-age);,用指向结构体的指针作为函数参数 结构体指针做函数参数,传地址,11.8 指向结构体的指针,11.8 指向结构体
32、的指针,#define FORMAT %dn%sn%fn%fn%fn struct student int num; char name20; float score3; stu=12345,Li Li,67.5,89,78.6; main() void print(struct student *); /*形参类型修改成指向结构体的指针变量*/ print( ,例:结构体数组作函数参数 打印2名学生的3门成绩,struct student int num; char name20; int score3; stu2; void input(struct student stu1) int i,j; for(i=0;i2;i+) printf(input NO.:); scanf(%d, ,void print(struct student stu2) int i,j; for(i=0;i2;i+) printf(n NO. %d,stu2i.num); printf(n name %s,); for(j=0;j3;j+) printf(n %d score %d,j+1,stu2i.scorej); ,ma
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 商业底商空间规划与动线优化方案
- 零售行业的店长岗位的招聘问答参考
- 护理与医疗团队的协作模式
- 水利工程旁站监理方案
- 新时代基础英语 2
- 基于健康素养的儿童体育运动类校外培训机构策略分析
- 客户服务团队激励策略研究
- 零售业门店经理招聘面试技巧与问题
- 炼铁厂的自动化与智能化升级路径
- 零售业内如何做好一名行政助理解析
- 2026年陕西航空职业技术学院单招职业技能考试题库附答案详解(完整版)
- 中级消防设施操作员(监控方向)理论考试题库资料(含答案)
- 2026年中考语文常考考点专题之古诗词赏析(选择题)
- 2025肿瘤科护理指南
- 2025年广州市公安局越秀区分局辅警招聘考试笔试试题(附答案)
- 2025-2026学年岭南版小学美术六年级第二学期教学计划及教学进度表
- 雨课堂学堂在线学堂云安全科学原理(中南大学)单元测试考核答案
- 磨矿培训教学课件
- 物流运输安全协议范本
- 中国呼吸衰竭诊断和治疗指南2025
- 2026春译林版新版八年级下册英语单词默写表
评论
0/150
提交评论