C语言程序设计——指针(完整版)课件.ppt
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_1.gif)
![资源得分’ title=](/images/score_05.gif)
《C语言程序设计——指针(完整版)课件.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计——指针(完整版)课件.ppt(80页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、为了说清楚什么是指针,必须弄清楚数据在内存中为了说清楚什么是指针,必须弄清楚数据在内存中是如何存储的,又是如何读取的。是如何存储的,又是如何读取的。 计算机中,所有的数据都是存放在存储器的内存计算机中,所有的数据都是存放在存储器的内存单元中的。一般把存储器中一个字节称为一个内存单元中的。一般把存储器中一个字节称为一个内存单元,不同数据类型所占用的内存单元数不等,如单元,不同数据类型所占用的内存单元数不等,如整型变量占整型变量占2个字节,字符变量占个字节,字符变量占1个字节等。个字节等。 为了正确地访问这些内存单元,必须为每个内存为了正确地访问这些内存单元,必须为每个内存单元编上号,根据一个内存
2、单元的编号即可准确地单元编上号,根据一个内存单元的编号即可准确地找到该内存单元。找到该内存单元。内存单元的编号,称为内存单元的编号,称为“地址地址” 。内存单元的内存单元的地址地址和内存单元的和内存单元的内容内容是两个不同的概念:是两个不同的概念:假设程序中定义了整型变量假设程序中定义了整型变量i,并赋值为,并赋值为3。编译时系统。编译时系统分配分配2000和和2001两个字节给变量两个字节给变量i,此时两个内存单元,此时两个内存单元的编号为单元的地址,其中存放的数据即是该单元的内的编号为单元的地址,其中存放的数据即是该单元的内容。容。两种访问方式:两种访问方式:直接访问方式:直接访问方式:在
3、程序中一般是通过变量名来对内存单元进行存取操作在程序中一般是通过变量名来对内存单元进行存取操作的,其实程序在编译后,已经将变量名转换成变量的地的,其实程序在编译后,已经将变量名转换成变量的地址,对变量值的存取都是通过地址进行的。址,对变量值的存取都是通过地址进行的。间接访问方式:间接访问方式: 将变量将变量i的地址存放在另一个变量中,的地址存放在另一个变量中,C语言规定,可语言规定,可以在程序中定义一种特殊的变量,用来存放地址。以在程序中定义一种特殊的变量,用来存放地址。假设定义一个变量假设定义一个变量p,用来存放整型变量的地址,它被,用来存放整型变量的地址,它被分配为分配为3010、3011
4、两个字节。两个字节。可以通过下面语句将可以通过下面语句将i的地址的地址(2000)存放到存放到p:p=&i; 对变量对变量i是访问,可直接访问,已知变量是访问,可直接访问,已知变量i的地址,根的地址,根据此地址直接对变量据此地址直接对变量i的存储单元进行存取访问;的存储单元进行存取访问; 也可间接访问,先找到存放变量也可间接访问,先找到存放变量i的地址的变量的地址的变量p,从,从其中得到变量其中得到变量i的地址,然后找到变量的地址,然后找到变量i的存储单元,对的存储单元,对它进行存取范围。它进行存取范围。 一个变量的地址称为该变量的一个变量的地址称为该变量的“指针指针”。如,地址。如,地址20
5、00是变量是变量i的指针。的指针。 C语言中,用一个变量存放指针语言中,用一个变量存放指针(地址地址),此变量称为,此变量称为指针变量指针变量,上述的变量,上述的变量p是指针变量,指针变量的值是是指针变量,指针变量的值是某个内存单元某个内存单元 的地址的地址(指针指针)。 严格地说,一个指针是一个地址,是一个常量;而一严格地说,一个指针是一个地址,是一个常量;而一个指针变量却可以被赋予不同的指针值,是变量。但通个指针变量却可以被赋予不同的指针值,是变量。但通常把指针变量简称指针。常把指针变量简称指针。指针变量的值不仅可以是变量的地址,也可以是其他数指针变量的值不仅可以是变量的地址,也可以是其他
6、数据结构的地址。据结构的地址。例如:在一个指针变量中可存放一个数组或一个函数的例如:在一个指针变量中可存放一个数组或一个函数的首地址。首地址。区别:区别:变量的指针变量的指针和和指针变量指针变量1.变量的指针就是变量的地址。变量的指针就是变量的地址。2.存放变量地址的变量是指针变量,它用来指向存放变量地址的变量是指针变量,它用来指向另一个变量。另一个变量。 为了表示指针变量和它所指向的变量之间的联系,为了表示指针变量和它所指向的变量之间的联系,在程序中用在程序中用“ * ”符号表示符号表示“指向指向”。 若已定义若已定义i_pointer为指针变量,则为指针变量,则* i_pointer是是i
7、_pointer所指向的变量,因此所指向的变量,因此* i_pointer也代表一个也代表一个变量,它和变量变量,它和变量i是同一回事。是同一回事。下面两个语句作用相同:下面两个语句作用相同:(1)i=3;(2) * i_pointer=3;第二个语句含义是将第二个语句含义是将3赋给指针赋给指针变量变量i_pointer所指向的变量所指向的变量i.一、一、 指针变量的定义指针变量的定义指针变量在使用前必须先定义,一般形式为:指针变量在使用前必须先定义,一般形式为: 类型说明符类型说明符 *指针变量名;指针变量名;其中,其中,*表示这是一个指针变量,表示这是一个指针变量,类型说明符类型说明符 表
8、示该指表示该指针变量所指变量的数据类型。针变量所指变量的数据类型。例如:例如:int *p1;(其中其中p1(而不是而不是 *p1)是一个指向整型变量的指针变量,是一个指向整型变量的指针变量,它的值是某个整型变量的地址。它的值是某个整型变量的地址。) float *p2;(其中其中p2是指向浮点型变量的指针变量是指向浮点型变量的指针变量)说明:说明:(1)指针变量名的构成原则是标识符,前面必须有指针变量名的构成原则是标识符,前面必须有“ * ” , 表示该变量的类型是指针型变量。表示该变量的类型是指针型变量。(2)在一个定义语句中,可以同时定义普通变量、数组、在一个定义语句中,可以同时定义普通
9、变量、数组、 指针变量。指针变量。(3)类型说明符说明的数据类型不是指针变量中存放的类型说明符说明的数据类型不是指针变量中存放的数据的数据类型,而是它数据的数据类型,而是它将要指向的变量或数组的数据将要指向的变量或数组的数据类型类型。因此,一个指针变量只能用来指向同种数据类型。因此,一个指针变量只能用来指向同种数据类型的其他变量或数组,不能时而指向一个浮点型变量,时的其他变量或数组,不能时而指向一个浮点型变量,时而指向一个整型变量。而指向一个整型变量。二、二、 指针变量的引用指针变量的引用 指针变量中只能存放变量的地址,绝不能存放任何指针变量中只能存放变量的地址,绝不能存放任何其他数据。其他数
10、据。例如:例如:int *p; p=2000; /*2000是一个整数而不是一个地址是一个整数而不是一个地址*/C语言提供两种有关的运算符:语言提供两种有关的运算符:(1)&:取地址运算符取地址运算符 (用来表示变量的地址用来表示变量的地址)(2)* :取内容运算符取内容运算符 (用来取其指向的内容,或称用来取其指向的内容,或称“间接间接 访问访问”运算符,或称指针运算符运算符,或称指针运算符)两种运算符都是单目运算符,其结合性都为自右向左,两种运算符都是单目运算符,其结合性都为自右向左,优先级别相同。优先级别相同。例如:例如:&a为变量为变量a的地址,的地址, *p为指针变量为指针变量p所指
11、向的内存单元的内容所指向的内存单元的内容 (即即p所指向的变量的值所指向的变量的值)。说明:说明:(1)设有指向整型变量的指针变量设有指向整型变量的指针变量p,若要把整型变量,若要把整型变量a的地址赋予的地址赋予p,有以下方式:,有以下方式: 指针变量初始化的方法:指针变量初始化的方法: int a; int *p=&a; 赋值语句的方法:赋值语句的方法: int a,*p; p=&a;(2)指针运算符指针运算符*和指针变量说明中的和指针变量说明中的指针说明符指针说明符*不是不是一回事。后者表示其后的变量是指针类型,前者则是一一回事。后者表示其后的变量是指针类型,前者则是一个运算符用以表示指针
12、变量所指的变量。个运算符用以表示指针变量所指的变量。说明:说明:(3)如果已执行了语句如果已执行了语句p=&a; ,则:,则: &*p:先进行:先进行*p的运算,即是变量的运算,即是变量a,再执行,再执行&运算运算, 即变量即变量a的地址。的地址。因此因此&*p与与&a相同。相同。 *&a:先进行:先进行&a的运算,即得的运算,即得a的地址,再执行的地址,再执行*运运 算算, 即即&a所指向的变量,即变量所指向的变量,即变量a。 因此因此*&a与与a相同。相同。#include void main( )int a,b; int *p1,*p2; a=100; b=10; p1=&a; p2=&
13、b; printf(“%d,%d n”,a,b); printf(“%d,%d n”,*p1,*p2);例例: : 通过指针变量访问整型变量。通过指针变量访问整型变量。 运行结果:运行结果:100,10100,10#include void main( )int a=5,b,c,*p; p=&a; b=*p; c=a+*p; printf(“%d,%d n”,b,c);例例: : 通过指针变量进行运算。通过指针变量进行运算。 运行结果:运行结果:5,10说明:说明:(1) 指针变量的运算种类也是有限的,它只能进行赋值指针变量的运算种类也是有限的,它只能进行赋值运算和部分算术运算及关系运算。运算
14、和部分算术运算及关系运算。(2) 指针变量还可以赋空值,其赋空值后,则可以使用,指针变量还可以赋空值,其赋空值后,则可以使用,只是它不指向具体的变量而已。只是它不指向具体的变量而已。 例如:例如:#define NULL 0 int *p=NULL;三、三、 指针变量作函数参数指针变量作函数参数#includeswap(int x,int y)int t; t=x; x=y; y=t;void main( )int a=3,b=5; if(ab) swap(a,b); printf(“a=%d,b=%d n”,a,b);C C语言是通过传值将参数传递给函数的,对被调函数来说,语言是通过传值将参
15、数传递给函数的,对被调函数来说,没有直接的方法来改变主调函数内的变量的值。没有直接的方法来改变主调函数内的变量的值。 例:对两个整数按大小顺序输出。例:对两个整数按大小顺序输出。运行结果:运行结果:a=3,b=5#includeswap(int *x,int *y)int t; t=*x; *x=*y; *y=t;void main( )int a=3,b=5; if(ab) swap(&a,&b); printf(“a=%d,b=%d n”,a,b);使主调函数传递指向要被改变量的指针,即可使被调函数使主调函数传递指向要被改变量的指针,即可使被调函数能改变主调函数的参数值。能改变主调函数的参
16、数值。例:对两个整数按大小顺序输出。例:对两个整数按大小顺序输出。运行结果:运行结果:a=5,b=3 一个数组是由连续的一块内存单元组成的,数一个数组是由连续的一块内存单元组成的,数组名即是这块连续内存单元的首地址。组名即是这块连续内存单元的首地址。 一个变量有地址,一个数组包含若干元素,每一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有个数组元素都在内存中占用存储单元,它们都有相应的地址。相应的地址。指针变量既然可以指向变量,当然指针变量既然可以指向变量,当然也可以指向数组元素也可以指向数组元素(把某一元素的地址放到一(把某一元素的地址放到一个指针变量中)。
17、所谓个指针变量中)。所谓数组元素的指针就是数组数组元素的指针就是数组元素的地址元素的地址。 指向数组的指针变量称为指向数组的指针变量称为数组指针变量数组指针变量。其一般形式为:其一般形式为:类型说明符类型说明符 * *指针变量名;指针变量名;其中,类型说明符表示所指数组的类型。从中可其中,类型说明符表示所指数组的类型。从中可以看出指向数组的指针变量和指向普通变量的指以看出指向数组的指针变量和指向普通变量的指针变量的说明是相同的。针变量的说明是相同的。一、指向数组元素的指针一、指向数组元素的指针说明:说明:设有实型数组设有实型数组a,指向,指向a的指针变量为的指针变量为pa,则有以下关系:,则有
18、以下关系:pa,a,&a0均指向同一内存单元,它们是数组均指向同一内存单元,它们是数组a的首的首地址,即是地址,即是a0的首地址;的首地址;pa+1,a+1,&a1均指向元素均指向元素a1的地址;的地址;pa+i,a+i,&ai均指向元素均指向元素ai的地址。的地址。*(pa+i),*(a+i)是是pa+i 或或a+i 所指向的数组元素,即所指向的数组元素,即ai注意:注意:pa是变量,是变量,a与与&ai都是常量都是常量(地址地址)。引入指针变量后,可以用两种方法来访问数组元素:引入指针变量后,可以用两种方法来访问数组元素:1.下标法:采用下标法:采用ai形式访问数组元素:形式访问数组元素:
19、2.指针法:采用指针法:采用*(pa+i)或或*(a+i)形式,用间接访问的形式,用间接访问的 方法来访问数组元素,即通过指向数组元方法来访问数组元素,即通过指向数组元 素的指针找到所需的元素。素的指针找到所需的元素。例例:(1)int a; (2)int a; 初始化赋值初始化赋值 int *p=&a0; int *p=a; (3)int a; (4)int a; 赋值语句赋值赋值语句赋值 int *p; int *p; p=&a0; p=a;按按C C语言的规定:如果指针语言的规定:如果指针p p已指向数组中的一个元素,已指向数组中的一个元素,则则p+1p+1指向同一数组中的下一个元素指向
20、同一数组中的下一个元素,而不是将,而不是将p p的值的值( (地址值地址值) )简单地加简单地加1 1。例如:例如:数组元素是数组元素是floatfloat型,每个元素占型,每个元素占4 4个字节,则个字节,则p+1p+1意味意味着使着使p p的值的值( (地址值地址值) )加加4 4个字节,以使它指向下一个元个字节,以使它指向下一个元素,此时,素,此时,p+1p+1所代表的地址实际上是所代表的地址实际上是p+1 dp+1 d,d d是一是一个数组元素所占的字节数。个数组元素所占的字节数。二、通过指针引用数组元素二、通过指针引用数组元素(1)下标法下标法 #include void main(
21、 )int a10,i; for(i=0;i10;i+) scanf(“%d”,&ai); printf(“n”); for(i=0;i10;i+) printf(“%d”,ai); printf(“n”);例:输出数组中的全部元素。例:输出数组中的全部元素。( (设一个设一个a a数组,整型,有数组,整型,有1010个元素,要输出各元素的值有个元素,要输出各元素的值有3 3种方法种方法) )(2)通过数组名计算数组元素通过数组名计算数组元素 的地址,找出元素的值的地址,找出元素的值 for(i=0;i10;i+) printf(“%d”,*(a+i);(3)用指针变量指向数组元素用指针变量指
22、向数组元素 for(p=a;p(a+10);p+) printf(“%d”,*p);#include void main( )int a10,i,*p; p=a; for(i=0;i10;i+) scanf(“%d”,p+); printf(“n”); for(i=0;ipa表示表示qa处于高地址位置;处于高地址位置;pa处于低地址位置;处于低地址位置;#include void main( )int a5,i,*pa,*qa; pa=qa=a; for(i=0;i5;i+) *qa=i; qa+; /*将指针将指针qa指向指向a数组中的下一元素数组中的下一元素 */ for(i=0;paqa
23、;i+) printf(“a%d=%-2d”,i,*pa); pa+; 例:通过指针变量的运算输出例:通过指针变量的运算输出a a数组中的数组中的5 5个元素。个元素。运行结果:运行结果:a0=0 a1=1 a2=2 a3=3 a4=42.指针变量的自增自减运算指针变量的自增自减运算如果先使如果先使p指向数组指向数组a的首元素的首元素(即即p=a),请分析:,请分析:(1)p+:使:使p指向数组指向数组a的下一元素,即的下一元素,即a1。(2)*p+:由于元素符:由于元素符+和和*同优先级,结合方向为自同优先级,结合方向为自 右向左,因此它等价于右向左,因此它等价于*(p+)。(3)*(p+)
24、 与与*(+p)作用不同。作用不同。(4)(*p)+:表示:表示p所指向的元素值加所指向的元素值加1,它等价于,它等价于 (a0)+。若。若a0=3,则,则(*p)+的值为的值为4。 注意:是元素值加注意:是元素值加1,而不是指针值加,而不是指针值加1。前面已介绍过可以用数组名作函数的参数,例如:前面已介绍过可以用数组名作函数的参数,例如:void f(int arr ,int n) void main( ) int array10; f(array,10); f (int arr , int n)但在编译时是将但在编译时是将arr按指针变量处理的,相当于将函数按指针变量处理的,相当于将函数f
25、的首部写成的首部写成f (int *arr, int n)以上两种写法是等价的。以上两种写法是等价的。三、用数组名和数组指针变量作函数参数三、用数组名和数组指针变量作函数参数以变量名和数组名、数组指针变量作为函数参数的以变量名和数组名、数组指针变量作为函数参数的比较:比较:实参类型变量名数组名要求形参的类型变量名数组名或指针变量传递的信息变量的值 实参数组的首地址通过函数调用能否改变实参的值不能能 归纳起来,如果有一个实参数组,想在函数中改变归纳起来,如果有一个实参数组,想在函数中改变此数组中的元素的值,实参与形参的对应关系有以下此数组中的元素的值,实参与形参的对应关系有以下种情况:种情况:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言程序设计 指针 完整版 课件
![提示](https://www.taowenge.com/images/bang_tan.gif)
限制150内