版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第第5 5章章 数组和指针数组和指针 5.1 数数 组组 数组是一种复合数据类型,是相同类型元素数组是一种复合数据类型,是相同类型元素 的有序集合。在内存中,它占据一组连续的内存的有序集合。在内存中,它占据一组连续的内存 位置。数组的每一项称为一个元素,每个元素的位置。数组的每一项称为一个元素,每个元素的 存取是通过数组名加偏移来实现的。存取是通过数组名加偏移来实现的。 例如,程序中用到例如,程序中用到a、b、c、d、e、f等等6个个int 变量,可用变量,可用int a6数组来代替,提高程序的可读数组来代替,提高程序的可读 性。性。 5.1.1 数组定义数组定义 和其他变量一样,在使用数组之
2、前需要对数组进行和其他变量一样,在使用数组之前需要对数组进行 定义。数组分为一维数组、二维数组和三维及以上的定义。数组分为一维数组、二维数组和三维及以上的 数组,我们通常把二维数组称为矩阵,三维及以上的数组,我们通常把二维数组称为矩阵,三维及以上的 数组称为多维数组。一维数组的定义格式如下:数组称为多维数组。一维数组的定义格式如下: 类型类型 数组名数组名 常量表达式常量表达式; 其中,其中,“类型类型”指出数组元素的数据类型,指出数组元素的数据类型,“数组数组 名名”指出数组的名称,指出数组的名称,“常量表达式常量表达式”指出一维数组指出一维数组 中存储的元素个数。中存储的元素个数。 例如,
3、以下语句定义了一个具有例如,以下语句定义了一个具有10个元素的整型个元素的整型 数组数组a: int a10; 对数组中某一个元素是通过数组名加下标访问的,对数组中某一个元素是通过数组名加下标访问的, 也就是说,在数组名称后面的方括号内(也就是说,在数组名称后面的方括号内()加入特)加入特 定元素的位置编号,就可以应用这些元素中任何一个。定元素的位置编号,就可以应用这些元素中任何一个。 如如a0是数组的第一个元素,是数组的第一个元素,a1是数组的第二个元素,是数组的第二个元素, a9是数组的最后一个元素。是数组的最后一个元素。 注意,数组的下标是从注意,数组的下标是从0开始,因而一个具有开始,
4、因而一个具有n个个 元素的数组元素的数组A,其有效元素为,其有效元素为a0至至an1。 5.1.2 数组初始化数组初始化 数组可在定义时初始化,其格式为:数组可在定义时初始化,其格式为: 类型类型 数组名数组名数组范围数组范围=值值1,值值2,,值,值n; 初始化值的个数可以小于或等于数组定义的元素个初始化值的个数可以小于或等于数组定义的元素个 数,但不可以多于元素个数(这将导致语法错误),不数,但不可以多于元素个数(这将导致语法错误),不 足部分的数组元素系统自动以足部分的数组元素系统自动以0值填充。如果在初始化值填充。如果在初始化 数组的语句内忽略了数组大小,则数组元素个数就数组的语句内忽
5、略了数组大小,则数组元素个数就是初是初 始化值的个数。以下初始化形式是合法的:始化值的个数。以下初始化形式是合法的: int a3=1,2,3;/初始化三个数组元素初始化三个数组元素 int a10=4,5; /只初始化前两个元素,其他元素等于只初始化前两个元素,其他元素等于0 int a=1,2,3,4; /数组大小由初始化值个数确定,数组大小由初始化值个数确定, /因而数组大小为因而数组大小为4 字符数组可以用多个字符或一个字符串初始化,字符数组可以用多个字符或一个字符串初始化, 但是需要注意:字符串常量以空字符但是需要注意:字符串常量以空字符null(0)结)结 尾,因而也占据一个数组元
6、素的位置。以下是一些字尾,因而也占据一个数组元素的位置。以下是一些字 符串数组的例子:符串数组的例子: char ca=a,b,c,d; /定义了大定义了大 /小为小为4的字符数组的字符数组 char ca=“abcd”; /定义了大小为定义了大小为5的字符的字符 /数组,注意字符串以数组,注意字符串以 0 结尾结尾 char ca4 =“abcd”; /错误,数组大小错误,数组大小(4)小于小于 /初始化值的个数初始化值的个数(5) 【例】以下能对一维数组【例】以下能对一维数组a所有元素正确初始化的所有元素正确初始化的 语句是语句是 。 A.int a20=1,2,3,4,5;B.int a
7、30=0; C.int a=1;D.a20=(10); 答:选项答:选项A和和B只给部分元素置初值,选项只给部分元素置初值,选项D语法错语法错 误。本题答案为:误。本题答案为:C。 5.1.3 数组赋值数组赋值 C+不支持数组之间的直接赋值,因而只能一不支持数组之间的直接赋值,因而只能一 个一个元素地赋值。如要将一个大小为个一个元素地赋值。如要将一个大小为20的数组的数组A 赋给另一个同样大小的数组赋给另一个同样大小的数组B,可以利用循环进行:,可以利用循环进行: for (i=0;i20;i+) Bi=Ai; 字符串(字符数组)的赋值可以利用预定义的字符串(字符数组)的赋值可以利用预定义的
8、字符串操作函数如字符串操作函数如strcpy()等实现,等实现, 例如:例如: char str10; strcpy(str, china); 5.1.5 二维数组二维数组 二维数组也称为矩阵,需要两个下标才能标识某个二维数组也称为矩阵,需要两个下标才能标识某个 元素的位置,二维数组经常用来表示按行和按列格式存元素的位置,二维数组经常用来表示按行和按列格式存 放信息的数值表。放信息的数值表。 1二维数组定义二维数组定义 二维数组的定义与一维数组的定义相似,只是必须二维数组的定义与一维数组的定义相似,只是必须 指定两个常量表达式。其格式如下:指定两个常量表达式。其格式如下: 类型类型 数组名数组
9、名常量表达式常量表达式1常量表达式常量表达式2; 其中,其中,“常量表达式常量表达式1”指出二维数组的行数,指出二维数组的行数,“常常 量表达式量表达式2”指出二维数组的列数。尽管二维数组的元素指出二维数组的列数。尽管二维数组的元素 逻辑上按行列方式排列,但在内存中仍然是顺序存放的,逻辑上按行列方式排列,但在内存中仍然是顺序存放的, 一般是按先行后列的顺序在内存中线性排列的。一般是按先行后列的顺序在内存中线性排列的。 例如,定义如下数组:例如,定义如下数组: int a23; 该数组有该数组有2行行3列,共列,共6个元素。各元素在内存中个元素。各元素在内存中 的排列顺序如下:的排列顺序如下:
10、a00,a01,a02,a10,a11,a12a00,a01,a02,a10,a11,a12 数组数组a中的每个元素用元素名中的每个元素用元素名aij识别,其中,识别,其中, a是数组名,是数组名,i和和j是惟一标识数组是惟一标识数组a中每个元素的下标。中每个元素的下标。 2二维数组初始化二维数组初始化 和一维数组一样,二维数组也能在定义时被初始化。和一维数组一样,二维数组也能在定义时被初始化。 例如,以下说明几个例如,以下说明几个23的整型数组,并初始化:的整型数组,并初始化: int b23=1,2,3,4,5,6; /1,2,3赋给赋给b数组第数组第1行的各行的各 /元素元素,4,5,6
11、 赋给赋给b数组第数组第2行的各元素行的各元素 int c23=1,2,4,5; /同样同样,1,2赋给赋给c数组第数组第1行行 /的前两列元素的前两列元素(c02=0), 4,5赋给赋给 /c数组第数组第2行的前两列元素行的前两列元素(c12=0) int d23=1,2,3,4,; /按行顺序依次赋给各元素,按行顺序依次赋给各元素,d00=1, / d01=2,d02=2,d10=4 【例】若有说明:【例】若有说明:int a45=0;则下列叙述正确;则下列叙述正确 的是的是 。 A.只有元素只有元素a00可得到初值可得到初值0 B.此说明语句错误此说明语句错误 C.数组数组a中各元素都可
12、得到初值,但其值不确定中各元素都可得到初值,但其值不确定 D.数组数组a中每个元素均可得到初值中每个元素均可得到初值0 答:若定义为答:若定义为 int a45=0,则,则a00元素得到元素得到 初值初值0。本题答案为:。本题答案为:A。 3省略第一维大小省略第一维大小 如果对全部元素都赋初值,则定义数组时对第一维如果对全部元素都赋初值,则定义数组时对第一维 的大小可以忽略,但第二维的大小不能省。例如的大小可以忽略,但第二维的大小不能省。例如 int a3=1,2,3,4,5,6,7,8,9; 与下面的代码是等价的:与下面的代码是等价的: int a33=1,2,3,4,5,6,7,8,9;
13、【例】若有定义:【例】若有定义:int a3=0,0;则下列叙述正;则下列叙述正 确的是确的是 。 A.数组数组a的每个元素都可得到初值的每个元素都可得到初值0 B.二维数组二维数组a第一维的大小为第一维的大小为4 C.数组数组a的行数为的行数为2 D.只有元素只有元素a00和和a01可得到初值可得到初值0,其余元素均得,其余元素均得 不到初值不到初值 答:第答:第1维的长度维的长度= 初始化元素个数初始化元素个数/第第2维的长度维的长度 =1。该数组不是静态数组。本题答案为:。该数组不是静态数组。本题答案为:D。 5.1.7 数组作为函数参数数组作为函数参数 数组也可以作为函数的形参和实参。
14、若数组元素数组也可以作为函数的形参和实参。若数组元素 作为函数的实参,其用法与普通变量相同。当数组作为函数的实参,其用法与普通变量相同。当数组 名作为函数的实参和形参时,传递的是数组的地址。名作为函数的实参和形参时,传递的是数组的地址。 数组作为函数参数需要注意以下几个方面:数组作为函数参数需要注意以下几个方面: (1)实参数组与形参数组类型应一致,如不一致,)实参数组与形参数组类型应一致,如不一致, 结果将出错。结果将出错。 (2)形参一维数组也可以不指定大小,在定义数组)形参一维数组也可以不指定大小,在定义数组 时数组名后跟一个空的方括号,为了在被调用的函数时数组名后跟一个空的方括号,为了
15、在被调用的函数 中处理数组元素,可另设一个参数,传递元素的个数。中处理数组元素,可另设一个参数,传递元素的个数。 对于多维数组作为形参,只有第一维的大小可以省略。对于多维数组作为形参,只有第一维的大小可以省略。 例如,若例如,若a是一个以是一个以int aMN(N、M都是用都是用#define 定义的符号常量)定义的二维定义的符号常量)定义的二维int型数组,调用函数为型数组,调用函数为 fun(a)。对应的。对应的fun()函数首部可写成以下两种形式:函数首部可写成以下两种形式: fun(int aN) fun(int aMN) 【例】若函数的形参为多维数组,则以下说明正确的【例】若函数的形
16、参为多维数组,则以下说明正确的 是是 。 A.调用函数时实参数组的维数必须等于形参数组的维数调用函数时实参数组的维数必须等于形参数组的维数 B.定义形参数组时可以省略每一维的大小定义形参数组时可以省略每一维的大小 C.定义形参数组时只能省略第一维的大小定义形参数组时只能省略第一维的大小 D.定义形参数组时必须指定每一维的大小定义形参数组时必须指定每一维的大小 答:对于多维数组作为形参,只有第一维的大小答:对于多维数组作为形参,只有第一维的大小 可以省略。因为除第一维以外,其余每一维的大小都可以省略。因为除第一维以外,其余每一维的大小都 将与各类指针如何进行移动和偏移有关,故不能省略。将与各类指
17、针如何进行移动和偏移有关,故不能省略。 本题答案为:本题答案为:C。 (3)降维处理。由于二维数组在内存中是线性排)降维处理。由于二维数组在内存中是线性排 列的,传递一维数组和传递二维数组都是传递地址,列的,传递一维数组和传递二维数组都是传递地址, 所以可以在被调用的函数中用单重循环来遍历二维数所以可以在被调用的函数中用单重循环来遍历二维数 组中的所有元素,只要传递数组名和元素总个数即可。组中的所有元素,只要传递数组名和元素总个数即可。 这时被传递的数组地址不要用数组名表示,要用第这时被传递的数组地址不要用数组名表示,要用第 一个元素的地址表示,因为数组名表示的是二维数组一个元素的地址表示,因
18、为数组名表示的是二维数组 的首地址,尽管地址值相同,但操作不同。的首地址,尽管地址值相同,但操作不同。 【例】分析以下程序的执行结果。【例】分析以下程序的执行结果。 #include float avg(int ,int); void main() int score4=92,65,68,78,74,88,77,83,92,60,71,82; cout 平均值平均值: avg( / for (int i=0;in;i+) s=s+ai; return (s/n); 平均值平均值:77.5 5.2 5.2 指指 针针 如果在程序中定义了一个变量,在编译时系统就如果在程序中定义了一个变量,在编译时
19、系统就 会给这个变量分配内存单元,并根据程序中定义的变会给这个变量分配内存单元,并根据程序中定义的变 量类型分配一定长度的内存空间,每个内存单元中存量类型分配一定长度的内存空间,每个内存单元中存 放着变量的值。为了便于内存单元的存取,系统为每放着变量的值。为了便于内存单元的存取,系统为每 个内存单元分配了一个地址。通常在程序定义指向个内存单元分配了一个地址。通常在程序定义指向 “地址地址”的变量,即的变量,即指针变量指针变量,简称为,简称为指针指针。 注意:指针是一类特殊的变量,它保存的不是一注意:指针是一类特殊的变量,它保存的不是一 般的数据值,而是程序中另一个对象(如整型、实型般的数据值,
20、而是程序中另一个对象(如整型、实型 变量)在内存中的地址。变量)在内存中的地址。 5.2.1 指针定义指针定义 以下语句定义了几个指针:以下语句定义了几个指针: unsigned int *ip; char *cp; float *fp; 一个指针所占用的内存空间大小与一个内存地址一个指针所占用的内存空间大小与一个内存地址 所占空间等同,因而,一个浮点型指针和一个字符型所占空间等同,因而,一个浮点型指针和一个字符型 指针所占内存大小相同。指针所占内存大小相同。 指针的类型仅用于告知编译系统如何将指针所指指针的类型仅用于告知编译系统如何将指针所指 的二进制序列翻译成实际的数据。的二进制序列翻译成
21、实际的数据。 5.2.2 指针初始化指针初始化 指针初始化有几种方式。指针初始化有几种方式。 (1)指针对象可以被一个具有相同类型的对象初)指针对象可以被一个具有相同类型的对象初 始化。始化。 例如,初始化一个整型指针:例如,初始化一个整型指针: int i=10; int *ip= 由于由于ip是一个指针,所以不能将变量是一个指针,所以不能将变量i的值直接的值直接 赋给它,而应将变量赋给它,而应将变量i的地址赋给它。符号的地址赋给它。符号“ (3)通过直接分配内存地址得到初值。)通过直接分配内存地址得到初值。 下面的例子分配了一块可以存放整数的内存,并下面的例子分配了一块可以存放整数的内存,
22、并 把该内存地址赋给了指针(运算符把该内存地址赋给了指针(运算符new将在后面详细将在后面详细 介绍):介绍): int *ip=new int; /通过直接分配内存给指针赋值通过直接分配内存给指针赋值 5.2.3 指针运算指针运算 施加于指针对象的运算除了取值(施加于指针对象的运算除了取值(*)外,一般还)外,一般还 有加减运算。对指针的加减运算不同于一般数值的加有加减运算。对指针的加减运算不同于一般数值的加 减运算,它对应于内存地址的偏移量,而且偏移量会减运算,它对应于内存地址的偏移量,而且偏移量会 随指针所指类型的不同而异。随指针所指类型的不同而异。 例如:例如: int a5=1,2,
23、3,4,5,*p=a; printf(“%dn”,*(p+3); 5.2.4 指针和数组的关系指针和数组的关系 在在C+中,数组和指针密切相关,几乎可以互相使中,数组和指针密切相关,几乎可以互相使 用。数组名称可以认为是常量指针,它指向存放数组用。数组名称可以认为是常量指针,它指向存放数组 第一个元素的内存地址。指针可以用于完成任何涉及第一个元素的内存地址。指针可以用于完成任何涉及 数组下标的操作。数组下标的操作。 实际上,数组下标表示法在编译期间将转换为指针实际上,数组下标表示法在编译期间将转换为指针 表示法,所以用指针方式来书写数组下标表达式可以表示法,所以用指针方式来书写数组下标表达式可
24、以 节省编译时间。节省编译时间。 例如,对于下面的数组定义:例如,对于下面的数组定义: char name10=Smith; name等于等于 则:则:namei、*(pname+i)和和*(name+i)具有相同的具有相同的 值,都是数组第值,都是数组第i+1个元素的值。而且个元素的值。而且 short int *pa=a; int i=3; cout ai endl; cout *(pa+i) endl; cout *(a+i) endl; cout cout a+i endl; cout pa+i endl; 4 4 4 0 x0065FDEA 0 x0065FDEA 0 x0065FD
25、EA 其中,输出值其中,输出值 0 x0065FDEA是程序是程序 执行时为执行时为a数组动态数组动态 分配的内存地址,读分配的内存地址,读 者执行该程序时不一者执行该程序时不一 定是这个值。定是这个值。 5.2.5 new与与delete 运算符运算符new返回指定类型的一个指针,如果分配返回指定类型的一个指针,如果分配 失败(如没有足够的内存空间),则返回失败(如没有足够的内存空间),则返回0。例如:。例如: double *p; p=new double; 系统自动根据系统自动根据double类型的空间大小开辟一个内类型的空间大小开辟一个内 存单元,并将地址放在指针存单元,并将地址放在指
26、针p中。运算符中。运算符delete操作操作 是释放是释放new请求到的内存。例如:请求到的内存。例如: delete p; 需要注意的是:需要注意的是: (1)运算符)运算符delete必须用于先前必须用于先前new分配的有效指分配的有效指 针。如果使用了未定义的其他任何类型的指针,就会针。如果使用了未定义的其他任何类型的指针,就会 带来严重问题,如系统崩溃等。带来严重问题,如系统崩溃等。 (2)用)用new也可指定分配的内存大小,例如:也可指定分配的内存大小,例如: int *p; p=new int(60); /为指针为指针p开辟开辟60个字节的内存单元个字节的内存单元 . (3)new
27、可以为数组分配内存,但当释放时,必可以为数组分配内存,但当释放时,必 须告诉须告诉delete数组有多少个元素。例如:数组有多少个元素。例如: int *p; p=new int10; /分配整型数组的内存,数组中有分配整型数组的内存,数组中有10个元素个元素 if (!p) cout 内存分配失败内存分配失败!; exit(1); /中断程序执行中断程序执行 for (int i=0;i10;i+) pi=i; /给数组赋值给数组赋值 . delete 10 p; /告诉告诉delete数组有多少个元素数组有多少个元素 5.2.6 字符指针字符指针 C+中,所有有关字符串的操作都是通过字符指
28、针中,所有有关字符串的操作都是通过字符指针 完成的。如定义一个字符串,并将它初始化为完成的。如定义一个字符串,并将它初始化为good bye: char *str=good bye; 遍历上述字符串可以利用将指针依次增遍历上述字符串可以利用将指针依次增1,直到,直到 遇到字符串结束符遇到字符串结束符0为止。下面的程序段输出字符串为止。下面的程序段输出字符串 中各个字符:中各个字符: char *p=str; while (*p!=0) cout *p; /显示显示p所指字符所指字符 p+; /p指针后移指针后移 5.3 5.3 指针与函数指针与函数 5.3.1 指针作为函数参数指针作为函数参数
29、 函数的参数不仅可以是一般数据类型的变量、数函数的参数不仅可以是一般数据类型的变量、数 组名或函数名,而且可以是指针。和数组名类似,用组名或函数名,而且可以是指针。和数组名类似,用 指针作为函数参数,都是传递地址,在调用时实参将指针作为函数参数,都是传递地址,在调用时实参将 值传递给形参,也就是使实参和形参指针变量指向同值传递给形参,也就是使实参和形参指针变量指向同 一内存地址,子函数运行过程中,对形参指针所指变一内存地址,子函数运行过程中,对形参指针所指变 量值的改变也同样影响着实参指针所指向的变量的值。量值的改变也同样影响着实参指针所指向的变量的值。 C+中扩充了引用类型。同样在第中扩充了
30、引用类型。同样在第4章中已经介绍章中已经介绍 过将引用作为函数参数的方法,通过引用也可以将函过将引用作为函数参数的方法,通过引用也可以将函 数中对形参的修改直接作用于主调函数中的实参,而数中对形参的修改直接作用于主调函数中的实参,而 且使用引用类型不会影响程序的可读性。且使用引用类型不会影响程序的可读性。 5.3.2 指针型函数指针型函数 指针型函数的一般定义格式如下:指针型函数的一般定义格式如下: 类型类型 *函数名函数名(参数表参数表) 其中,其中,“类型类型”指出该函数返回指针的数据类型,指出该函数返回指针的数据类型, “函数名函数名”和和“*”标识了一个指针型的函数,标识了一个指针型的
31、函数,“参数参数 表表”是函数的形参列表。是函数的形参列表。 【例】【例】 以下程序建立一个如下图所示的链表,该以下程序建立一个如下图所示的链表,该 链表首结点的指针为链表首结点的指针为head,并输出该链表各结点的数,并输出该链表各结点的数 据域值。据域值。 head 3 6 2 7 一个链表一个链表 #include typedef struct node /自定义类型自定义类型Node int data; /数据域数据域 struct node *next;/指针域指针域 Node; Node *createlist(int a,int n) /尾插法建立一个链表尾插法建立一个链表 No
32、de *head,*r,*s; / r总是指向最后结点总是指向最后结点 for (int i=0;idata=ai; s-next=NULL; if (i=0) head=s;r=s; /head为首结点指针为首结点指针 else r-next=s;r=s; /链接结点链接结点s return head; void displist(Node *h) /显示链表显示链表h的所有结点的的所有结点的data域域 cout 链表结点值链表结点值:; while (h!=NULL) cout data next; cout next!=NULL) h=h-next; delete p; p=h; de
33、lete p; /释放最后一个结点释放最后一个结点 void main() Node *head; int a=3,6,2,7; head=createlist(a,4); displist(head); freelist(head); 5.3.3 函数指针函数指针 函数指针是指向函数的一种指针。它指向内存中的函数指针是指向函数的一种指针。它指向内存中的 某一地址,该地址正好是函数代码段的起始地址。通某一地址,该地址正好是函数代码段的起始地址。通 过函数指针,可以对函数进行调用。说明一个函数指过函数指针,可以对函数进行调用。说明一个函数指 针的一般格式如下:针的一般格式如下: 类型类型 (*函
34、数指针名函数指针名)(参数表参数表) 其中,其中,“类型类型”指出函数指针所指函数的返回值类指出函数指针所指函数的返回值类 型,第一个圆括号中的内容指明一个函数指针的名称,型,第一个圆括号中的内容指明一个函数指针的名称, “参数表参数表”指出该指针所指函数的形参类型和个数。指出该指针所指函数的形参类型和个数。 函数指针在使用之前也要进行赋值,使指针指向函数指针在使用之前也要进行赋值,使指针指向 一个已经存在的函数代码的起始地址。其一般格式一个已经存在的函数代码的起始地址。其一般格式 如下:如下: 函数指针名函数指针名=函数名函数名; 其中,其中,“函数名函数名”指出的必须是一个已经定义指出的必
35、须是一个已经定义 过的、和函数指针说明具有相同返回类型的函数。过的、和函数指针说明具有相同返回类型的函数。 在赋值之后,就可以通过在赋值之后,就可以通过“函数指针名函数指针名”来间接引来间接引 用这个指针指向的函数。用这个指针指向的函数。 #include int add(int m,int n) /加法函数加法函数 return m+n; int sub(int m,int n) /减法函数减法函数 return m-n; int mul(int m,int n) /乘法函数乘法函数 return m*n; int div(int m,int n) /整除函数整除函数 return m/n;
36、 int (*pfun)(int,int); /函数指针函数指针 void main() int i=8,j=2; pfun=add; /函数指针指向函数指针指向add函数函数 cout i + j = pfun(i,j) endl; pfun=sub; /函数指针指向函数指针指向sub函数函数 cout i - j = pfun(i,j) endl; pfun=mul; /函数指针指向函数指针指向mul函数函数 cout i * j = pfun(i,j) endl; pfun=div; /函数指针指向函数指针指向div函数函数 cout i / j = pfun(i,j) endl; 8+
37、2=10 8-2=6 8*2=16 8/2=4 5.4 5.4 指针与多维数组指针与多维数组 5.4.1 指向数组元素的指针指向数组元素的指针 数组名是数组存储的首地址。可以使用指针来对数组名是数组存储的首地址。可以使用指针来对 数组及其元素进行方便而快速的操作。数组及其元素进行方便而快速的操作。 一维数组的指针表示法一维数组的指针表示法 int a5; /a是一维数组名,它有是一维数组名,它有5个个int型变量型变量 用指针方法表示时,用指针方法表示时,*(a+i)与与ai(其中(其中i=0,1,2,3,4)是)是 相同的。相同的。 二维数组的指针表示法二维数组的指针表示法 int b23;
38、 /b是二维数组名,它有是二维数组名,它有6个个int型变量型变量 注意:用指针方法表示时,注意:用指针方法表示时,*(*(b+i)+j)、*(bi+j)、 (*(b+i)j与与bij(其中(其中i=0,1;j=0,1,2)都是相)都是相 同的。同的。 【例】【例】 分析以下程序的执行结果。分析以下程序的执行结果。 #include void main() int a9=1,2,3,4,5,6,7,8,9,i,*p; for (i=0;i9;i+) cout ai ; cout endl; for (i=0;i9;i+) cout *(a+i) ; cout endl; for (p=a;p(
39、a+9);p+) cout *p ; cout endl; 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 5.4.2 指针数组指针数组 如果一个数组的每个元素都是指针变量,这个数组如果一个数组的每个元素都是指针变量,这个数组 就是指针数组。指针数组的每个元素都指向相同类型就是指针数组。指针数组的每个元素都指向相同类型 的变量或对象,元素的值是所指变量或对象在内存中的变量或对象,元素的值是所指变量或对象在内存中 的地址。一般使用的指针数组都是一维指针数组,所的地址。一般使用的指针数组都是一维指针数组,所 以我们只介绍一维指针数组。以我
40、们只介绍一维指针数组。 说明一维指针数组的语法如下:说明一维指针数组的语法如下: 类型类型 *数组名数组名常量表达式常量表达式; 由于由于“*”的优先级小于的优先级小于“”,“数组名数组名”先与先与“” 结合,表示说明的是一个数组,再与结合,表示说明的是一个数组,再与“*”结合,表示结合,表示 该数组的每个元素是指针类型,即定义的是指针数组。该数组的每个元素是指针类型,即定义的是指针数组。 例如:例如: int *p3; 由于由于“”比比“*”优先级高,因此优先级高,因此p先与先与3结合,结合, 形成形成p3的数组形式,它有的数组形式,它有3个元素。然后再与个元素。然后再与p前前 面的面的“*
41、”结合,表示是指针类型的数组,该数组的结合,表示是指针类型的数组,该数组的 每个元素都是整型数的指针,所以每个元素都具有每个元素都是整型数的指针,所以每个元素都具有 指针的特性。指针的特性。 【例】【例】 分析以下程序的执行结果。分析以下程序的执行结果。 #include void main() int *p2; int a3=4,5,6; p0=new int3; p00=1;p01=2;p02=3; p1=a; for (int i=0;i2;i+) for (int j=0;j3;j+) cout pij ; cout endl; delete 2 *p; /释放分配的空间释放分配的空间
42、 1 2 3 4 5 6 指针数组指针数组 5.4.3 多级指针多级指针 在在C+语言中,除了允许指针指向普通数据之外,语言中,除了允许指针指向普通数据之外, 还允许指针指向另外的指针,这种指向指针的指针称还允许指针指向另外的指针,这种指向指针的指针称 为多级指针。其说明形式如下:为多级指针。其说明形式如下: 数据类型数据类型 *指针名指针名; 当一个指针指向普通数据时,这样的指针称为一级当一个指针指向普通数据时,这样的指针称为一级 指针。指向一级指针的指针称为二级指针。指向二级指针。指向一级指针的指针称为二级指针。指向二级 指针的指针称为三级指针,依次类推。指针的指针称为三级指针,依次类推。
43、 在引入多级指针的概念后,需要注意的是:访问一在引入多级指针的概念后,需要注意的是:访问一 个指针的目标时,只有一级指针的目标才是要处理的个指针的目标时,只有一级指针的目标才是要处理的 数据,而多级指针的目标仍是一个指针。数据,而多级指针的目标仍是一个指针。 例如,有以下说明:例如,有以下说明: int *p,*pp,*ppp; 其中,其中,p为一级指针,为一级指针,pp为二级指针,为二级指针,ppp为三级指为三级指 针。针。 一般地,一般地,p用于指向普通的整数,或整型数组的元素;用于指向普通的整数,或整型数组的元素; 当指向整型数组的元素时,当指向整型数组的元素时,p+表示指向该数组的下表
44、示指向该数组的下 一个元素;一个元素; pp用于指向一个指针,用于指向一个指针,p为整数的指针。大多数情为整数的指针。大多数情 况下,况下,pp作为一个指针数组的指针,这时,作为一个指针数组的指针,这时,pp+表示表示 指向该指针数组的下一个元素;指向该指针数组的下一个元素; ppp用于指向一个二级指针的指针。大多数情况下,用于指向一个二级指针的指针。大多数情况下, ppp作为一个二维数组指针的指针。作为一个二维数组指针的指针。 【例】以下程序的输出结果是【例】以下程序的输出结果是 。 #include fun(char *m) /m为多级指针为多级指针 +m; printf(%sn,*m);
45、 main() char *a=BASIC,FOXPRO,C; fun(a); A.BASICB.ASIC C.FOXPROD.C 指针数组指针数组 答:实参答:实参a是一个指针数组,对应的形参是指是一个指针数组,对应的形参是指 针的指针,如下图所示,执行针的指针,如下图所示,执行+m后,后,m指向指向a1, *m即为即为a1所指的字符串即所指的字符串即FOXPRO。本题答。本题答 案为:案为:C。 BASIC FOXPRO C a0 a1 a2 m 【例】以下程序的输出结果是【例】以下程序的输出结果是 。 #include main() int i; char *p,*a=“dog”,“ca
46、t”,“chook”; /p为多级指针为多级指针 for (p=a,i=0;i3;i+) printf(%s,%cn,*(p+i),*(*(p+i)+i); 答:答:*(p+i)=ai。 for循环循环i=0: *(p+i)=*(p+0)=a0=“dog”, *(*(p+i)+i)= *(*(p+0)+0)=*p=d; for循环循环i=1: *(p+i)=*(p+1)=a1=“cat”, *(*(p+i)+i)=*(*(p+1)+1)=a; for循环循环i=2: *(p+i)=*(p+2)=a2=“chook”, *(*(p+i)+i)= *(*(p+2)+2)=o(“chook”串的第串
47、的第3个字符)。个字符)。 dog,d cat,a chook,o 【例】以下程序的输出结果是【例】以下程序的输出结果是 。 #include main() static int a=2,6,10,14,18; static *ptr= int *p,i; /p为多级指针为多级指针 for (i=0;i5;i+) ai=ai/2+ai; p=ptr; printf(%d ,*(*(p+2); printf(%dn,*(*(+p); 答:答:执行执行static *ptr= 语句后,使语句后,使ptr0指向指向a0,ptr4指向指向a4。执行。执行for循循 环语句和环语句和p=ptr之后,存储结构如下图所示。之后,存储结构如下图所示。 *(*(p+2)=*ptr2=15,*(*(+p)=*ptr1=9。程序输出为:。程序输出为: 15 9。 p ptr0 3 ptr1 9 ptr2 15 ptr3 21 ptr4 27 5.4.4 数组指针数组指针 数组指针是指向多维数组中的分数组的指针变量,数组指针是指向多维数组中的分数组的指针变量, 所指向的应该是降一维的整个分数组。如:指向二所指向的应该是降一维的整个分数组。如:指向二 维数组中分数组的
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 教师就业访谈实录
- 2026雅安职业技术学院附属医院上半年招聘非编制工作人员2人笔试备考题库及答案解析
- 2026广西玉林市公安局玉州分局第一次公开招聘警务辅助人员29人笔试备考试题及答案解析
- 2026年中国法学会所属事业单位招聘工作人员笔试参考题库及答案解析
- 2026年吉林大学第二医院医生招聘(244人)笔试参考题库及答案解析
- 2026广西贵港市荷城初级中学招募高校毕业生就业见习人员11人考试备考题库及答案解析
- 2026浙江宁波东钱湖旅游度假区某国有企业招聘派遣制工作人员6人考试参考题库及答案解析
- 2026湖南长沙浏阳市金刚镇中心学校春季招聘编外合同制教师1人笔试备考题库及答案解析
- 2026广西防城港东兴市教育系统公开招聘第二批次中小学临聘教师16人考试备考试题及答案解析
- 2026贵州贵阳市花溪第五中学春季学期体制外教师招聘公5人告考试备考试题及答案解析
- 安全用电培训内容及要求课件
- 危险品全员安全培训方案课件
- 屋顶彩钢瓦施工流程
- (新教材)2026年人教版一年级下册数学 7.2 复习与关联 数与运算(2) 课件
- 询证函复函协议书
- 2025 九年级数学下册二次函数与一次函数交点问题课件
- 2022青鸟消防JBF5131A 型输入模块使用说明书
- 五个带头方面整改措施
- 2026年江苏海事职业技术学院单招职业倾向性测试必刷测试卷含答案
- 2026年内蒙古机电职业技术学院单招职业技能考试题库及答案解析(夺冠)
- 2025年REACH第35批SVHC高度关注物质清单251项
评论
0/150
提交评论