版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第五章第五章 指针指针【要求要求】掌握指针的概念掌握指针的概念掌握指针对变量、数组的引用方法掌握指针对变量、数组的引用方法理解二维数组中行指针的概念理解二维数组中行指针的概念掌握指针数组、指向一维数组指针的使用方法掌握指针数组、指向一维数组指针的使用方法了解二级指针的概念了解二级指针的概念5。1引言引言为什么要使用指针?指针是C语言中的一个重要的概念,也是C语言的一个重要特色。1、可以提高程序的执行效率。2、利用指针动态分配内存,可以更合理使用内存。3、可以使程序的结构更加简洁、紧凑和清晰。4、可以方便的使用数组。5、在调用函数时可以获得一个以上的结果。5.2地址和指针为了说清楚什么是指针,必
2、须弄清楚数据在内存中是如何存储的,又是如何读取的。 、按变量地址存取变量值的方式称为“直接访问直接访问”方式 int i=3, j=6,k;print(,k);例如:例如:内存区的每一个字节有一个编号,这就是“地址地址” 。如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元。 5.2地址和指针;执行过程:(1)根据变量名与地址的对应关系,找到I,j的地址(2)分别从I,j的地址单元中取出3和6,再相加;(3)将结果存放到变量K中。变量名地址编译2、 “间接访问间接访问” 即将变量的地址存放在另一个变量中。在语言中,指针是一种特殊的变量,它是存放地址的。在语言中,指针
3、是一种特殊的变量,它是存放地址的。int i,*i_pointeri_pointer=&i;将的地址(2000)存放到i_pointer中。这时, i_pointer的值就是(2000) ,即变量所占用单元的起始地址。要存取变量的值,可以采用间接方式:先找到存放“的地址”的变量i_pointer ,从中取出的地址(2000),然后到2000 、 200字节取出的值.3、地址运算符C语言中的两个地址运算符& *& 取地址运算符间接访问运算符例: int i, *ip; ip=&i; *&i=i;5.2地址和指针int a5,*ip,k;ip=a;k=*(a
4、+1);一个变量的地址称为该变量的“指针指针”。例如,地址2000是变量的指针。如果有一个变量专门用来存放另一变量的地址(即指针),则它称为“指针变量指针变量”。上述的i_pointer就是一个指针变量。指针和指针变量的概念:指针和指针变量的概念:5.3指针变量的定义和引用5.3.1 定义一个指针变量定义一个指针变量定义指针变量的一般形式为类型标识符(基类型)类型标识符(基类型) *指针变量名;指针变量名;5.3指针变量的定义和引用1、指针变量前面的“*”,表示该变量的类型为指针型变量。例: float *pointer_1;指针变量名是pointer_1 ,而不是* pointer_1 。
5、2、 在定义指针变量时必须指定基类型。需要特别注意的是,只有整型变量的地址才能放到指向整型变量的指针变量中。下面的赋值是错误的 float a; int * pointer_1; pointer_1=&a; /* 将float型变量的地址放到指向整型变量的指针变量中,错误 */下面都是合法的定义:float *pointer_; / pointer_是指向float型变量的指针变量char *pointer_; /pointer_是指向字符型变量的指针变量5.3.1 定义一个指针变量定义一个指针变量5.3.2 指针变量的初始化指针变量的初始化基本类型的变量、数组如何初始化?指针变量的初
6、始化1、在定义的同时初始化类型标识符 *变量名=地址int i, *ip=&i;2、先定义后初始化int i=5,*ip;ip=&i;5.3.3 指针变量的引用指针变量的引用 例例10. 通过指针变量访问整型变量通过指针变量访问整型变量#include voidmain ( ) int ,; int*pointer, *pointer; ; pointer_; pointer_; printf(%,%,); printf(%,%,*pointer_, *pointer_); 通过间接访问运算符*思考:两个printf输出的结果是否相同?对“”和“*”运算符说明:如果已执行了语句
7、 pointer_;(1)* pointer_的含义是什么?“”和“*”两个运算符的优先级别相同,但按自右而左方向结合,因此先进行* pointer_的运算,它就是变量,再执行运算。因此,* pointer_与相同,即变量a的地址。如果有pointer_2 * pointer_ ;它的作用是将(的地址)赋给pointer_2 ,如果pointer_2原来指向,经过重新赋值后它已不再指向了,而指向了。5.3.3 指针变量的引用指针变量的引用 (2) *的含义是什么?先进行运算,得的地址,再进行*运算。即所指向的变量,也就是变量a。*和*pointer_的作用是一样的,它们都等价于变量。即*与等价
8、。(3) (*pointer_)相当于。注意括号是必要的,如果没有括号,就成为了*pointer_,从附录可知:+和*为同一优先级别,而结合方向为自右而左,因此它相当于*(pointer_)。由于+在pointer_1的右侧,是“后加”,因此先对pointer_的原值进行*运算,得到的值,然后使pointer_的值改变,这样pointer_不再指向了。5.3.3 指针变量的引用指针变量的引用 例例10 . 2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main() int =10,=20,t=0; printf(“a=%d,b
9、=%d”,a,b) if(); ; ;printf(=,=,); 例例10 . 2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main() int *1,*2,*,=10,=20; 1; if();printf(=,=,); printf(max=,min=,*1,*2); 例例10 . 2 输入和两个整数,按先大后小的顺序输出输入和两个整数,按先大后小的顺序输出 和。和。#include void main() int *1,*2,t,=10,=20; 1; if()t*;*;*;printf(=,=,); printf(m
10、ax=,min=,*1,*2); 5.4.1、取地址运算(、取地址运算(&)和取内容运算()和取内容运算(*)& 和和 * 都是单目运算符。都是单目运算符。运算符运算符 & 用来取操作对象的地址。用来取操作对象的地址。运算符运算符 * 用来取指针操作对象的内容。用来取指针操作对象的内容。例如:例如:int *ipa , a10 , b;ipa=&a;b=*ipa;5.4.2、指针变量的赋值运算、指针变量的赋值运算指针变量的赋值运算是将一个变量的地址赋指针变量的赋值运算是将一个变量的地址赋给指针变量给指针变量。例如例如:int *ip1,*ip2,x,a10;ip
11、1=&x; /一个变量的地址赋给指针变量一个变量的地址赋给指针变量ip2=a; /一个数组名赋给指针变量一个数组名赋给指针变量ip2=ip1; /一个指针变量赋给另一个指针变量一个指针变量赋给另一个指针变量关于数组元素与指针:关于数组元素与指针:ip2=a3;ip2=&a3; 指针的算术运算。例如:指针的算术运算。例如:ip+,ip-,ip+n,ip-n,ip+=n指针的变量加(减)一个整数指针的变量加(减)一个整数n的运算,并不是指的运算,并不是指针变量的地址加(减)一个整数针变量的地址加(减)一个整数n,而是将指针由当,而是将指针由当前所指向的位置向后(向前)移动前所指向的
12、位置向后(向前)移动n个字节位置,即个字节位置,即指向其基本类型的后指向其基本类型的后n个)(前个)(前n个)元素的位置。个)元素的位置。5.4.3指针的移动是指指针变量加(或减)一个整数以及指针为题的自增或自减例:例:int a10,20,30; int *ipa=a; ipa+=2; ipa-; ipa指向哪个元素的位置?指向哪个元素的位置?注:注: ipan的实际地址是的实际地址是ipa+n*sizeof(数据类型数据类型)5.4.3指针的移动ipa分别指向什么地址?5.4.4、指针变量的相减运算、指针变量的相减运算指向同一数组的两个指针变量可以相减,其差表示指向同一数组的两个指针变量可
13、以相减,其差表示这两个指针变量所指数组元素之间相差的个数。这两个指针变量所指数组元素之间相差的个数。#includeVoid main() int a=1,2,3,4,5,6,7,8,9,10; int *ip1=a,*ip2=&a9; printf(“ip1=%x,ip2=%x,ip1-ip2=%d”,ip1,ip2,ip1-ip2);3.4.5 指针的关系运算指针的关系运算一般情况下,当两个指针指向同一数组时,可在一般情况下,当两个指针指向同一数组时,可在关系表达式中对两个指针进行关系运算。指针的关系运关系表达式中对两个指针进行关系运算。指针的关系运算有:算有:用于比较两个指针所指
14、向的地址的大小关系:用于比较两个指针所指向的地址的大小关系=!=:用于判断两指针是否指向同一地址:用于判断两指针是否指向同一地址5.5 数组与指针 一个变量有地址,一个数组包含若干元素,每个数组元素都在内存中占用存储单元,它们都有相应的地址。指针变量既然可以指向变量,当然也可以指向数组元素(把某一元素的地址放到一个指针变量中)。所谓数组元素的指针就是数组元数组元素的指针就是数组元素的地址素的地址。 定义一个指向数组元素的指针变量的方法,与以前介绍的指向变量的指针变量相同。例如: ;*; ;5.5.1 5.5.1 指向一维数组的指针变量指向一维数组的指针变量引用一个数组元素,可以用:()() 下
15、标法,如形式;下标法,如形式;()() 指针法,如指针法,如*()或()或*()()。其中是数组名,是指向数组元素的指针变量,其初值。5.5.1 5.5.1 指向一维数组的指针变量指向一维数组的指针变量(1)下标法下标法#include void main() int ; int;for(;)scanf(,); printf();for(;)printf(,); 例例10.5 输出数组中的全部元素输出数组中的全部元素 5.5.1 5.5.1 指向一维数组的指针变量指向一维数组的指针变量(2) 通过数组名计算数组元素地址,找出元素的值。#include voidmain() int ; int
16、;for(; )scanf(,);printf(); for(;) printf(,*(); 5.5.1 5.5.1 指向一维数组的指针变量指向一维数组的指针变量(3) 用指针变量指向数组元素。#include void main() int ; int *,; for(;) scanf(,); printf(); for(;();) printf( ,*); 5.5.1 5.5.1 指向一维数组的指针变量指向一维数组的指针变量5.5.1 5.5.1 指向一维数组的指针变量指向一维数组的指针变量#include #define N 5Void main()int xN,*p=x,*q=x+N-
17、1,j,t;printf(“Enter %d number:”,N);for(j=0;jN;j+)scanf(“%d”,p+j);for(;pq;p+,q-) t=*p; *p=*q; *q=t; printf(“nResult is :”);for(j=0,p=x;jN;j+)printf(“%d”,*(p+j);5.5.2 二维数组与指针二维数组与指针 用指针变量可以指向一维数组中的元素,也可以指向多维数组中的元素。但在概念上和使用上,多维数组的指针比一维数组的指针要复杂一些。 1. 二维数组元素的地址二维数组元素的地址先回顾一下多维数组的性质,可以认为二维数组是“数组的数组”,例 :定义
18、定义int a34=1,3,5,7,;则二维数组a是由3个一维数组所组成的。设二维数组的首行的首地址为 ,则表表 示示 形形 式式含义含义地地 址址a a 二维数组名,指向一维数组二维数组名,指向一维数组a0a0,即,即0 0行首地行首地址址20002000a0a0, ,* *(a+0),(a+0),* *a a0 0行行0 0列元素地址列元素地址20002000a+1a+1,&a&a1 11 1行首地址行首地址20082008a a1 1, ,* *(a+1)(a+1)1 1行行0 0列元素列元素a10a10的地址的地址20082008a1+2,a1+2,* *(a+1)+2
19、,(a+1)+2,&a12&a121 1行行2 2列元素列元素a12 a12 的地址的地址20122012* *(a1+2),(a1+2),* *( (* *(a+1)+2),(a+1)+2),a12a121 1行行2 2列元素列元素a a1 12 2的值的值元素值为元素值为1313int a34=1,3,5,7,;2 . 指向多维数组元素的指针变量指向多维数组元素的指针变量在了解上面的概念后,可以用指针变量指向多维数组的元素。(1) 指向数组元素的指针变量指向数组元素的指针变量例例: : 用指针变量输出二维数组元素的值用指针变量输出二维数组元素的值 #include void
20、 main() int 341,3,5,7,9,11,13,15,17,19,21,23; int*; for(;) () printf(); printf(,*); (2) 指向由个元素组成的一维数组的指针变量指向由个元素组成的一维数组的指针变量例例10.13 10.13 出二维数组任一行任一列元素的值出二维数组任一行任一列元素的值#include void main ( ) int 1,3,5,7,9,11, 13,15,;int (*),; ;scanf( ,); printf(, ,*(*(); 运行情况如下:, (本行为键盘输入),行指针5.5.3 通过行指针变量引用二维数组元素通过
21、行指针变量引用二维数组元素 指针指针指针变量指针变量行指针变量行指针变量(指向一维数组的指针):指向由N个元素组成的一维数组的指针变量 定义一般形式: 类型标识符类型标识符 (*行指针变量名)行指针变量名)常量表达式常量表达式例: int (*ip)4,a34; ip=a;表明了指向的一维数表明了指向的一维数组元素的个数组元素的个数思考:用IP如何去访问二维数组?5.5.3 通过行指针变量引用二维数组元素通过行指针变量引用二维数组元素 问题:用IP如何去访问二维数组a?1、ip访问a的第i行 ip+i2、 ip访问a的第i行第j列 ipija+i第i行第j列元素的地址第i行第j列的元素&
22、;(*(p+i)j(*(p+i)j*(p+i)+j*(*(p+i)+j)pi+j*(pi+j)&pijPij5.5.3 通过行指针变量引用二维数组元素通过行指针变量引用二维数组元素 例:输入输出一个二维数例:输入输出一个二维数1、使用下标、使用下标#include#define N 3#define M 4Void main()int I,j,aNM;for(i=0;iN;i+) for(j=0;jM;j+) scanf(“%d,&aij);for(i=0;iN;i+) for(j=0;jM;j+) printff(“%d aij);5.5.3 通过行指针变量引用二维数组元素通
23、过行指针变量引用二维数组元素 例:输入输出一个二维数例:输入输出一个二维数2、使用行指针、使用行指针#include#define N 3#define M 4Void main()int I,j,aNM,(*p)4;for(i=0;iN;i+) for(j=0;jM;j+) scanf(“%d”,*(p+i)+j);for(i=0;iN;i+) for(j=0;jM;j+) printff(“%d”,*(*(p+i)+j);5.6 字符串与指针字符串的表示形式字符串的表示形式 例例 定义一个字符数组,对它初始化,定义一个字符数组,对它初始化, 然后输出然后输出该字符串该字符串 #includ
24、e void main()char string !; printf(,); (1) 用字符数组存放一个字符串,然后输出该字符串。用字符数组存放一个字符串,然后输出该字符串。(2) 用字符指针指向一个字符串用字符指针指向一个字符串 可以不定义字符数组,而定义一个字符指针。用字符指针指向字符串中的字符。例:定义字符指针#include void main()char*string !;printf(,);例例: : 将字符串复制为字符串将字符串复制为字符串 对字符串中字符的存取,可以用下标方法,也可以对字符串中字符的存取,可以用下标方法,也可以用指针方法用指针方法 #include void (
25、)char am a boy,20; int ; for(;*()!;) *()*(); *(); printf(string a is :,); printf( :); for(;!;) printf(,); printf(); 也可以设指针变量,用它的值的改变来指向字符串也可以设指针变量,用它的值的改变来指向字符串中的不同的字符。中的不同的字符。 例例: 用指针变量来处理字符串复制问题。用指针变量来处理字符串复制问题。#include void main() char =I am a boy. ,20,*p1,*p2; int ; ; for(;*!;p1,p2) *;*;printf(s
26、tring is:,); printf( :);for(;!;) printf(,); printf();1、字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,决不是将字符串放到字符指针变量中。2、赋值方式。对字符数组只能对各个元素赋值,不 能用以下办法对字符数组赋值。 char str; str !; 而对字符指针变量,可以采用下面方法赋值: char*; !; 但注意赋给的不是字符,而是字符串第一个元素 的地址。(4) 如果定义了一个字符数组,在编译时为它分配内存单元,它有确定的地址。而定义一个字符指针变量时,给指针变量分配内存单元,在其中可以放一个字符变量的地
27、址也就是说,该指针变量可以指向一个字符型数据,但如果未对它赋予一个地址值,则它并未具体指向一个确定的字符数据。 如: char str; scanf(,str););是可以的。而常有人用下面的方法,目的是想输入一个字符串,虽然一般也能运行,但这种方法是危险的 : char*; scanf(,);,);5.6 字符串与指针字符串与指针例5。11 从键盘输入两个字符串,将第2个字符串的内容合并到第1个字符串的后面。While(*p1) *p1=*p2; P1+; p2+5.6 字符串与指针字符串与指针例例5。12 从键盘输入一个字符串,删除其中与字符变量从键盘输入一个字符串,删除其中与字符变量C中
28、中相同的字符。相同的字符。5 . 7二级指针与指针数组二级指针与指针数组指针变量:存储目标变量的地址。Int x=3,*p=&x; /p 存放的是变量x的地问题:能否定义一个指针变量,存储另一个指针变量的地址? 如一指针变量如一指针变量指向指向的对象是另一个指针,即存放的是的对象是另一个指针,即存放的是另另一指针一指针的地址;的地址;称其为称其为指向指针的指针指向指针的指针或指针型或指针型指针指针。int x=10,*q,*p;q=&x; p=&q;指针指针p地址地址&q地址地址&x 10 指针指针q变量变量x5 . 7二级指针与指针数组二级指针与指针数
29、组5 . 7。1二级指针的定义二级指针的定义二级指针(指向指针的指针)的定义: 类型标识符类型标识符 *指针变量名指针变量名 的前面有两个*号。*运算符的结合性是从右到左,因此*相当于*(*),显然*是指针变量的定义形式。如果没有最前面的*,那就是定义了一个指向字符数据的指针变量。现在它前面又有一个*号,表示指针变量是指向一个字符指针变量的。*就是所指向的另一个指针变量。5 . 7二级指针与指针数组二级指针与指针数组5 . 7。1二级指针的初始化与引用二级指针的初始化与引用定义定义初始化初始化引用引用5 . 7。1二级指针的初始化与引用二级指针的初始化与引用例:二级指针访问一维数组和二维数组。
30、5 . 7。1二级指针的初始化与引用二级指针的初始化与引用例:二级指针访问一维数组和二维数组。5.5.指针数组和指向指针的指针指针数组和指向指针的指针一个数组,若其元素均为指针类型数据,称为指针指针数组数组,也就是说,指针数组中的每一个元素都相当于一个指针变量。一维指针数组的定义形式为类型名类型名数组名数组长度;数组名数组长度;例如:*;5 . 7。1指针数组指针数组例例515 将若干字符串按字母顺序(由小到大)输出。将若干字符串按字母顺序(由小到大)输出。#include #include void main()void sort(char *name ,int n); void print
31、f(char *name ,int n); char *name =Follow me,BASIC,Great Wall,FORTRAN,Computer design; int ;sort(,); print(,);void sort(char * ,int )char *; int ,; for(; for(; if(strcmp(name,name)0)=; if(!) temp=namei; namei=namek; namek=temp; 例例515 将若干字符串按字母顺序(由小到大)输出。将若干字符串按字母顺序(由小到大)输出。在程序中一但定义了变量或数组,在程序中一但定义了变量或
32、数组,C编译程序就会为编译程序就会为这些变量或数组分配相应的内存空间。即使这些变量或数这些变量或数组分配相应的内存空间。即使这些变量或数组在程序运行期间不再使用,也必须占有这些固定的内存组在程序运行期间不再使用,也必须占有这些固定的内存空间。通常把这种预先确定存储空间,且在程序运行期间空间。通常把这种预先确定存储空间,且在程序运行期间存储空间的大小固定不变的分配方法,称为存储空间的大小固定不变的分配方法,称为静态存储分配静态存储分配。采用该方法,编程者采用该方法,编程者必须预先知道必须预先知道所用变量或数组的所用变量或数组的大小大小,否则数组定义,否则数组定义过大过大(浪费存储空间),或者(浪
33、费存储空间),或者过小数过小数组越界)。组越界)。为解决上述问题,在为解决上述问题,在C语言中可采用语言中可采用动态存储动态存储分配分配技术,即在程序的运行过程中,根据需要技术,即在程序的运行过程中,根据需要临时临时分配存储空分配存储空间,不需要时,随时间,不需要时,随时释放释放这些存储空间。这些存储空间。1、malloc( )函数函数函数原型:函数原型:void *malloc(unsigned size)说明:说明:函数的功能是在内存中分配一个指定长度(以字节为函数的功能是在内存中分配一个指定长度(以字节为单位)的存储空间。单位)的存储空间。 返回值返回值:(1)函数返回指向分配的存储区起始地址的指针。函数返回指向分配的存储区起始地址的指针。 (2)若不能获得所需的内存空间,函数返回若不能获得所需的内存空间,函数返回 null值。值。由于函数返回值为无值型(由于函数返回值为无值
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 【文档】应急管理部18号令《安全生产违法行为行政处罚办法》重点解读
- 2024-2025学年反射疗法师3级经典例题重点附答案详解
- 证据支持下的护理实践
- 紧急项目进度通报回复函7篇范本
- 2024-2025学年公务员(省考)考前冲刺试卷(考点梳理)附答案详解
- 2024-2025学年云南交通职业技术学院电视播音主持期末考试考前冲刺试卷及参考答案详解(达标题)
- 2024-2025学年度执业兽医试题(夺分金卷)附答案详解
- 2024-2025学年度专升本试卷带答案详解(达标题)
- 2024-2025学年度收银审核员模拟试题【有一套】附答案详解
- 2024-2025学年度烟台汽车工程职业学院单招数学题库试题附参考答案详解【巩固】
- 2026年宁夏葡萄酒与防沙治沙职业技术学院自主公开招聘工作人员考试参考试题及答案解析
- 推动职业教育国际化-交流协会的探索与实践
- 2026中央台办所属事业单位招聘10人笔试备考试题及答案解析
- 2025年“安全生产月”《安全知识》培训考试题库及答案
- 2026浙江台州市港航事业发展中心招聘2人考试备考试题及答案解析
- 腹膜透析护理实践指南(2025年版)
- GB/T 1535-2026大豆油
- 2026年临汾职业技术学院单招职业倾向性考试题库含答案详解(完整版)
- 2026校招:远大物产集团试题及答案
- 康复中心考核制度
- 点金手丰年课件在线看
评论
0/150
提交评论