《C语言学习文档第08章指针(培训)(共30张).pptx》由会员分享,可在线阅读,更多相关《C语言学习文档第08章指针(培训)(共30张).pptx(30页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、2.2.数据在内存中的存储方式数据在内存中的存储方式: : 按数据类型在内存为其分配一定数量的按数据类型在内存为其分配一定数量的存储单元存储单元( (字节字节) )。1.1.内存单元的地址内存单元的地址: : 计算机的内存是以字节为单位的一片连续的计算机的内存是以字节为单位的一片连续的存储空间,每一个字节都有一个编号,这个存储空间,每一个字节都有一个编号,这个编号就称为内存地址编号就称为内存地址3.3.内存单元的内容:内存单元的内容: 即变量的值。即变量的值。例如有定义例如有定义: short int a,b; char c; float x; 变量变量a,b,c,x的内存分配的内存分配情况情
2、况:abxc200020012002200320042005200620072008 每个变量的地址是指该变量所占存储单元的每个变量的地址是指该变量所占存储单元的第一个字节的地址,称为指针。第一个字节的地址,称为指针。4. 4. 计算机中数据存取方式计算机中数据存取方式A A、变量的、变量的“直接访问直接访问”方式:方式: 按变量的地址存取变量值的方式。按变量的地址存取变量值的方式。( (见下图见下图) )i20003直接访问直接访问: :编译器自动完成编译器自动完成3i20002000pointer间接访问方式示意图间接访问方式示意图: 将将变量的地址变量的地址放在另一个特殊的变量中,先到另
3、放在另一个特殊的变量中,先到另一个变量所表示的存储单元中取得变量的地址,再一个变量所表示的存储单元中取得变量的地址,再由变量的地址找到变量并进行数据存取由变量的地址找到变量并进行数据存取( (见下图见下图) )。b.b.变量的变量的“间接访问间接访问”方式方式变量变量pointer为指针变量为指针变量, ,存放的是变量存放的是变量i i的的内存地址内存地址, ,我们说我们说pointer指向指向 i i。6.指针的概念:指针的概念:一个变量的首地址称为该变量的指针。一个变量的首地址称为该变量的指针。用来专门存储用来专门存储变量指针变量指针的变量称为指针变量。的变量称为指针变量。一一. . 指针
4、变量的定义指针变量的定义1. 定义方式:定义方式: 类型标识符类型标识符 *指针变量名指针变量名1,*指针变量名指针变量名2 ;例:例:float *p1; (定义了定义了p1为指向实型变量的指针变量为指向实型变量的指针变量) char *p2; (定义了定义了p2为指向字符型变量的指针变量为指向字符型变量的指针变量) 标识符前面的标识符前面的“* *”,表示该变量为指针,表示该变量为指针 变量。但指针变量名是变量。但指针变量名是* *后面的名字(不包后面的名字(不包括括“* *”)。)。3.3.说明说明2. 指针变量的指针变量的三三要素要素:v指针变量的指针变量的基类型基类型: 和其所指变量
5、的类型一致;和其所指变量的类型一致;v指针变量的指针变量的值值:另一个变量在内存的地址;另一个变量在内存的地址;v指针变量的指针变量的名字名字:符合用户标识符规则。符合用户标识符规则。 指针变量名指针变量名=某一地址某一地址;8.3.8.3.指针变量的赋值指针变量的赋值方式方式1: 指针变量名指针变量名=&变量名变量名;方式方式2: 指针变量名指针变量名=另一已经赋值的指针变量另一已经赋值的指针变量;方式方式3: 通过标准的库函数(通过标准的库函数(malloc和和calloc在内存中开辟动态存储在内存中开辟动态存储单元)单元)i的地址的地址pi的值的值iqi的地址的地址例如例如: int i
6、,*p,*q; p=&i; /*方式方式1*/ q=p; /*方式方式2*/示示意意图图说明:给指针变量赋说明:给指针变量赋“空空”值值除了给指针变量赋地址值外,还可以给指针变量赋除了给指针变量赋地址值外,还可以给指针变量赋NULLNULL值。值。如:如:p=Nullp=Null;NullNull是在是在stdio.hstdio.h头文件中定义的预定义符。在使用前必须头文件中定义的预定义符。在使用前必须使用预定义行:使用预定义行:#include #include 。NullNull的代码值为的代码值为0 0,当执行以上赋值语句后,称当执行以上赋值语句后,称p p为空指针。等价于:为空指针。等
7、价于:p=0 ; p=0 ; 或或 p=0 p=0注意:这时指针注意:这时指针p p不是指向地址为不是指向地址为0 0的存储单元,而是一个的存储单元,而是一个具有一个确定的值具有一个确定的值“空空”。企图通过一个空指针去访问一。企图通过一个空指针去访问一个存储单元,将会得到一个出错信息。个存储单元,将会得到一个出错信息。1. 1.已知已知 int a=3, a int a=3, a的地址为的地址为10011001,则,则&a= &a= ?100110012. 2.设有定义:设有定义:float x; float x; 则以下对指针变量则以下对指针变量p p进行定义且赋初值的语进行定义且赋初值的
8、语句中正确的是:句中正确的是:a) float a) float * *p=1024; b) int p=1024; b) int * *p=(float)x; c) float p=&x d) float p=(float)x; c) float p=&x d) float * *p=&xp=&xD D4. 4.有以下程序段有以下程序段#include #include main()main() int n, int n,* *p=NULL;p=NULL; * *p=&n;p=&n; scanf(“%d”,&p); scanf(“%d”,&p); printf(“%dn”,p); print
9、f(“%dn”,p); 该程序试图通过该程序试图通过P P为变量为变量n n读入数据并输出,但程序有多出错误,读入数据并输出,但程序有多出错误,以下语句正确的是:以下语句正确的是:a.int n,a.int n,* *p=NULL b.p=NULL b.* *p=&n p=&n c.scanf(“%d”,&p) d.printf(“%dn”,p);c.scanf(“%d”,&p) d.printf(“%dn”,p);A A8.4.8.4.对指针变量的操作对指针变量的操作1. 1.通过指针来引用一个存储单元通过指针来引用一个存储单元 C C语言提供了一个称作语言提供了一个称作“间接访问运算符间接
10、访问运算符”(”(间接运算符)的单目间接运算符)的单目运算符:运算符:“* *”,当指针变量有确切的地址值时,就可以通过间接,当指针变量有确切的地址值时,就可以通过间接访问运算符引用该地址指向的存储单元。访问运算符引用该地址指向的存储单元。如:如: int int * *p,i=10,j;p,i=10,j; p=&i; p=&i; j= j=* *p; p; 说明:把说明:把p p所指向的存储单元(所指向的存储单元(i i)的值赋给)的值赋给j j,* *p p代表代表p p所指向的所指向的变量变量i i,以上语句等价于:,以上语句等价于: j=i j=i;分析以下表达式的含义:分析以下表达式
11、的含义:j=j=* *(&i); j=(&i); j=* *p+1;p+1;* *p=100; p=100; * *p+=1;p+=1;+* *p; (p; (* *p)+;p)+; int int * *p,i=10,j;p,i=10,j; p=&i; p=&i; j= j=* *p; p; 例子:例例子:例8.18.12.算术运算算术运算(移动指针)移动指针) 例如例如: int *p,i; char *q , c; p=&i;q=&c;.i10001001100220002001cpq.i10001001100220002001cpq / /* *运算示例运算示例* */ / p+;q+
12、; 对指针进行加减运算时,数字对指针进行加减运算时,数字“1”“1”不代表十进制整数不代表十进制整数“1”“1”,即不是移动一个字节,而是移动一个存储单元长度。即不是移动一个字节,而是移动一个存储单元长度。例如例如:右图右图1 pq为为假。假。.i10001001100220002001cpq.400040014002400340184019pqa0a1a9例如例如:右图右图2int a10;int *p,*q;p=&a0; /*或或p=a;*/q=&a9;/*或或q=a+9;*/求求pq为真为假为真为假?2.比较运算比较运算例例 main()int a,b;int *pointer_1,*p
13、ointer_2;a=100;b=10;pointer_1=&a;pointer_2=&b; printf (%d,%dn,a,b);printf(%d,%dn,*pointer_1,*pointer_2);程序运行结果:程序运行结果: 100,10 100,10思考:思考:1.若已执行了若已执行了“pointer_1=&a”,则:则: “&*pointer_1”的含意是什么?的含意是什么? (答:相当于答:相当于&a )2. *&a的含意是什么的含意是什么? (答:答:a )3. (*pointer_1)+相当于什么相当于什么? (答:答:a+ )例例对输入的两个整数按大小顺序输出对输入的两
14、个整数按大小顺序输出main()int *p1,*p2,*p,a,b;a=5;b=9;p1=&a;p2=&b;&a59p1p2&bab(1 初始初始)2 执行执行p=p1后后&a5p1a&b9p2b&apif (ab) p=p1;p1=p2; p2=p; printf(a=%d,b=%dn,a,b); printf(max=%d,min=%dn,*p1,*p2);&b&b3 执行执行p2=p1后后&ap9p1p25ab4 执行执行p2=p后后5&a&b&a9pp1p2ab-指向指针变量的指针指向指针变量的指针.定义形式定义形式: 类型类型 *变量名变量名;例如例如: int i,*p,*q;
15、i=30; p=&i; q=&p;100020001000100120003000ipq 内存示意图内存示意图:指针的指针指针的指针国家等级考试练习:国家等级考试练习:1. 1.设有定义:设有定义:int n1=0,n2,int n1=0,n2,* *p=&n2,p=&n2,* *q=&n1,q=&n1,以下赋值语句中与以下赋值语句中与n2=n1;n2=n1;语句等价的是:语句等价的是:a. a. * *p=p=* *q; b.p=q c.q; b.p=q c.* *p=&n1 d. p=p=&n1 d. p=* *q qA A2. 2.若有说明语句:若有说明语句:double double
16、* *p,a;p,a;则能通过则能通过scanfscanf语句正确给输入语句正确给输入项读入数据的程序段是:项读入数据的程序段是:a. a.* *p=&a;scanf(“%lf”,p); b.p=&a;scanf(“%lf”,p); b.* *p=&a; scanf(“%f”,p);p=&a; scanf(“%f”,p);c.p=&a;scanf(“%lf”,c.p=&a;scanf(“%lf”,* *p); d.p=&a;scanf(“%lf”,p);p); d.p=&a;scanf(“%lf”,p);D D3. 3.已定义以下函数已定义以下函数int fun(int int fun(int
17、 * *p)p)return return * *p;p;funfun函数的返回值是:函数的返回值是:a. a.不确定的值不确定的值 b. b.一个整数一个整数 c. c.形参形参p p中存放的值中存放的值 d. d.形参形参p p的地址值的地址值 B B1. 1.形参为指针变量时实参和形参之间的数据传递形参为指针变量时实参和形参之间的数据传递 若函数的形参为指针类型,调用该函数时,对应的实参必须是若函数的形参为指针类型,调用该函数时,对应的实参必须是基类型相同的地址值或者是已指向某个存储单元的指针变量。基类型相同的地址值或者是已指向某个存储单元的指针变量。例例. .编写函数编写函数myadd
18、(int myadd(int * *a,int a,int * *b),b),函数中把指针函数中把指针a a和和b b所指向的存储所指向的存储单元中两个值相加,然后将和的值作为函数值返回。单元中两个值相加,然后将和的值作为函数值返回。#include #include int myadd( int int myadd( int * *a,int a,int * *b)b) int sum; int sum; sum= sum=* *a+a+* *b; b; return sum; return sum; main()main() int x,y,z; int x,y,z; printf(“en
19、ter x,y:”); printf(“enter x,y:”);scanf(“%d%d”,&x,&y);scanf(“%d%d”,&x,&y);z=myadd(&x,&y);z=myadd(&x,&y);printf(“%d+%d=%dn”,x,y,z);printf(“%d+%d=%dn”,x,y,z); 思考:如果在被调函数中改变形参的值将如何呢?思考:如果在被调函数中改变形参的值将如何呢?2. 2.通过传送地址值在被调用函数中直接改变调用函数中变量的值通过传送地址值在被调用函数中直接改变调用函数中变量的值#include “stdio.h”#include “stdio.h”Void
20、swap(int Void swap(int * *,int ,int * *); );Void main()Void main() int x=30,y=20; int x=30,y=20; printf(“(1) x=%d y=%dn”,x,y); printf(“(1) x=%d y=%dn”,x,y); Swap(&x,&y); Swap(&x,&y); printf(“(4) x=%d y=%dn”,x,y); printf(“(4) x=%d y=%dn”,x,y); Void swap(int Void swap(int * *a,int a,int * *b)b) int t;
21、 int t; printf(“(2) a=%d b=%dn”, printf(“(2) a=%d b=%dn”,* *a, a,* *b);b); t= t=* *a; a;* *a=a=* *b; b;* *b=t;b=t; printf(“(3) a=%d b=%dn”, printf(“(3) a=%d b=%dn”,* *a, a,* *b);b); 输出结果:输出结果:(1)(1) x=30 y=20 x=30 y=20(2)(2) a=30 b=20a=30 b=20(3)(3) a=20 b=30a=20 b=30(4)(4) (4) x=20 y=30(4) x=20 y=3
22、0void swap(int *x1,int *x2)void order(int *a,int *b)1. 一个函数可以带回整型值、实型值、字符一个函数可以带回整型值、实型值、字符型值,也可以带回指针类型的数据,即地址。型值,也可以带回指针类型的数据,即地址。 返回值是指针类型的函数,称为指针函数。返回值是指针类型的函数,称为指针函数。2. 一般定义形式为:一般定义形式为: 类型标识符类型标识符 *函数名(参数表);函数名(参数表); 例如:例如: int *a(int x,float y) 对于定义对于定义: int *a(int x, float y) va是函数名,调用它后能得到一个指
23、向整型数是函数名,调用它后能得到一个指向整型数据的指针(地址)。据的指针(地址)。vx,y是函数是函数a的形参。的形参。v这个函数前面有一个这个函数前面有一个*,表示此函数是指针类,表示此函数是指针类型函数(函数值是指针)。型函数(函数值是指针)。main()int a,b,*p; int *max( );scanf(“%d,%d”,&a,&b);p=max(a,b);printf(“max=%d”,*p); 指针函数应用举例指针函数应用举例 int *max(int x,int y)if(xy) return(&x);else return(&y);国家等级考试练习:国家等级考试练习:1. 1.以下叙述中错误的是:以下叙述中错误的是:a. a.改变函数形参的值,不会改变对应的实参改变函数形参的值,不会改变对应的实参b. b.函数可以返回地址值函数可以返回地址值c. c.可以给指针变量赋一个整数作为地址值可以给指针变量赋一个整数作为地址值d. d.当在函数的开头中包括头文件当在函数的开头中包括头文件stdio.hstdio.h时,可以给变量赋时,可以给变量赋NULLNULLC C演讲完毕,谢谢观看!