版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 地址与指针的概念 指针与变量 指针与数组 指针与字符串 指针与函数* 返回指针值的函数 指针数组和指向指针的指针 动态内存分配 有关指针的数据类型和指针运算小结地址:内存的编号,基本单位是字节。内存单元与内存单元的内容:数值被存储在连续的若干个内存单元中;数值的存取通过变量进行,编译时已经将变量名自动转换为内存地址,物理上的存取是通过地址进行的;直接访问:按变量地址直接存取变量值。间接访问:将变量i的地址存放在另一个变量ip中,通过ip访问变量i的值。int i=100; /连续4个字节变量i2000变量ip1002000因此,数值100送到变量中有两种方法:将100送到变量i标志标志的单元
2、中;将100送到变量ip指向指向的单元中。 即:即:i i标志的单元标志的单元 指针:一个变量的地址称为该变量的“指针”。指针变量:专门用来存放另一个变量地址的变量称为指针变量;指针变量的值是指针。int i=100; /连续4个字节变量i2000变量ip1002000程序中 *表示“指向”,*ip与i是同一回事i=100;*ip=100指针变量的定义语句:例如:int *pA;/指向整数变量的指针变量char *pCh; /指向字符变量的指针变量float *pF;/指向实数变量的指针变量在指针定义中,一个*只能表示一个指针。例如:int *pA, pB;/pA是指针变量名, pB是一个普通
3、的整形变量。int *pAa, *pBb; /pAa和pBb都是指针变量。 定义指针变量定义指针变量指针运算符:& &:取地址运算符;* *:放在操作语句中的指针之前,称为间接访问运算符。如:int a, b = 10, c;int *ipa, *ipb;ipa = &a;ipb = &b;c = *ipa;指针变量使用前必须初始化;注意变量与指针的区别; int a, *ipa; ipa = 100; /错误 *ipa = &a; /错误指针变量的值是可以改变的,即改变指针的指向; int a = 10, b = 20; int *ipa, *ipb;
4、 ipa = &a; ipb = &b; *ipa = *ipb; ipa = ipb; *ipa = 10;102020003000a:地址为2000b:地址为3000ipaipb指针变量的引用指针变量的引用注意指针运算的组合: int a = 100, *ipa; ipa = &a; &*ipa ? *&a ? (*ipa)+ ? *(ipa+) ? *ipa+ ? *(+ipa) ? +*ipa ?&*ipa = &a = ipa*&a = *ipa = a(*ipa)+ = a+*(ipa+) 首先取出ipa指向的单元内容
5、, 然后ipa指向a的下一个类型单元*ipa+ 与 *(ipa+)等效*(+ipa) 首先ipa指向下一个类型单元, 然后取出该类型单元的内容+*pa = +(*ipa) ipa指向的单元内容加1 即:a = 101100aipamain() int *p1,*p2,*p,a,b; scanf(%d,%d,&a, &b); p1=&a; p2=&b; if(ab) p=p1; p1=p2; p2=p; printf(na=%d,b=%dn, a, b); printf(max=%d,min=%dn, *p1, *p2);输入a和b两个整数,按先大后小的顺序输出a
6、和b abp2p1pabp2p1p通过指针交换实现swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp;main() int a,b; int *ip1,*ip2; scanf(%d,%d,&a, &b); ip1=&a; ip2=&b; if(ab) swap(ip1, ip2); printf(n%d,%dn,a, b);&a&b59abip1ip2&b&b95abp2ip2&a&a59abp1ip1&a&b95abip1ip2i
7、nt *temp;&a&ap1ip1&b&bp2ip2*temp=*p1?temp初值swap(int x,int y) int temp; temp=x; x=y; y=temp;main() int a,b; scanf(%d,%d,&a, &b); if(ab) swap(a, b); printf(n%d,%dn,a, b);得不到所要结果:从局部变量的作用域考虑;从实参-形参的值传送考虑。swap(int *p1,int *p2) int *p; p=p1; p1=p2; p2=p;main() int a,b; int *ip1,*i
8、p2; scanf(%d,%d,&a, &b); ip1=&a; ip2=&b; if(ab) swap(ip1, ip2); printf(n%d,%dn,*ip1, *ip2);调用函数不可能改变实参指调用函数不可能改变实参指针变量的值,但可以改变实针变量的值,但可以改变实参指针变量所指变量的值。参指针变量所指变量的值。&a&b59abip1ip2&b&a59abp1p2&a&b59abp1p2&b&a59abip1ip2swap(int *p1,int *p2) int t; t=*p1; *
9、p1=*p2; p2=t;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);输入a、b、c 3个整数,按大小顺序输出 main() int a, b, c, *p1, *p2, *p3; scanf(%d,%d,%d,&a,&b,&c); p1=&a; p2=&b; p3=&c; exchange(p1,p2,p3); printf(n%d,%d,%d n,a,b,c);一个变量
10、有一个地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。所谓数组的指针是指数组的起始地址,数组元素的指针是数组元素的地址。 一个数组是由连续的一块内存单元组成的。数组名就是这块连续内存单元的首地址。一个数组也是由各个数组元素(下标变量)组成的。每个数组元素按其类型不同占有几个连续的内存单元。一个数组元素的首地址也是指它所占有的几个内存单元的首地址。指向数组的指针变量的定义指向数组的指针变量的定义int a10;/定义a为包括10个整数数据的数组int *p;/定义p为指向整数变量的指针变量指向数组元素的指针变量的赋值指向数组元素的指针变量的赋值p = &
11、;a0;/把数组a的第0号元素的地址赋给指针变量pp = &a5;/把数组a的第5号元素的地址赋给指针变量p数组名就是数组第一个元素地址数组名就是数组第一个元素地址p = a;/把数组a的首地址赋给指针变量p指针变量的初始化指针变量的初始化int a10;int *p = a;/等价于int *p = &a0;C语言规定:如果指针变量p已指向数组中的一个元素,则p+1指向同一数组中的下一个元素。如果p的初值为&a0,则:数组元素访问:初值数组元素访问:初值p=a 下标法:ai 指针法:*(p+i) *(a+i)实际地址:实际地址: a+i*d /每个元素 占d个字节p+
12、i和a+i就是ai的地址,或者说它们指向a数组的第i个元素。*(p+i)或*(a+i)就是p+i或a+i所指向的数组元素,即ai。例如,*(p+5)或*(a+5)就是a5。指向数组的指针变量也可以带下标,如pi与*(p+i)等价。 main() int a10, i; for(i=0;i10;i+) ai=i; for(i=0;i10;i+) printf(a%d=%dn, i, ai);main() int a10, i; for(i=0;i10;i+) *(a+i)=i; for(i=0;i10;i+) printf(a%d=%dn, i, *(a+i);【例】输出数组中的全部元素下标法:
13、 数组名法: main() int a10, i, *p = a; for(i=0;i10;i+) *(p+i)=i; for(i=0;i10;i+) printf(a%d=%dn, i, *(p+i);main() int a10,i,*p=a; for (i=0; i10; i+) *(p+) = i; p = a; /必须重指必须重指 for(i=0;i10;i+) printf(a%d=%dn,i, *(p+);指针变量法1: 指针变量法2: 【例】输出数组中的全部元素main() int a10,i,*p; for (i=0; i10; i+) scanf(“%d”,&ai)
14、; for(p=a;p(a+10);p+) printf(%d,*p);指针变量法3: main() int a10,i,*p; for (i=0; i10; i+) scanf(“%d”,&ai); for(p=a;a(p+10);a+) printf(%d,*a);?a+错,a是数组首地址,是常量,不能+。几个注意的问题:p+是合法的,而a+是错误的。a是数组名,它是数组的首地址,是常量;指针变量可以指到数组以后的内存单元,系统并不认为非法;*p+ 等价于 *(p+);*(p+)与*(+p)作用不同。若p的初值为a,则*(p+)等价a0,*(+p)等价a1; (*p)+表示p所指向
15、的元素值加1;如果p当前指向a数组中的第i个元素,则 *(p-)相当于ai-; *(+p)相当于a+i; a) *(-p)相当于a-i。指针加减:p+, p-, +p, -p;p+5, p-5;int a10;int *p1=&a0;int *p2=&a5;两个指针相减:p1-p2两个指针相加:无意义两个指针比较:if (p1 p2) 用数组元素作实参和用变量作实参时一样,是“值传递”方式,单向传递数据。用数组名作实参,在调用函数时实际上是把数组的首地址传递给形参,即“地址传递”方式,这样实参数组和形参数组共占同一段内存;如果函数调用过程中使形参数组的元素值发生变化,也就使实参
16、数组的元素值发生变化;这种值的变化是由于形参和实参数组共享同一段内存造成的。一个实参数组,想在函数中改变此数组的元素的值,实参与形参的对应关系有以下4种:形参和实参都用数组名;实参用数组名,形参用指针变量;形参和实参都用指针变量;实参用指针变量,形参用数组名; f(int arr,int n) main() int array10; f(array,10); array,arrarray0arr0f(int *arr,int n)等价从主调函数传递过来实参的地址,array与arr共用一段内存单元。arri和*(arr+i)是同一回事,在f被调用期间,就代表arryi。将n个整数按相反顺序存放
17、 void inv(int x, int n) int i,j,temp, m=(n-1)/2; for (i=0;i=m;i+) j=n-1-i; temp=xi; xi=xj; xj=temp; return;main() int A10=3,7,9,11,0,6,7,5,4,2; int i; printf(“Before inverting:n); for(i=0; i10; i+) printf(%d,ai); printf(n); inv(A, 10); printf(“After inverting:n); for(i=0; i10; i+) printf(%d,ai); pri
18、ntf(n);3 7 9110 6 7 5 4 22 4 5 7 6 0119 7 3ijm将n个整数按相反顺序存放 有了指针,程序变化多种多样有了指针,程序变化多种多样void inv(int *x, int n) int *p, m, temp, *fr, *ta; m=(n-1)/2; fr=x; ta=x+n-1; p=x+m; for(; fr=p; fr+, ta-) temp=*fr; *fr=*ta; *ta=temp; return;main() int A10=3,7,9,11,0,6,7,5,4,2; int i, *p = A; printf(“Before inver
19、ting:n); for(i=0; i10; i+) printf(%d,*p+); printf(n); inv(A, 10); printf(“After inverting:n); for(p=A; pb ? a:b);main()int a = 10, b = 20, c;c = max(a,b);main() int (*p)(int,int); int a = 10, b = 20, c; p = max; c = (*p)(a,b);用函数指针变量调用函数;用指向函数的指针作函数参数。Vc下必须写下必须写函数在编译时被分配一入口函数在编译时被分配一入口地址,这一地址就是函数的地址
20、,这一地址就是函数的指针指针。指令2指令1maxp用函数指针变量调用函数;用指向函数的指针作函数参数。int max(int a, int b) return (ab ? a:b);main() int (*p)(int,int); int a = 10, b = 20, c; p = max; c = (*p)(a,b);指向函数的指针变量定义:函数返回类型 (*指针变量名)();int (*p)(参数类型); float (*pf)(参数类型);函数指针变量赋值时只用函数名;p = max; /无参数对函数指针变量, p+, p+n,p-等运算无意义。返回值为整型指针的函数名为p的原型说明
21、不能写成 int *p(参数类型);Vc下必须写下必须写或或c=p(a,b);用指向函数的指针作函数参数。用用指向函数的指针作形式参数,可以实现函数地址的传递。也就是将函数名传给形参。sub( int(*x1)(int), int (*x2)(int,int) int a,b,i,j; a=(*x1)(i); b=(*x2)(i,j); .f1函数f2函数f1x1f2x2用指向函数的指针作函数参数。int max(int a, int b) return (ab?a:b); int min(int a, int b) return(ab?a:b); int add(int a, int b)
22、return (a+b); int process(int a, int b, int (*fun)(int, int) int result = (*fun)(a, b); return result;main()int max(int , int ); int min(int , int ); int add(int , int ); int process(int , int, int (*fun)(int, int); int x, y; scanf(“%d,%dn”, &x, &y); printf(“max:%dn”, process(x, y, max); pri
23、ntf(“min:%dn”, process(x, y, min); printf(“add:%dn”, process(x, y, add); 函数返回值可以是C语言中的任何定义类型标准和用户定义;返回值为指针值的函数定义: 基类型基类型 * *函数名函数名( (形参列表形参列表) )如: int *fun(float a, float b)main() 输入学生序号,查找打印学生的成绩输入学生序号,查找打印学生的成绩score4=60,70,80,90,56,89,76,88,89,78,90,88; float * search(float (*pointer)4,int n); flo
24、at *p; int i,m; scanf(“%d”,&m); p=search(score,m); for(i=0;i4;i+) printf(“%5.1f”,*(p+i);float *search(float (*pointer)4,int n) float *pt; pt=*(pointer+n); return (pt);889078898876895690807060pointerpointer+1pt156.0 89.0 76.0 88.0pt=(*pointer+n);170.0 80.0 90.0 56.0main() 打印有打印有90分以上成绩的学生各科成绩分以上成
25、绩的学生各科成绩score4=60,70,80,90,56,89,76,88,89,78,90,88; float * search(float (*pointer)4,int n); float *p; int i,j; for (i=0;i3;i+) p=search(score+i); if (p=*(score+i) printf(“%d”,i); for(j=0;j4;j+) printf(“%5.1f”,*(p+j); printf(“n”); float *search(float (*pointer)4) int i; float *pt; pt=*(pointer+1); f
26、or (i=0;i90) pt=*pointer; return(pt);889078898876895690807060pointerpointer+1ptmalloccallocfreemain() int a100, num, i; printf(“input the number:n”); scanf(“%d”, &num); for (i=0; inum; i+) ai = i; 缺点: 当num很少时,浪费空间; 当num超过100时,需要重新修改,否则错误。原因: 使用了不能扩展的静态数组结构。改进方法: 采用动态数据结构需要多少,申请多少;数组一旦定义,其所占的内存空间
27、就确定;通过数组名指示其首地址;malloccallocfreemain() int *a, num, i; printf(“input the number:n”); scanf(“%d”, &num); a = (int *)malloc(num*sizeof(int); if (!a) printf(“没有足够内存空间!n”, exit(1); for (i=0; inum; i+) ai = i; free(a);函数原型:void *malloc(unsigned int size);void *calloc(unsigned int n, unsigned int size
28、);void free(void *p);malloccallocfree1)malloc内存申请内存申请: (类型说明符类型说明符 *) malloc(size);功能功能:在内存的动态存储区中分配一块长度为size字节的连续区域。函数的返回值为该区域的首地址。 “类型说明符”表示把该区域用于何种数据类型。 (类型说明符 *)表示把返回值强制转换为该类型指针。 size是一个无符号数。如: pstr = (char *)malloc(1000*sizeof(char); 申请1000个字节的连续空间,首地址赋予指针变量pstr。pstr1000个字节malloccallocfree2)calloc内存申请内存申请: (类型说明符类型说明符 *) calloc(n, size);功能功能:在内存动态存储区中分配n块长度为size字节的连续区域。函数的返回值为该区域的首地址。 如: pscore = (float *) ca
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2024年煤矿安全生产法律法规知识考试复习题库及答案
- 委托二手房买卖合同的
- 国家基本药物政策目录及招标相关政策解读课件
- 二零二五年度车队租赁车辆保险及理赔合同范本3篇
- 2025年度个人担保贷款协议书2篇
- 2025年度环保技术合资企业个人股东股权转让协议书4篇
- 二零二五年度工业遗产厂房拆迁补偿与文化传承协议2篇
- 2025年钢材贸易居间代理服务合同范本
- 二零二五年度旅游景区景点租赁服务协议3篇
- 二零二五年度自动化仓库租赁运营合同3篇
- 寺院消防安全培训课件
- 比摩阻-管径-流量计算公式
- 专题23平抛运动临界问题相遇问题类平抛运和斜抛运动
- GB/T 42430-2023血液、尿液中乙醇、甲醇、正丙醇、丙酮、异丙醇和正丁醇检验
- 五年级数学应用题100道
- 西方经济学(第二版)完整整套课件(马工程)
- 高三开学收心班会课件
- GB/T 33688-2017选煤磁选设备工艺效果评定方法
- 科技计划项目申报培训
- 591食堂不合格食品处置制度
- 黑布林绘本 Dad-for-Sale 出售爸爸课件
评论
0/150
提交评论