C程序设计复习 第九章 指针
一.知识点
1.指针的概念 2.指针变量
a[0] a[1] a[2] a[3] a[4] 3.指针与数组
4.指针与字符串
10 20 30 40 50
【要点归纳】
图8.1 1、指针变量 p ↑
在 C 语言中允许用一个变量来存放指针,这种变量称为指针变量。 在 C 语言中,提供了两种指针运算符: z *:取指针目标运算符 z &:取地址运算符
2、指针的说明和初始化
指针说明的一般形式如下: 数据类型 *指针名;
说明:与普通变量不同的是,说明指针时指定的数据类型并不是指针变量本身的数据类型,而是其目标的数据类型。无论目标数据类型如何,所有指针都是具有相同格式的地址量,随着机器硬件不同,地址量的数据长度也不同。
第 33 页 共 43 页
C程序设计复习 指针初始化的一般形式如下: 数据类型 *指针名=初始地址值;
说明:指针初始化的过程是:系统按照给出的数据类型,在一定的存储区域为该指针分配存储空间,同时把初始值置入指针的存储空间内,从而该指针就指向了初始地址值所给定的内存空间。 3、指针运算
⑴指针与整数的加减运算 C 语言的地址计算规定,一个地址量加上或减去一个整数 n,其计算结果仍然是一个地址量,它是以运算量为基点的前方或后方第 n 个数据的地址。 对于目标类型为 type 的指针 p, p+n 表示的实际位置的地址值是: p+n*sizeof(type)。 ⑵指针相减
在 C 语言中,两个地址量相减,并非它们的两个地址值之间直接做减法运算,两个指针相减的结果是整数,表示该两指针所指地址之间的数据个数。 ⑶指针的关系运算
目标类型相同的两个指针之间的关系运算,表示的是它们指向的地址位置之间的关系。 4、指针和一维数组
在C 语言中,指针与数组之间的关系十分密切,它们都可以处理内存中连续存放的一系列数据。数组与指针在访问内存时采用统一的地址计算方法。 C 语言中规定,数组名代表数组的首地址,也就是说,可以将数组名(即在内存中存放该数组的首地址)赋给指针。 注:以下四种关系等价 int a[10], *pa=a;
a[i], *(a+i), pa[i], *(pa+i)。 5、字符指针和字符串 字符指针变量和字符数组的区别如下:
⑴字符数组由若干个元素组成,每个元素中放一个字符,而字符指针变量中存放的是地址,而不是将字符串放在字符指针变量中。
⑵赋值方式,对字符数组,只能对各个元素赋值,但不能直接给字符数组进行整体赋值,而对于字符指针,既可以用字符串常量进行初始化,又可以直接用字符串常进行赋值。 ⑶在定义一个数组时,在编译时即已分配内存单元,有确定的地址,而定义
一个字符指针变量时,是给指针变量分配内存单元,并在其中可以放一个地址值,也就是说,该指针变量可以指向一个字符型数据,但如果末对它赋一个地址值,则它并末具体指向哪个字符数据。 C 语言编译系统提供了动态分配和释放存储单元的函数:
z malloc(size) :在内存的动态存储区中分配一个长度为 size 的连续空间,此函数的返回值是一个指向分配域起始地址的指针。
z calloc(n, size):在内存的动态存储区中分配 n 个长度为 size 的连续空间,此函数的返回值是一个指向分配域起始地址的指针。 z free(ptr):释放由 ptr指向的内存区。 6、指针和二维数组
二维数组应区分开行,列指针的概念:
以下几种关系等价: int a[10][20]; a[3][2] , *(*(a+3)+2) , *(a[3]+2)。 7、指针数组 当一系列有次序的指针变量集合成数组时,就形成了指针数组。指针数组是指针的集合,
第 34 页 共 43 页
C程序设计复习 它的每个元素都是一个指针变量,并且指向相同的数据类型。 指针数组的说明形式如下:
数据类型 *指针数组名[元素个数]; 8、多级指针
指向指针的指针称为多级指针。 其说明形式如下: 数据类型 **指针名;
说明:当一个指针指向普通数据时,这样的指针称为一级指针,指向一级指针的指针称为二级指针。指向二级指针的指针称为三级指针,依此类推。
9、函数的数据传递方式 C 语言的参数传递均为单向的值传递,但值又分为普通数据和地址值两种。
⑴数据复制方式传递数据
其特点是:由于数据在传递方和被传递方占用不同的内存空间,所以接收被
传递数据的变量在被调用函数中无论如何变化,都不会影响调用的函数中相应的实参值。 ⑵地址传递方式传递数据
地址传递方式传递数据时传递的不是数据本身,而是存储该数据的地址。 其特点是:由于数据无论是在调用的函数中还是被调用函数中都使用同一个 存储空间,所以被调用函数对该存储空间的值做出某种变动后,必然会影响到使 用该空间的调用函数中的变量的值。 ⑶return 传递数据 ⑷全局变量传递数据 9、指针型函数
当函数的返回值为某种类型的数据的地址时,称为指针型函数。 其定义和说明的一般格式如下: 数据类型 *函数名(形参说明表) 10、指向函数的指针
在 C 语言中,指针变更除了可以保存数据的存储地址外,还可以用于保存
函数的存储首地址。函数的存储首地址又称为函数的执行入口地址。指针变量保 存函数的入口地址时,它就指向了该函数,所以称这种指针为指向函数的指针, 简称为函数指针。
其说明形式如下:数据类型 ( *函数指针名)();
二.练习
㈠.填空题:
1.若有定义:char ch;
⑴使指针p可以指向变量ch的定义语句是 char *p 。 ⑵使指针p指向变量ch的赋值语句是 p=&ch 。
⑶通过指针p给变量ch读入字符的scanf函数调用语句是 scanf(“%c”,p) 。
第 35 页 共 43 页
C程序设计复习 ⑷通过指针p给变量ch赋字符的语句是 *p=’a’ 。
⑸通过指针p输出ch中字符的语句是 printf(“%c”,p) 。
2.若有如图8.1所示五个连续的int类型的存储单元并赋值,且p和s的基类型皆为int,
p已指向存储单元a[1]。
⑴通过指针p,给s赋值,使其指向最后一个存储单元a[4]的语句是 s=p+3 。 ⑵用以移动指针s,使之指向中间的存储单元a[2]的表达式是 s=s-2 。
⑶已知k=2,指针s已指向中间的存储单元a[2],表达式*(s+k)的值是 5 。 ⑷指针s已指向存储单元a[2],不移动指针s,通过s引用存储单元a[3]的表达式是 *(s+1) 。
⑸指针s指向存储单元a[2],p指向存储单元a[0],表达式s-p的值是 2 。 ⑹若p指向存储单元a[0],则以下语句的输出结果是 1 2 3 4 5 。
for(i=0;i<5;i++) printf(“%d ”,*(p+i));printf(“\\n”);
㈡.选择题:
1.若有定义:int x,*pb;则以下正确的赋值表达式是( A )。 A.pb=&x B.pb=x C.*pb=&x D.*pb=*x 2.以下程序的输出结果是( B )。
A.因变量无定义输出不定值 B.0 C.-1 D.1
#include “stdio.h” main() { printf(“%d\\n”,NULL);}
3.已知指针p的指向如图8.1所示,则表达式*++p的值是( B )。 A.20 B.30 C.21 D.31
4.已知指针p的指向如图8.1所示,则表达式++*p的值是( C)。 A.20 B.30 C.21 D.31 5.以下程序的输出结果是( D )。
A.23 B.24 C.25 D.26 void prtv(int *x) { printf(“%d\\n”,++*x); } main()
{ int a=25;prtv(&a);}
6.指针变量a所指的字符串长度为(D )
A.26 B.27 C.28 D.23 char *a=”\\nMy Name is Zhang Li.\\”\\n”;
7.在C语言中,变量的指针是指该变量的(C )
A.值 B.名 C. 地址 D.一个标志 8.下面程序段的运行结果是(C )
A.cde B.无确定的输出结果
C.字符’c’的ASCII码值 D.存放字符’c’的存储单元的地址
第 36 页 共 43 页