C语言全国计算机二级等级考试教程第9章 数组(章节带习题)
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
第9章 数组
9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8
一维数组的定义和一维数组元素的引用 一维数组和指针 函数之间对一维数组和数组元素的引用 一维数组应用举例 二维数组的定义和二维数组元素的引用 二维数组和指针 二维数组名和指针数组作为实参 二维数组程序举例
9.2 一维数组和指针
9.2.2 通过数组的首地址引用数组元素
通过前面的学习我们可以知道: a+0 a[0] *(a+0) a[1] *(a+1) a[2] *(a+2) 从上面可以看出,a+0或&a[0]都是地址值。 那我们如何通过该地址来间接的访问存储单元中的值? 例如: float a[10]={1,2,3,4,5,6,7,8,9,10}; for(k=0;k<10;k++) pintf(“%4d”,*(a+k)); for(k=0;k<10;k++) pintf(“%4d”,a[k]); a+2 &a[0]+2 &a[2] a+1 &a[0]+1 &a[1] &a[0]+0 &a[0] a[0] *&a[0] a[1] *&a[1] a[2] *&a[2]
主函数
请问,此时程序对不对? 比如我们输入: 10<CR> 50<CR> 30<CR> -5<CR>
10 50 30
9.3 函数之间对一维数组和数组元素的引用
9.3.3 数组元素地址作为实参
例9.3 编写函数,对具有10个元素的char类型数组,从下标为4的元素开始,全部 设置星号‘*’,保持前4个元素中的内容不变。 比如10个元素在内存中的示意图为:
这时我们引用该元素的时候,只是引用其中的值, 那我们如何获取该元素的地址呢?
例如:&a[0]、 &a[1] 、 &a[2] 、 &a[3] 、 &a[4]
相等
除此之外,数组中还有一个特殊的地址表示方式: 例如:int a[5]; int *p; p=&a[0];
数组名 a也表示地址 例如:p=a+1; p++; 请问a++是否合法?
A
c[0]
A
c[0]
#include <stdio.h> #define M 10 #define B 4 B C D E F G H I J c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] void setstar(char *,int); /*两个函数说明语句*/ void arrout(char *,int); main() {char c[M]={'A','B','C','D','E','F','G','H','I','J'}; setstar(&c[4],M-B); arrout(c,M); } void setstar(char *a,int n)/*星号处理函数*/ B C D * * * * * * c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] {int i; for(i=0;i<n;i++) *(a+i)='*'; } void arrout(char *a,int n) {int i; for(i=0;i<n;i++) printf("%c",a[i]); ABCD****** printf("\n"); }
9.1 一维数组的定义和一维数组元素的引用
9.1.4 通过赋初值定义数组的大小
例如: a[ ]={0,0,0,0,0,0,0,0};
这时我们可以确定数 组的大小为8
9.1 一维数组的定义和一维数组元素的引用
9.1.5 一维数组的定义和数组元素引用举例
例9.1 编写程序,定义一个含有30个元素的int类型数组。依次给数组元素赋奇 数1、3、5、……,然后按每行10个数顺序输出,最后再按每行10个数逆序输出。 程序分析:
ห้องสมุดไป่ตู้
/*定义a为包含5个整型数据的数组*/ /*定义p为指向整型变量的指针变量*/ /*把数组中第一个元素的地址赋给指针 变量p,即p指向a数组的第一个元素*/
非法,因为a是数组首地址,是地址常量,常量不能进行++和- -运算
9.2 一维数组和指针
9.2.1 一维数组和数组元素的地址
举例说明: float a[10],*p; int k; p=a; for(k=0;k<10;k++) p=a+k; /*指针p从左向右依次指向a数组中的每一个元素*/ 由于scanf函数要求给出输入项的地址值,因此可以通过以下循环从终端读入数据 依次放入a数组中: for(k=0;k<10;k++) scanf(“%d”,a+k);
为所定义的数组元素赋初值: int a[8]={2,4,6,8,10,12,14,16}; 以上语句就相当于: int a[8]; a[0]=2; a[1]=4; a[2]=6; a[3]=8; a[4]=10; a[5]=12; a[6]=14; a[7]=16; 注意 1. 在初始化时,一对花括号中的数值类型必须与所说明的类型一致。 他们之间用逗号隔开。 2. 在初始化时,一对花括号中的数据个数不能多于所定义数组的元素 个数。否则在编译时将给出出错信息。 3. 当所赋初值少于所定义数组的元素个数时,系统将自动给后面的元 素补以初值0。例如:int a[5]={2,4};
9.2 一维数组和指针
9.2.4 用带下标的指针变量引用一维数组元素
若有以下定义和语句: int *p,s[10],i; p=s; 比如i的取值范围:i>=0&&i<10
地址的表示方式有三种: &s[i] s+i 数组元素的表示方式也有三种: s[i] *(s+i)
p+i
*(p+i) p[i]
注意
9.1 一维数组的定义和一维数组元素的引用
9.1.1 一维数组的定义
数组是具有相同类型的变量的集合,这些变量在内存中占有连续的存储单元。 一维数组的定义形式如下:
和变量名的命名规则相同
类型名 数组名[整型常量表达式] 例如:int a[8]; /*定义了一个名为a的一维数组*/ int b[3][5]; /*定义了一个名为b的二维数组*/ ★ ★ ★ ★
#include <stdio.h> #define M 30 main() {int s[M],i,k=1; for(i=0;i<M;i++) {s[i]=k;k+=2;} printf("\nSequence Output:\n"); for(i=0;i<M;i++) {printf("%4d",s[i]); if((i+1)%10==0) printf("\n"); } printf("\nInvert Output:\n"); for(i=M-1;i>=0;i--) {printf("%4d",s[i]); if(i%10==0) printf("\n"); } printf("\n"); }
注意
数组说明符的一对方括号中只能是整型常量或整型常量表达式。
9.1 一维数组的定义和一维数组元素的引用
9.1.2 一维数组元素的引用(使用)
若有以下定义语句: double x[8]; 则我们可以引用(使用)的数组元素可以有:x[0]、 x[1]、 x[2]、 ……、 x[7]。 引用的形式还可以是:int i,j,k; i=1;j=3;k=5; x[i]=7.5;x[j]=7.5;x[i+k]=7.5;
a[0] a[1] a[2] a[3] a[4]
p
p+1 *(p+1)
/*访问下一个元素的地址*/ /*间接访问下一个元素中的值*/
例如:for(p=a,k=0;k<5;k++) printf(“%4d”,*(p+k)); /*逐个输出a数组元素中的值*/ 还可以用这种方式逐个输出: for(p=a,k=0;k<5;k++) {printf(“%4d”,*p);p++;}
9.2 一维数组和指针
9.2.1 一维数组和数组元素的地址
如下定义的是一个包含5个元素的一维数组: int a[5]; 数组a在内存中开辟存储单元的示意图如下:
a[0]
地址(指针)a 永远是指向 这边的。
a[1] a[2] a[3] a[4]
p
p
p
a[0] 、a[1]、 a[2]、 a[3]、 a[4] 实质上就是五个变量名。
9.3 函数之间对一维数组和数组元素的引用
9.3.4 函数的指针形参和函数体中数组的区别
请分析如下程序: #include <stdio.h> #define N 10 int *fun(int a[N],int n) {int b[N]; : : return b; } main() {int w[N];*p; : p=fun(w,N); : }
9.2 一维数组和指针
9.2.3 通过指针引用一维数组元素
若有以下定义语句: float a[5],*p,k; p=a; /*相当于p=&a[0]*/ a[0] /*访问该存储单元中的值*/ &a[0] /*访问该存储单元的地址*/ * &a[0] /*间接访问该存储单元中的值*/ p /*访问第一个元素的地址*/ *p /*间接访问第一个元素中的值*/
定义数组 调用函数arrin 给数组输入数据 调用函数arrout 将数组中的数据 输出 #include <stdio.h> #define M 100 void arrout(int *,int); int arrin(int *); /*函数说明语句*/ main() {int s[M],k; k=arrin(s); /*k通过函数得到输入数据的个数*/ arrout(s,k); } int arrin(int *a) /*a为指针,因为传递过来是地址s*/ {int i=0,x; scanf("%d",&x); while(x>=0) /*为负数时退出循环*/ {*(a+i)=x; /*因为a指向数组s中的元素,所以相当于s[i]=x*/ i++; scanf("%d",&x); } return i; /*返回你输入数据的个数*/ } void arrout(int *a,int n) /*输出该数组中的数据*/ {int i; for(i=0;i<n;i++) printf(((i+1)%5==0)?"%4d\n":"%4d",*(a+i)); printf("\n"); }
s++ p++
s=p p=s
p=&s p=&s[i]
非法 合法
9.3 函数之间对一维数组和数组元素的引用
例9.2 编写程序,通过一个函数给主函数中定义的数组输入若干个大于或等于0 的整数,用负数作为输入结束标志;调用另一个函数输出该数组中的数据。 程序分析: ① 主函数 ② 用户自定义输入函数 ③ 用户自定义输出函数
x[1]=7.5;x[3]=7.5;x[6]=7.5;
说明
1. 一个数组元素实质上就是一个变量,代表内存中的一个存储单元。 2. 在引用数组元素时,数组元素中下标表达式的值必须是整数,下标 表达式值的下限从0开始。
9.1 一维数组的定义和一维数组元素的引用
9.1.3 一维数组的初始化(定义时赋初值)
① ② ③ ④
首先定义数组; 给数组赋值; 顺序输出,每行10个; 逆序输出,每行10个;
Sequence Output: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 Invert Output: 59 57 55 53 51 49 47 45 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1
也叫下标表达式,当只有一 个下标时,为一维数组
方括号中的8规定了a数组含有8个元素(变量),它们是a[0]、 a[1]、…… 、 a[7]。 类型名int规定了a数组中每个元素都是整型,在每个元素中只能存放整型数。 在使用该数组时,它的下标范围是从0~7,即下标的下界为0,上界为7。 定义数组,也就是在内存中开辟了一块连续的空间。如图所示。 ★ 在一个定义数组语句中,可以有多个数组说明 符,它们之间用逗号隔开。如: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] double w[22],v[100],u[5]; ★ 数组说明符和普通变量名可同时出现在一个类型定义语句中,例如: char c1,c2,carr[51]; char c1,c2,carr[10+71];
9.1 9.2 9.3 9.4 9.5 9.6 9.7 9.8
一维数组的定义和一维数组元素的引用 一维数组和指针 函数之间对一维数组和数组元素的引用 一维数组应用举例 二维数组的定义和二维数组元素的引用 二维数组和指针 二维数组名和指针数组作为实参 二维数组程序举例
9.2 一维数组和指针
9.2.2 通过数组的首地址引用数组元素
通过前面的学习我们可以知道: a+0 a[0] *(a+0) a[1] *(a+1) a[2] *(a+2) 从上面可以看出,a+0或&a[0]都是地址值。 那我们如何通过该地址来间接的访问存储单元中的值? 例如: float a[10]={1,2,3,4,5,6,7,8,9,10}; for(k=0;k<10;k++) pintf(“%4d”,*(a+k)); for(k=0;k<10;k++) pintf(“%4d”,a[k]); a+2 &a[0]+2 &a[2] a+1 &a[0]+1 &a[1] &a[0]+0 &a[0] a[0] *&a[0] a[1] *&a[1] a[2] *&a[2]
主函数
请问,此时程序对不对? 比如我们输入: 10<CR> 50<CR> 30<CR> -5<CR>
10 50 30
9.3 函数之间对一维数组和数组元素的引用
9.3.3 数组元素地址作为实参
例9.3 编写函数,对具有10个元素的char类型数组,从下标为4的元素开始,全部 设置星号‘*’,保持前4个元素中的内容不变。 比如10个元素在内存中的示意图为:
这时我们引用该元素的时候,只是引用其中的值, 那我们如何获取该元素的地址呢?
例如:&a[0]、 &a[1] 、 &a[2] 、 &a[3] 、 &a[4]
相等
除此之外,数组中还有一个特殊的地址表示方式: 例如:int a[5]; int *p; p=&a[0];
数组名 a也表示地址 例如:p=a+1; p++; 请问a++是否合法?
A
c[0]
A
c[0]
#include <stdio.h> #define M 10 #define B 4 B C D E F G H I J c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] void setstar(char *,int); /*两个函数说明语句*/ void arrout(char *,int); main() {char c[M]={'A','B','C','D','E','F','G','H','I','J'}; setstar(&c[4],M-B); arrout(c,M); } void setstar(char *a,int n)/*星号处理函数*/ B C D * * * * * * c[1] c[2] c[3] c[4] c[5] c[6] c[7] c[8] c[9] {int i; for(i=0;i<n;i++) *(a+i)='*'; } void arrout(char *a,int n) {int i; for(i=0;i<n;i++) printf("%c",a[i]); ABCD****** printf("\n"); }
9.1 一维数组的定义和一维数组元素的引用
9.1.4 通过赋初值定义数组的大小
例如: a[ ]={0,0,0,0,0,0,0,0};
这时我们可以确定数 组的大小为8
9.1 一维数组的定义和一维数组元素的引用
9.1.5 一维数组的定义和数组元素引用举例
例9.1 编写程序,定义一个含有30个元素的int类型数组。依次给数组元素赋奇 数1、3、5、……,然后按每行10个数顺序输出,最后再按每行10个数逆序输出。 程序分析:
ห้องสมุดไป่ตู้
/*定义a为包含5个整型数据的数组*/ /*定义p为指向整型变量的指针变量*/ /*把数组中第一个元素的地址赋给指针 变量p,即p指向a数组的第一个元素*/
非法,因为a是数组首地址,是地址常量,常量不能进行++和- -运算
9.2 一维数组和指针
9.2.1 一维数组和数组元素的地址
举例说明: float a[10],*p; int k; p=a; for(k=0;k<10;k++) p=a+k; /*指针p从左向右依次指向a数组中的每一个元素*/ 由于scanf函数要求给出输入项的地址值,因此可以通过以下循环从终端读入数据 依次放入a数组中: for(k=0;k<10;k++) scanf(“%d”,a+k);
为所定义的数组元素赋初值: int a[8]={2,4,6,8,10,12,14,16}; 以上语句就相当于: int a[8]; a[0]=2; a[1]=4; a[2]=6; a[3]=8; a[4]=10; a[5]=12; a[6]=14; a[7]=16; 注意 1. 在初始化时,一对花括号中的数值类型必须与所说明的类型一致。 他们之间用逗号隔开。 2. 在初始化时,一对花括号中的数据个数不能多于所定义数组的元素 个数。否则在编译时将给出出错信息。 3. 当所赋初值少于所定义数组的元素个数时,系统将自动给后面的元 素补以初值0。例如:int a[5]={2,4};
9.2 一维数组和指针
9.2.4 用带下标的指针变量引用一维数组元素
若有以下定义和语句: int *p,s[10],i; p=s; 比如i的取值范围:i>=0&&i<10
地址的表示方式有三种: &s[i] s+i 数组元素的表示方式也有三种: s[i] *(s+i)
p+i
*(p+i) p[i]
注意
9.1 一维数组的定义和一维数组元素的引用
9.1.1 一维数组的定义
数组是具有相同类型的变量的集合,这些变量在内存中占有连续的存储单元。 一维数组的定义形式如下:
和变量名的命名规则相同
类型名 数组名[整型常量表达式] 例如:int a[8]; /*定义了一个名为a的一维数组*/ int b[3][5]; /*定义了一个名为b的二维数组*/ ★ ★ ★ ★
#include <stdio.h> #define M 30 main() {int s[M],i,k=1; for(i=0;i<M;i++) {s[i]=k;k+=2;} printf("\nSequence Output:\n"); for(i=0;i<M;i++) {printf("%4d",s[i]); if((i+1)%10==0) printf("\n"); } printf("\nInvert Output:\n"); for(i=M-1;i>=0;i--) {printf("%4d",s[i]); if(i%10==0) printf("\n"); } printf("\n"); }
注意
数组说明符的一对方括号中只能是整型常量或整型常量表达式。
9.1 一维数组的定义和一维数组元素的引用
9.1.2 一维数组元素的引用(使用)
若有以下定义语句: double x[8]; 则我们可以引用(使用)的数组元素可以有:x[0]、 x[1]、 x[2]、 ……、 x[7]。 引用的形式还可以是:int i,j,k; i=1;j=3;k=5; x[i]=7.5;x[j]=7.5;x[i+k]=7.5;
a[0] a[1] a[2] a[3] a[4]
p
p+1 *(p+1)
/*访问下一个元素的地址*/ /*间接访问下一个元素中的值*/
例如:for(p=a,k=0;k<5;k++) printf(“%4d”,*(p+k)); /*逐个输出a数组元素中的值*/ 还可以用这种方式逐个输出: for(p=a,k=0;k<5;k++) {printf(“%4d”,*p);p++;}
9.2 一维数组和指针
9.2.1 一维数组和数组元素的地址
如下定义的是一个包含5个元素的一维数组: int a[5]; 数组a在内存中开辟存储单元的示意图如下:
a[0]
地址(指针)a 永远是指向 这边的。
a[1] a[2] a[3] a[4]
p
p
p
a[0] 、a[1]、 a[2]、 a[3]、 a[4] 实质上就是五个变量名。
9.3 函数之间对一维数组和数组元素的引用
9.3.4 函数的指针形参和函数体中数组的区别
请分析如下程序: #include <stdio.h> #define N 10 int *fun(int a[N],int n) {int b[N]; : : return b; } main() {int w[N];*p; : p=fun(w,N); : }
9.2 一维数组和指针
9.2.3 通过指针引用一维数组元素
若有以下定义语句: float a[5],*p,k; p=a; /*相当于p=&a[0]*/ a[0] /*访问该存储单元中的值*/ &a[0] /*访问该存储单元的地址*/ * &a[0] /*间接访问该存储单元中的值*/ p /*访问第一个元素的地址*/ *p /*间接访问第一个元素中的值*/
定义数组 调用函数arrin 给数组输入数据 调用函数arrout 将数组中的数据 输出 #include <stdio.h> #define M 100 void arrout(int *,int); int arrin(int *); /*函数说明语句*/ main() {int s[M],k; k=arrin(s); /*k通过函数得到输入数据的个数*/ arrout(s,k); } int arrin(int *a) /*a为指针,因为传递过来是地址s*/ {int i=0,x; scanf("%d",&x); while(x>=0) /*为负数时退出循环*/ {*(a+i)=x; /*因为a指向数组s中的元素,所以相当于s[i]=x*/ i++; scanf("%d",&x); } return i; /*返回你输入数据的个数*/ } void arrout(int *a,int n) /*输出该数组中的数据*/ {int i; for(i=0;i<n;i++) printf(((i+1)%5==0)?"%4d\n":"%4d",*(a+i)); printf("\n"); }
s++ p++
s=p p=s
p=&s p=&s[i]
非法 合法
9.3 函数之间对一维数组和数组元素的引用
例9.2 编写程序,通过一个函数给主函数中定义的数组输入若干个大于或等于0 的整数,用负数作为输入结束标志;调用另一个函数输出该数组中的数据。 程序分析: ① 主函数 ② 用户自定义输入函数 ③ 用户自定义输出函数
x[1]=7.5;x[3]=7.5;x[6]=7.5;
说明
1. 一个数组元素实质上就是一个变量,代表内存中的一个存储单元。 2. 在引用数组元素时,数组元素中下标表达式的值必须是整数,下标 表达式值的下限从0开始。
9.1 一维数组的定义和一维数组元素的引用
9.1.3 一维数组的初始化(定义时赋初值)
① ② ③ ④
首先定义数组; 给数组赋值; 顺序输出,每行10个; 逆序输出,每行10个;
Sequence Output: 1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31 33 35 37 39 41 43 45 47 49 51 53 55 57 59 Invert Output: 59 57 55 53 51 49 47 45 43 41 39 37 35 33 31 29 27 25 23 21 19 17 15 13 11 9 7 5 3 1
也叫下标表达式,当只有一 个下标时,为一维数组
方括号中的8规定了a数组含有8个元素(变量),它们是a[0]、 a[1]、…… 、 a[7]。 类型名int规定了a数组中每个元素都是整型,在每个元素中只能存放整型数。 在使用该数组时,它的下标范围是从0~7,即下标的下界为0,上界为7。 定义数组,也就是在内存中开辟了一块连续的空间。如图所示。 ★ 在一个定义数组语句中,可以有多个数组说明 符,它们之间用逗号隔开。如: a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] double w[22],v[100],u[5]; ★ 数组说明符和普通变量名可同时出现在一个类型定义语句中,例如: char c1,c2,carr[51]; char c1,c2,carr[10+71];