版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第七七章章1 1第七章第七章指指 针针第第七七章章 内存地址及数据的存取方式内存地址及数据的存取方式 指针的定义及运算指针的定义及运算 指向数组的指针指向数组的指针 指针操作字符串指针操作字符串 语法练习和编程练习语法练习和编程练习2 2本讲主要内容本讲主要内容第第七七章章计算机的内存储器就象计算机的内存储器就象一个巨大的一维数组,一个巨大的一维数组,每个数组元素就是一个每个数组元素就是一个存储单元存储单元类似每个数组元素的下类似每个数组元素的下标,每个内存单元都有标,每个内存单元都有一个编号,称为该单元一个编号,称为该单元的地址的地址注意区分内存单元的地注意区分内存单元的地址与内存单元的值
2、址与内存单元的值00000000:0000000000000000:000100014000:10004000:10004000:10014000:10014000:10024000:10024000:10034000:1003A000:C300A000:C300A000:C301A000:C301FFFF:FFFFFFFF:FFFF内存空间内存空间线性排列线性排列58586A6A3 3内存地址内存地址第第七七章章在运行一个程序时,程序及其数据(程序、在运行一个程序时,程序及其数据(程序、函数、变量、常量、数组等)都要放在内存函数、变量、常量、数组等)都要放在内存储器中储器中编译程序根据对象的
3、数据类型,在内存中为编译程序根据对象的数据类型,在内存中为其分配一个或多个连续的存储单元。其分配一个或多个连续的存储单元。在编写程序时,通常是通过名字来使用一个在编写程序时,通常是通过名字来使用一个变量或调用某个函数,而变量和函数的名字变量或调用某个函数,而变量和函数的名字与其实际的存储地址之间的变换由编译程序与其实际的存储地址之间的变换由编译程序自动完成,编译程序按变量名查找其地址,自动完成,编译程序按变量名查找其地址,然后对该地址中的内容进行读写操作然后对该地址中的内容进行读写操作 4 4存取数据的方法存取数据的方法第第七七章章单元地址单元地址变量名变量名变量类型变量类型占用单元长度占用单
4、元长度规定运算操作规定运算操作值的存放形式值的存放形式空闲空间空闲空间操作系统占用区操作系统占用区00000000:000000003CFF:00003CFF:00008F10:00008F10:0000A100:0000A100:0000C100:2BFFC100:2BFFFFFF:FFFFFFFF:FFFF静态区静态区 (全局变量、(全局变量、 静态局部变量)静态局部变量)程序区程序区(函数(函数及其常量代码)及其常量代码)应用程应用程序空间序空间动态区动态区 (局部变量、(局部变量、形参变量)形参变量) 临时占临时占用空间用空间5 5内存分配方式内存分配方式第第七七章章直接访问:直接访问
5、:变量名代表着该变量已分到的地址,变量名代表着该变量已分到的地址,按变量地址存取变量值的方式称为直接访问。按变量地址存取变量值的方式称为直接访问。间接访问:间接访问:这种方式好比我们要找到宝藏,必须这种方式好比我们要找到宝藏,必须先找到埋宝藏的地址,才能根据地址找到宝藏先找到埋宝藏的地址,才能根据地址找到宝藏200020002000200220023010301020062006变量变量 i i变量变量 j j变量变量ipip3 36.56.55050例如:例如:若变量若变量ipip保存保存着变量着变量i i的地址,通过的地址,通过ipip存取存取i i的值就是间接的值就是间接访问。要使用间接
6、访访问。要使用间接访问运算符问运算符 * *6 6变量的访问形式变量的访问形式第第七七章章问题的提出:问题的提出: 从键盘输入两个整数放到变量从键盘输入两个整数放到变量a a、b b中,编写子中,编写子函数交换两个变量。函数交换两个变量。基本算法:基本算法:该题要求通过子函数的调用实现向主该题要求通过子函数的调用实现向主调函数返回两个结果值的运算调函数返回两个结果值的运算用普通变量的方法来编程序用普通变量的方法来编程序swap(p,q)swap(p,q)int p,q;int p,q;int temp;int temp; temp=p;p=q; temp=p;p=q; q=temp; q=te
7、mp; return() return() main()main()int a,b;int a,b; scanf(“%d,%d”,&a,&b); scanf(“%d,%d”,&a,&b); swap(a,b); swap(a,b); s程序设计到这里就无法进行下去了,因为变量程序设计到这里就无法进行下去了,因为变量a a、b b作实参只是将值单向传递给形参作实参只是将值单向传递给形参p p、q q,虽,虽然在然在swapswap函数中交换了函数中交换了p p、q q的值,但不会交换的值,但不会交换a a、b b的值。的值。s通过通过returnreturn语句只
8、能返回一个值语句只能返回一个值7 7提出问题提出问题第第七七章章解决该问题的办法有两个:解决该问题的办法有两个:将变量定义为全局变量,使其携带结果值返回。将变量定义为全局变量,使其携带结果值返回。但全局变量从定义处开始在整个程序执行过程中但全局变量从定义处开始在整个程序执行过程中都占用存储空间,直到程序结束。既浪费空间又都占用存储空间,直到程序结束。既浪费空间又不利于程序的模块化结构设计,不提倡。不利于程序的模块化结构设计,不提倡。 使用指针变量作为函数的参数。被调函数不能改使用指针变量作为函数的参数。被调函数不能改变实参指针变量的值,但可以改变实参指针变量变实参指针变量的值,但可以改变实参指
9、针变量所指变量的值。运用指针变量作参数,就能使被所指变量的值。运用指针变量作参数,就能使被调函数和主函数在同一变量上操作,从而得到多调函数和主函数在同一变量上操作,从而得到多个返回值。个返回值。8 8解决问题解决问题第第七七章章swap(int swap(int * *p1,int p1,int * *p2)p2) int p; int p; p= p=* *p1;p1; * *p1=p1=* *p2;p2; * *p2=p;p2=p;main()main()int a,b;int a,b; int int * *max, max, * *min;min; scanf(“%d%d”,&
10、a,&b); scanf(“%d%d”,&a,&b); max=&a;min=&b; max=&a;min=&b; swap(max,min); swap(max,min); printf(“n%d %d”,a,b); printf(“n%d %d”,a,b); 结果:结果:1 81 88 18 1例例12.112.1maxmax&aa a1minmin&bb b8主函数中主函数中参数传递参数传递minmin&bb8p2p2&bmaxmax&aa1p1p1&a通过通过p1p1和和p2p2的操
11、作的操作改变变量改变变量a a和和b b的值的值9 9用指针变量作参数用指针变量作参数第第七七章章定义指针变量的语法格式为:定义指针变量的语法格式为:类型说明符类型说明符 * *指针变量名指针变量名1 1,* *指针变量名指针变量名2 2,;v其中:其中:* *表示变量为指针类型;表示变量为指针类型;“类型说明符类型说明符”表示该指针变量所能指向的变量类型。指针变量可表示该指针变量所能指向的变量类型。指针变量可以在定义的时候就进行初始化。以在定义的时候就进行初始化。例如:例如:int a,int a,* *p=&a;p=&a;注意:注意:任何变量都有三个要素:变量名、变量任何变
12、量都有三个要素:变量名、变量的值和变量类型,指针变量的类型是它所指向的变的值和变量类型,指针变量的类型是它所指向的变量的类型,指针变量只能指向同一个类型的变量量的类型,指针变量只能指向同一个类型的变量 1010指针的定义指针的定义第第七七章章取地址运算符取地址运算符& &“&”“&”是单目运算符,作用是取得变量的地址,是单目运算符,作用是取得变量的地址,常用于给指针变量赋值。例如有以下定义:常用于给指针变量赋值。例如有以下定义: float f1=2.5,f2=1.0,2.0,3.0;float f1=2.5,f2=1.0,2.0,3.0;float float
13、 * *fp1=&f1,fp1=&f1,* *fp2=f2;fp2=f2;以上定义建立了指向变量以上定义建立了指向变量f1f1的指针变量的指针变量fp1fp1,指向指向f2f2数组首元素的指针变量数组首元素的指针变量fp2fp2(相当于(相当于fp2=&f20fp2=&f20)s能把一个数组名能把一个数组名f2f2赋给一个指针变量吗?赋给一个指针变量吗?s变量的地址、数组的地址、函数的地址?变量的地址、数组的地址、函数的地址?1111指针的运算指针的运算第第七七章章间接访问运算符间接访问运算符* * “* *”是单目运算符,用于得到指针所指向的变是单目运算符,用
14、于得到指针所指向的变量值,与量值,与“&”&”互为逆运算,同时出现时可抵消互为逆运算,同时出现时可抵消例如:例如:float f1=2.5,float f1=2.5,* *fp1=&f1,a;fp1=&f1,a; a=a=* *fp1;fp1;其中:变量其中:变量f1f1的指针(地址)是的指针(地址)是&f1&f1对对&fp1&fp1作取值运算的表达式为作取值运算的表达式为* *(&fp1),(&fp1),等效等效于直接访问于直接访问fp1fp1,得到变量,得到变量f1f1的地址;的地址;对对fp1fp1作取值运算
15、的表达式为作取值运算的表达式为* *fp1,fp1,等效于直等效于直接访问接访问f1,f1,得到变量得到变量f1f1的值的值2.52.5。 1212指针的运算指针的运算第第七七章章指针的赋值运算指针的赋值运算 指针变量必须被赋以一个地址值,如:指针变量必须被赋以一个地址值,如:p=&a;p=&a; / /* *将变量将变量a a的地址赋给指针的地址赋给指针p p* */ /p=array;p=array; / /* *将数组将数组arrayarray的首地址赋给的首地址赋给p p* */ /p=&arrayi; p=&arrayi; / /* *将数组将数组ar
16、rayarray的第的第i i个元素的地址赋给个元素的地址赋给p p* */ /p=max; p=max; / /* *maxmax为已定义的函数,将为已定义的函数,将maxmax的入口地址赋给的入口地址赋给p p* */ /p1=p2p1=p2; ;/ /* *p1p1和和p2p2都是指针变量,将都是指针变量,将p2p2的值赋给的值赋给p1p1* */ /注意:注意:不能把一个整数赋给指针变量。不能把一个整数赋给指针变量。 1313指针的运算指针的运算第第七七章章main()main() char c1=a,c2=b; char c1=a,c2=b; float f1=90.0,f2=80.
17、5; float f1=90.0,f2=80.5; char char * *pc=&c1; floatpc=&c1; float* *pf=&f1; pf=&f1; printf(“&c1=%x,c1=%c;&f1=%x,f1=%4.1fn”, printf(“&c1=%x,c1=%c;&f1=%x,f1=%4.1fn”, pc,pc,* *pc,pf,pc,pf,* *pf);pf); pc+;pf+; pc+;pf+; printf(“&c2=%x,c2=%c;&f2=%x,f2=%4.1fn”, print
18、f(“&c2=%x,c2=%c;&f2=%x,f2=%4.1fn”,pc,pc,* *pc,pf,pc,pf,* *pf); pf); 例例7.17.1程序运行结果:程序运行结果:&c1=&c1=?, c1=, c1=?, &f1=, &f1=?, f1=, f1=?&c2=&c2=?, c2=, c2=?, &f2=, &f2=?, f2=, f2=? 1414指针运算举例指针运算举例第第七七章章编译器在编译时会将数组的下标转换成指针,因编译器在编译时会将数组的下标转换成指针,因此,使用指针编写数组下标可以节省编
19、译时间此,使用指针编写数组下标可以节省编译时间定义指向数组的指针定义指向数组的指针例:例:int a10;int a10; int int * *pa; pa=&a0; pa; pa=&a0; 或或 pa=a;pa=a;通过指针引用数组元素通过指针引用数组元素经过上述定义及赋值后:经过上述定义及赋值后:* *papa就是就是a0,a0,* *(pa+1)(pa+1)就是就是a1,a1,., ., * *(pa+i)(pa+i)就是就是aiaiai, ai, * *(pa+i), (pa+i), * *(a+i), pai(a+i), pai都是等效的都是等效的不能写不能写 a+
20、a+,因为,因为a a是数组首地址是常量。是数组首地址是常量。 1515指向数组元素的指针指向数组元素的指针第第七七章章int a10,int a10,* *p;p;p=a;p=a;用数组:用数组:ai, &aiai, &ai用指针:用指针:* *(p+i),p+i,p+,(p+i),p+i,p+,* *(a+i)(a+i) a0 a1 a2 ai a9&a0 &a1 &a2 . &ai &a9a+0 a+1 a+2 a+i . a+9a a*p *(p+1) *(p+2) *(p+i) *(p+9)p p+1 p+2 p+i p+9p+
21、 , +p , *p+, *(a+i),不可用不可用a+ , +a , !p1616访问数组元素访问数组元素第第七七章章 用指针实现从键盘上输入一维数组的元素用指针实现从键盘上输入一维数组的元素并将其打印出来。并将其打印出来。例例7.27.2main()main() int int * *p,i,a10;p,i,a10; p=a; / p=a; /* *确定指针指向确定指针指向* */ / for(i=0;i10;i+) for(i=0;i10;i+) scanf(“%d”,p+); / scanf(“%d”,p+); /* *指针绝对移动引用指针绝对移动引用* */ / printf(“n”
22、); printf(“n”); p=a; / p=a; /* *指针复位指针复位* */ / for(i=0;i10;i+) for(i=0;i10;i+) printf(“%2d”, printf(“%2d”,* *(p(pi); i); / /* *指针相对移动引用指针相对移动引用* */ /1717数组与指针数组与指针第第七七章章引用数组元素既可以用下标法也可以用指针法引用数组元素既可以用下标法也可以用指针法来实现来实现数组名代表数组的首地址,由编译系统分配,数组名代表数组的首地址,由编译系统分配,是一个常量,不能进行自增或自减运算是一个常量,不能进行自增或自减运算指针变量是一个变量,当
23、它指向数组指针后,指针变量是一个变量,当它指向数组指针后,数组名和指针变量名可以混用数组名和指针变量名可以混用指针变量可以作为赋值表达式的左值使用,可指针变量可以作为赋值表达式的左值使用,可以自增自减,可以指向数组中任意元素以自增自减,可以指向数组中任意元素数组名是常量,不能随意改变数组名是常量,不能随意改变1818数组名和指针变量数组名和指针变量第第七七章章 四种访问数组的方法四种访问数组的方法例例7.37.3main()main() int i; int i; int test=20,30,90,80; int test=20,30,90,80; int int * *p=test;p=t
24、est; printf(“arrar test printed n”); printf(“arrar test printed n”); printf(“ array subscript notation n”); printf(“ array subscript notation n”); for(i=0;i=3;i+) / for(i=0;i=3;i+) /* *数组名加下标数组名加下标* */ / printf(“test%d=%dn”,i,testi); printf(“test%d=%dn”,i,testi); printf(“narray & offset notation
25、 n”); printf(“narray & offset notation n”); 例例7.37.31919数组与指针举例数组与指针举例第第七七章章 当指针指向数组后就可以进行以下算术运算:当指针指向数组后就可以进行以下算术运算:指针与整数的加减法指针与整数的加减法: :指针加上指针加上( (减去减去) )一个整数,一个整数,得到的结果仍是指针,表示指针由当前的位置得到的结果仍是指针,表示指针由当前的位置向前向前( (向后向后) )移动移动n n个数据位置。个数据位置。自增自增/ /自减运算自减运算: :指针进行自增指针进行自增/ /自减运算,结果自减运算,结果仍然为指针,可以使指
26、针向前(仍然为指针,可以使指针向前(+)或向后()或向后(- - -)移动一个数据位置)移动一个数据位置指针减法运算:指针减法运算:指针相减反映出两个指针之间指针相减反映出两个指针之间相隔的数据个数相隔的数据个数在使用时要注意在使用时要注意* *和和+(-)运算的优先级)运算的优先级 2020指针的算术运算指针的算术运算第第七七章章 int a10,int a10,* *p=&a3;p=&a3;则:则:* *p+: p+: 相当于相当于* *(p+p+),即访问),即访问a3a3之后之后p p再指向再指向a4a4( (* *p)+: p)+: 是将是将a3a3元素的值增一,元素
27、的值增一,p p仍然指向仍然指向a3a3* *-p-p: 相当于相当于* *(-p-p),即),即p p指向指向a2a2之后再之后再访问访问a2a2-(-(* *p)p):是:是a3a3元素的值将减一,元素的值将减一,p p仍然指向仍然指向a3a32121指针的算术运算举例指针的算术运算举例第第七七章章 两个指向同种数据类型的指针可作关系运算,两个指向同种数据类型的指针可作关系运算,运算结果为运算结果为0 0或或1 1。指针的关系运算表示它们所。指针的关系运算表示它们所指向的地址之间的关系指向的地址之间的关系 、=、 :判断两个指针指向的数据位置判断两个指针指向的数据位置的前后关系的前后关系=
28、、!=!=:判断两个指针是否指向同一个数据判断两个指针是否指向同一个数据例如:例如:int a=2,b=3,int a=2,b=3,* *p1=&a,p1=&a,* *p2=&b;p2=&b;if(p1=p2)printf(“if(p1=p2)printf(“p1p1与与p2p2指向相同!指向相同!”););if(if(* *p1=p1=* *p2)printf(“p2)printf(“p1p1与与p2p2的值相同!的值相同!”););2222指针的关系运算指针的关系运算第第七七章章对字符串的处理可以采用字符数组或字符类对字符串的处理可以采用字符数组或字符类型的
29、指针两种方。型的指针两种方。#include “stdio.h”#include “stdio.h”main()main() char char * *s=”s=”* * * * * * *”;”; for( ; for( ;* *s!=0;s+)s!=0;s+) puts(s);putchar(n);puts(s);putchar(n); 例例7.47.4用指向字符串用指向字符串的指针输出一的指针输出一个三角形个三角形*0s s结果为:结果为:* * * * * * * * * * * * * * * * * * * * * *2323用指针操作字符串用指针操作字符串第第七七章章main()
30、main() int slen; int slen; char char * *s=“123456”;s=“123456”; slen=strlen(?)slen=strlen(?); printf( ? );printf( ? ); 测试字符串的长度函数测试字符串的长度函数例例7.57.5int strlen(char int strlen(char * *s)s) int len=0; int len=0; while(while(* *s+) len+s+) len+; return (len); return (len); S S每向后移一个字符每向后移一个字符就计数一次,直到就计数一
31、次,直到s s指向串结束符为止指向串结束符为止1234560s s s ss ss ss ss ss s2424指针操作字符串举例指针操作字符串举例第第七七章章 / /* *拷贝源串拷贝源串srcsrc到目的串到目的串destdest* */ / void strcpy(char void strcpy(char * *dest,char dest,char * *src) src) while(while( (* *dest+=dest+=* *src+)!=0src+)!=0) ); ; 说明:说明:destdest和和srcsrc是两个指向字符串的指针。函数是两个指向字符串的指针。函数调
32、用时,分别把目的字符串和源字符串的起始地址调用时,分别把目的字符串和源字符串的起始地址传给传给destdest和和srcsrc。然后把。然后把srcsrc指向的字符对应赋值到指向的字符对应赋值到destdest所指向的空间,接着各自移动一个字符空间,所指向的空间,接着各自移动一个字符空间,进行下一个字符的赋值,直到遇到空字符进行下一个字符的赋值,直到遇到空字符00。 字符串拷贝字符串拷贝例例7.67.62525指针操作字符串举例指针操作字符串举例第第七七章章 int strcmp(char int strcmp(char * *s,char s,char * *t)t) while while
33、( (* *s=s=* *t)t) if( if(* *s=0) return 0; s=0) return 0; s+;t+; s+;t+; return return( (* *s-s-* *t)t); ; 对两个字符串中的字符一一进行比较,若对两个字符串中的字符一一进行比较,若两个字符串中的字符完全相同,返回两个字符串中的字符完全相同,返回0 0;若两个字;若两个字符串中有不同的字符,返回最先出现不同的两个符串中有不同的字符,返回最先出现不同的两个字符的差值。字符的差值。例例7.77.7main()main() sstrcmp(“abc”,”acd”)strcmp(“abc”,”acd”
34、)2626指针操作字符串举例指针操作字符串举例第第七七章章 char strrev(char char strrev(char * *s)s)char char * *headhead=s=s,* *tail; tail; char temp; char temp; tailtail=s+(strlen(s)-1); =s+(strlen(s)-1); while(headtail) while(head-成员名;成员名;其中其中-称为指向运算符,如:称为指向运算符,如: struct workertypestruct workertype* *currnode;currnode; printf(n enter worker no:“); printf(n enter worker no:“); gets(numstr); gets(numstr); currnode-workno=atol(numstr); currnode-workno=atol(numstr); 3030指向结构类型的指针指向结构类型的指针第第七七章章#include #include Sub(int x,int y,int Sub(int x,int y,int * *z)z) * *z=y-x; z=y-x; main()main() int a,b,c; int a,b,c
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 二零二五年度货车司机劳动合同(含货物保险及索赔流程)
- 2025年度游艇转让与船舶市场推广合作合同
- 2025年度海域旅游开发租赁合同书
- 二零二五年度农产品销售提成与品牌溯源合同
- 二零二五年度沿街商铺租赁服务合同(含公共区域使用权)
- 2025年度房地产项目法律尽职调查服务合同
- 2025年度健身俱乐部租赁合同租金调整及会员服务补充协议
- 2025年仓储租赁服务合同范本
- 航空航天股权转让居间合同
- 玩具的购销合同
- 江苏中国中煤能源集团有限公司江苏分公司2025届高校毕业生第二次招聘6人笔试历年参考题库附带答案详解
- 【语文】第23课《“蛟龙”探海》课件 2024-2025学年统编版语文七年级下册
- 北师版七年级数学下册第二章测试题及答案
- 2025年全体员工安全意识及安全知识培训
- 2025警察公安派出所年终总结工作汇报
- 机动车检测站新换版20241124质量管理手册
- 2024年决战行测5000题言语理解与表达(培优b卷)
- 中国游戏发展史课件
- 2025年慢性阻塞性肺疾病全球创议GOLD指南修订解读课件
- 工程数学试卷及答案
- 《PLC应用技术(西门子S7-1200)第二版》全套教学课件
评论
0/150
提交评论