第七章 数组
一维数组
二维数组
字符串输入 30 个数,将它们排序后输出。
数组:相同类型数据的有序集合在内存中连续存放用数组名和下标唯一地确定数组元素每个元素都属于同一类型
s
0 1 2 29
s[0] s[1] s[29]
s0,s1,s2,……s29
一批相同类型的变量使用同一个数组变量名,用下标来相互区分优点:
表述简洁,可读性高便于使用循环结构
s
0 1 2 29
s[0] s[1] s[29]
7.1 一 维 数 组
7.1.1 一维数组的定义和引用
1、定义类型名 数组名 [数组长度 ]
类型名:数组元素的类型数组名:数组变量的名称(数组),标识符数组长度:常量表达式,给定数组的大小
int a[10] ;
定义一个含有 10个整型元素的数组 a
int a[10] ;
定义一个含有 10个整型元素的数组 a
char c[200] ;
定义一个含有 200个字符元素的数组 c
float f[5];
定义一个含有 5个浮点型元素的数组 f
2、数组元素的引用先定义,后使用只能引用单个的数组元素,不能一次引用整个数组数组元素的引用:数组名 [下标 ]
下标:整型表达式取值范围,[0,数组长度 -1]
int a[10] ;
10个元素,a[0],a[1],…… a[9]
下标不要越界,不能使用 a[10]
定义数组,类型名 数组名 [数组长度 ]
引用数组元素:数组名 [下标 ]
数组元素的使用方法与同类型的变量相同
int k,a[10];
k=3;
a[0]=23;
a[k-2]=a[0]+1;
scanf("%d",&a[9]);
区分 定义数组 和引用数组元素定义数组,类型名 数组名 [数组长度 ]
引用数组元素:数组名 [下标 ]
int a[10];
a[0]=a[1]=a[9]=0;
下标不要越界
main( )
{
int a[10];
int i;
for(i = 0; i < 10; i++)
a[ i ] = i;
for(i = 0; i < 10; i++)
printf("%d ",a[i]);
}
输出,0 1 2 3 4 5 6 7 8 9
a[0] a[1] a[9]
a 0 1 2 3 4 5 6 7 8 9
main( )
{ int i;
int a[10];
for(i = 0; i < 10; i++)
scanf(“%d”,&a[i]);
for(i = 0; i < 10; i++)
printf("%d ",a[i]);
printf("\n");
for(i = 9; i >=0; i--)
printf("%d ",a[i]);
}
输入,1 2 3 4 5 6 7 8 9 10
a[0] a[1] a[9]
a 1 2 3 4 5 6 7 8 9 10
输出:
1 2 3 4 5 6 7 8 9 10
10 9 8 7 6 5 4 3 2 1
3、程序举例例 7.1 输入 10个数,求和,
例 7.2 用数组计算 fibonacci数列的前 20个数,
并按每行打印 5个数的格式输出。 1,1,2,3,
5,……
例 7.3 输入 5个整数,将它们存入数组 a中,
再输入 1个数 x,然后在数组中查找 x,如果找到,输出相应的下标,否则,输出,Not
Found”。
程序举例例 7.4_1 输入 10个数,求最小值,
例 7.4_2 输入 n(n<10),再 输入 n个数,求最小值。
例 7.4_3 输入 n(n<10),再 输入 n个数,输出最小值和它所对应的下标 。
例 7.4_4 输入 n(n<10),再 输入 n个数,将最小值与第一个数交换,输出交换后的 n个数。
例 7.5 输入 n(n<10),再 输入 n个数,用选择法将它们从小到大排序后输出。
例 7.1求和输入 10个数,求和,
main( )
{ int i,a[10];
long sum;
for(i = 0; i < 10; i++)
scanf(“%d”,&a[i]);
sum = 0;
for(i = 0; i < 10; i++)
sum = sum+a[i];
printf("%ld\n ",sum);
}
# include,stdio.h”
void main( )
{ int a[10],i;
long sum=0;
for(i = 0; i < 10; i++){
scanf(“%d”,&a[i]);
sum = sum+a[i];
}
printf("%ld\n ",sum);
}
用数组计算 fibonacci数列的前 20个数,并按每行打印 5个数的格式输出。
1,1,2,3,5,8,13,……
分析:
用数组计算并存放 fibonacci数列的前 20个数
f[0]=f[1]=1
f[n]=f[n-1]+f[n-2] 2≤n≤19
例 7.2 计算 fibonacci数列
main( )
{ int i,fib[20];
fib[0]=fib[1]=1;
for(i=2; i<20; i++)
fib[i]=fib[i-1]+fib[i-2];
for(i=0; i<20; i++){
printf(“%6d",fib[i]);
if((i+1)%5==0) printf(“\n");
}
}
输入 5个整数,将它们存入数组 a中,再输入 1个数 x,然后在数组中查找 x,如果找到,输出相应的下标,否则,输出,Not
Found”。
例 7.3查找输入,2 9 8 9 6
9
输出,1
void main( )
{ int i,x,a[5];
for(i=0; i<5; i++)
scanf(“%d”,&a[i]);
scanf(“%d”,&x);
for(i=0; i<5; i++)
if(a[i]==x){
printf("%d\n",i);
break;
}
if(i>=5) printf(“Not Found\n”);
}
1
3
void main( )
{ int i,x,a[5];
for(i=0; i<5; i++)
scanf(“%d”,&a[i]);
scanf(“%d”,&x);
for(i=0; i<5; i++)
if(a[i]==x)
printf("%d\n",i);
}
输入,2 9 8 9 6
9
输出:
输入,2 9 8 9 6
9
输出,3
void main( )
{ int i,x,sub,a[5];
for(i=0; i<5; i++)
scanf(“%d”,&a[i]);
scanf(“%d”,&x);
for(i=0; i<5; i++)
if(a[i]==x) sub=i;
printf("%d\n",sub);
}
输入 10个数,求最小值,
main( )
{ int i,min,a[10];
for(i = 0; i < 10; i++)
scanf(“%d”,&a[i]);
min = a[0];
for(i = 1; i < 10; i++)
if ( a[i]< min) min = a[i];
printf("%d\n ",min);
}
例 7.4_ 1 求最小值输入 n(n<10),再 输入 n个数,求最小值。
main( )
{ int i,min,n,a[10];
scanf(“%d”,&n);
for(i = 0; i < n; i++)
scanf(“%d”,&a[i]);
min = a[0];
for(i = 1; i < n; i++)
if ( a[i]< min) min = a[i];
printf("%d\n ",min);
}
例 7.4_2 求最小值 (n个数 )
输入 n(n<10),再 输入 n个数,输出最小值和它所对应的下标 。
用 index记录最小值对应的下标
a[index]就是最小值例 7.4_3 求最小值 (下标 )
输出最小值和它所对应的下标
N-S流程图输入数组 a
index=0
for i=1 to n-1
a[i] < a[index]
index=i
输出最小值 a[index]和下标 index
Y N
main( )
{ int i,min,n,a[10];
scanf(“%d”,&n);
for(i = 0; i < n; i++)
scanf(“%d”,&a[i]);
index=0;
for(i = 1; i < n; i++)
if (a[i]<a[index]) index=i;
printf("%d %d\n ",a[index],index);
}
输入 n(n<10),再 输入 n个数,将最小值与第一个数交换,输出交换后的 n个数。
用 index记录最小值对应的下标
a[index]就是最小值最小值与第一个数交换
a[index] <==> a[0]
例 7.4_4 最小值交换例 7.5 选择法排序
3 5 2 8 1
输入 n(n<10),再 输入 n个数,用选择法将它们从小到大排序后输出。
n=5
(1) 1 5 2 8 3
(2) 2 5 8 3
(3) 3 8 5
(4) 5 8
3 5 2 8 1 (n=5)
5个数 (a[0]~a[4])中找最小数,与 a[0]交换
(1) 1 5 2 8 3 a[4] <==> a[0]
4个数 (a[1]~a[4])中找最小数,与 a[1]交换
(2) 1 2 5 8 3 a[2] <==> a[1]
3个数 (a[2]~a[4])中找最小数,与 a[2]交换
(3) 1 2 3 8 5 a[4] <==> a[2]
2个数 (a[3]~a[4])中找最小数,与 a[3]交换
(4) 1 2 3 5 8 a[4] <==> a[3]
(1) n个数 (a[0]~a[n-1])中找最小数,与 a[0]交换
(2) n-1个数 (a[1]~a[n-1])中找最小数,与 a[1]交换
……
(n-1) 2个数 (a[n-2]~a[n-1])中找最小数,与 a[n-2]交换
(1) 5个数 (a[0]~a[4])中找最小数,与 a[0]交换
(2) 4个数 (a[1]~a[4])中找最小数,与 a[1]交换
(3) 3个数 (a[2]~a[4])中找最小数,与 a[2]交换
(4) 2个数 (a[3]~a[4])中找最小数,与 a[3]交换
n个数 (a[0]~a[n-1])中找最小数,与 a[0]交换
N-S流程图输入数组 a
index=0
for i=1 to n-1
a[i] < a[index]
index=i
a[index]<==>a[0]
Y N
N-S流程图 (选择排序 )
输入数组 a
index=k
for i = k+1 to n-1
a[i] < a[index]
index=i
a[index]<==>a[k]
Y N
for k=0 to n-2
输出数组 a
void main()
{ int i,index,k,n,temp,a[10];
scanf(“%d”,&n);
for(i=0; i<n; i++) scanf(“%d”,&a[i]);
for(k=0; k<n-1; k++){
index=k;
for(i=k+1; i<n; i++)
if(a[i]< a[index]) index=i;
temp=a[index]; a[index]=a[k]; a[k]=temp;
}
for(i=0; i<n; i++) printf(“%d,,a[i]);
}
7.1.2 一维数组的初始化定义数组时,对数组元素赋初值类型名 数组名 [数组长度 ]= {初值表 };
1,对全部元素赋初值
int a[10]={0,1,2,3,4,5,6,7,8,9};
a[0]=0,a[1]=1,...… a[9]=9
静态数组、全局数组、自动型数组初始化
static int b[5]={1,2,3,4,5};
静态存储的数组如果没有初始化,自动给所有元素赋 0
static int b[5]
2,部分元素初始化
static int b[5]={1,2,3};
b[0]=1,b[1]=2,b[2]=3,b[3]=0,b[4]=0
auto int fib[20]={0,1};
如果对全部元素都赋初值,可以省略数组长度
int a[ ]={0,1,2,3,4,5,6,7,8,9};
建议不要省略数组长度
7.2 二维数组多维数组的空间想象二维数组,一个表格或一个平面矩阵一维数组,一列长表或一个向量多维数组,多维空间的一个数据列阵三维数组,三维空间的一个方阵
7.2.1 二维数组的定义和引用
1、定义类型名 数组名 [行长度 ][列长度 ]
int a[3][2];
定义 1个二维数组 a,3行 2列,6个元素
int b[5][10];
5 行 10 列,50 个元素
2、数组元素的引用先定义,后使用定义:类型名 数组名 [行长度 ][列长度 ]
数组元素的引用:
数组名 [行下标 ] [列下标 ]
行下标的取值范围是 [0,行长度 -1]
列下标的取值范围是 [0,列长度 -1]
下标不要越界
int a[3][2];
3 行 2 列,6 个元素表示 1个 3行 2列的矩阵
a[0][0] a[0][1]
a[1][0] a[1][1]
a[2][0] a[2][1]
二维数组的元素在内存中按行 /列方式存放
a[0][0]
a[0][1]
a[1][0]
a[1][1]
a[2][0]
a[2][1]
遍历二维数组行下标和列下标分别做为循环变量,通过二重循环,遍历二维数组通常将行下标做为外循环的循环变量
a[0][0] a[0][1]
a[1][0] a[1][1]
a[2][0] a[2][1]
for(i = 0; i < 3; i++)
for(j=0; j<2; j++)
a[i][j] = i+j;
i=0 j=0
i=0 j=1
i=1 j=0
i=1 j=1
i=2 j=0
i=2 j=1
0 1
1 2
2 3
输入二维数组
int a[3][2];
for(i = 0; i < 3; i++)
for(j=0; j<2; j++)
scanf(“%d”,&a[i][j] );
输入,1 2 3 4 5 6
a[0][0] a[0][1]
a[1][0] a[1][1]
a[2][0] a[2][1]
1 2
3 4
5 6
按矩阵的形式输出二维数组
int a[3][2];
for(i = 0; i < 3; i++){
for(j=0; j<2; j++)
printf(“%d”,&a[i][j] );
printf(“\n”);
}
a[0][0] a[0][1]
a[1][0] a[1][1]
a[2][0] a[2][1]
3、程序举例例 7.6 定义 1个 3*2的二维数组 a,数组元素的值由下式给出,按矩阵的形式输出 a。
a[i][j]=i+j( 0≤i≤2,0≤j≤1)
例 7.7 找出矩阵中绝对值最小的元素,以及它的行下标和列下标 。
例 7.8 方阵转置 ( 行列互换 )
定义 1个 3*2的二维数组 a,数组元素的值由下式给出,按矩阵的形式输出 a。
a[i][j]=i+j( 0≤i≤2,0≤j≤1)
例 7.6
#include <stdio.h>
void main( )
{ int i,j;
int a[3][2];
for(i=0; i<3; i++)
for(j=0; j<2; j++)
a[i][j]=i+j;
for(i=0; i<3; i++){
for(j=0; j<2; j++)
printf("%4d",a[i][j]);
printf("\n");
}
}
找出矩阵中绝对值最小的元素,以及它的行下标和列下标。
求绝对值函数 abs( ) 或 fabs( )
头文件 math.h
row记录绝对值最小的元素的行下标
col记录 列下标
a[row][col]就是绝对值最小的元素例 7.7
#include <stdio.h>
#include <math.h>
void main( )
{ int i,j;
int a[3][2];
for(i = 0; i < 3; i++)
for(j=0; j<2; j++)
scanf(“%d”,&a[i][j] );
row=col=0;
for(i=0; i<3; i++)
for(j=0; j<2; j++)
if(abs(a[i][j])<abs(a[row][col])){
row=i;
col=j;
}
printf(“a[%d][%d]=%d\n",row,col,a[row][col]);
}
输入,3 2 10 -9 6 -1 3 2
10 -9
6 -1
int a[N][N]; N是正整数数组元素 a[i][j],i和 j的取值范围 [0,N-1]
用二维数组 a表示 N*N方阵时,对应关系,
a[0][0] a[0][1] a[0][2] 主对角线
a[1][0] a[1][1] a[1][2] 上三角
a[2][0] a[2][1] a[2][2] 下三角方阵
i==j
i<=j
i>=j
输入一个正整数 n (1<n≤6),根据下式生成 1
个 n*n的方阵,然后将该方阵转置(行列互换)后输出。
a[i][j]=i*n+j+1( 0≤i≤n-1,0≤j≤n-1)
int a[6][6]
例 7.8
分析
1 2 3
4 5 6
7 8 9
1 4 7
2 5 8
3 6 9
a[0][1] a[1][0]
a[0][2] a[2][0]
a[1][2] a[2][1]
a[i][j] a[j][i]
#include <stdio.h>
void main( )
{ int i,j,n,t;
int a[6][6];
scanf(“%d”,&n);
for(i=0; i<n; i++)
for(j=0; j<n; j++)
a[i][j]=i*n+j+1;
输入 3
1 2 3
4 5 6
7 8 9
for(i=0; i<n; i++)
for(j=0; j<n; j++){
t=a[i][j];
a[i][j]=a[j][i];
a[j][i]=t;
}
for(i=0; i<n; i++){
for(j=0; j<n; j++)
printf("%4d",a[i][j]);
printf("\n");
}
}
for(i=0; i<n; i++)
for(j=0; j < n; j++){
t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}
i=0:
1 4 7
2 5 6
3 8 9
i=1:
1 2 7
4 5 8
3 6 9
i=2:
1 2 3
4 5 6
7 8 9
1 2 3
4 5 6
7 8 9
for(i=0; i<n; i++)
for(j=0; j < n; j++)
if(i <= j ){
t = a[i][j];
a[i][j] = a[j][i];
a[j][i] = t;
}
1 2 3
4 5 6
7 8 9
主对角线,i == j
上三角,i <= j
下三角,i > =j
i=0:
1 4 7
2 5 6
3 8 9
i=1:
1 4 7
2 5 8
3 6 9
for(i=0; i<n; i++)
for(j=0; j < n;j++)
if(i <= j ){
t=a[i][j];
a[i][j]=a[j][i];
a[j][i]=t;
}
1 2 3
4 5 6
7 8 9
主对角线,i == j
上三角,i <= j
下三角,i > =j
for( j = i; j < n; j++)
7.2.2 二维数组的初始化
1、分行赋初值
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
static int b[4][3] = {{1,2,3},{},{4,5}};
数组 a
1 2 3
4 5 6
7 8 9
数组 b
1 2 3
0 0 0
4 5 0
0 0 0
2、顺序赋初值
int a[3][3] = {1,2,3,4,5,6,7,8,9};
static int b[4][3] = {1,2,3,0,0,0,4,5};
省略行长度对全部元素都赋了初值,
int a[ ][3]={1,2,3,4,5,6,7,8,9};
或分行赋初值时,在初值表中列出了全部行
static int b[ ][3]={{1,2,3},{},{4,5},{}}
建议不要省略数组 a
1 2 3
4 5 6
7 8 9
数组 b
1 2 3
0 0 0
4 5 0
0 0 0
7.3 字符串字符串的存储和运算用一维字符数组实现
7.3.1 一维字符数组定义、引用、初始化
char str[80] ;
定义一个含有 80个字符型元素的数组 str
char t[5]={'H','a','p','p','y'};
初始化数组 t
t[0] t[1] t[4]
t H a p p y
7.3.1 一维字符数组
char t[5]={'H','a','p','p','y'};
static char s[6]={'H','a','p','p','y'};
s[0] s[1] s[5]
s H a p p y \0
t[0] t[1] t[4]
t H a p p y
static char s[6]={'H','a','p','p','y',0};
0代表字符 '\0',也就是 ASCII码为 0的字符
static char s[6]={'H','a','p','p','y',?\0?};
一维字符数组
char t[5]={'H','a','p','p','y'};
for(i=0; i<5; i++)
putchar(s[i]) ;
t[0] t[1] t[4]
t H a p p y
7.3.2 字符串字符串常量用一对双引号括起来的字符序列一个字符串结束符 '\0'
"Happy"
6个字符 'H' 'a? 'p? 'p? 'y' '\0'
有效字符字符串结束符字符串的有效长度:有效字符的个数字符串字符串:一个特殊的一维字符数组
把字符串放入一维字符数组(存储)
对字符串的操作 ===> 对字符数组的操作存储
static char s[6]={'H','a','p','p','y','\0'};
字符数组初始化,用字符串常量
static char s[6]={"Happy"};
static char s[6]= "Happy";
字符串
static char s[6]= "Happy";
数组长度 >= 字符串的有效长度 +1
char t[5]
"Happy" 不能存入 t
s[0] s[1] s[5]
s H a p p y \0
字符串
auto char s[80]= "Happy";
s[0] s[1] s[5]
s H a p p y \0
字符串遇 '\0'结束第一个 '\0'前面的所有字符和 '\0'一起构成了字符串 "Happy”
'\0'之后的其他数组元素与该字符串无关计算字符串的有效长度,并输出该字符串字符串的有效长度,有效字符的个数数组中第一个 '\0'前面的字符个数例 7.10 字符串的有效长度
s[0] s[1] s[5]
s H a p p y \0
void main( )
{ int i=0,len;
char s[80]="Happy";
for(i=0; s[i]!='\0'; i++);
len=i;
printf("len = %d\n",len);
for(i=0; s[i]!='\0'; i++)
putchar(s[i]);
}
s[0] s[1] s[5]
s H a p p y \0
输出
len=5
Happy
输出字符串
for(i=0; s[i]!='\0'; i++)
putchar(s[i]);
for(i=0; i<80; i++)
putchar(s[i]);
for(i=0; i<len; i++)
putchar(s[i]);
s[0] s[1] s[5]
s H a p p y \0
字符串
把字符串放入一维字符数组(存储)
对字符串的操作 ===> 对字符数组的操作存储字符数组初始化,用字符串常量
static char s[6]=,Hello";
赋值
s[0]='a'; s[1]='\0';
等价
static char s[6]= "a";
字符串区分,a” 和 ‘ a?
“a” 2个字符‘ a?和 '\0'
a? 1个字符常量输入字符串
把字符串放入一维字符数组(存储)
对字符串的操作 ===> 对字符数组的操作存储
–字符数组初始化,static char s[6]=,Happy";
–赋值,s[0]='a'; s[1]='\0';
–输入
‘ \0?代表空操作,无法输入输入时,设定一个输入结束符将输入结束符转换为字符串结束符 '\0'
输入一个以问号结束的字符串 (少于 80个字符 ),
统计其中数字字符的个数。
分析:
数组长度取上限 80
以 '?'做为输入结束符例 7.11 统计
void main( )
{int count=0,i=0 ;
char s[80];
while((s[i]=getchar( ))!='?')
i++;
s[i]='\0';
for(i=0; s[i]!='\0'; i++)
if(s[i]<='9'&&s[i]>='0')
count++;
printf("count = %d\n",count);
}
输出
count=3
输入
It's 512?
0 1 2 3 4 5 6 7 8
s I t? s 5 1 2 \0
输入一个以回车结束的字符串(少于 10个字符),
它由数字字符组成,将该字符串转换成整数后输出。
,123” ==>123
分析:
数组长度取上限 10
以‘ \n'做为输入结束符例 7.12 字符串转换成整数
void main( )
{ int i=0; char s[10];
long n=0;
while((s[i]=getchar( ))!='\n')
i++;
s[i]='\0';
for(i=0; s[i]!='\0'; i++)
if(s[i]<='9'&&s[i]>='0')
n = n*10+(s[i]-'0');
else break;
printf("%Ld\n",n);
}
输出
123
输入
123
0 1 2 3
s 1 2 3 \0
for(i=0; s[i]!='\0'; i++)
if(s[i]<='9'&&s[i]>='0')
n = n*10+(s[i]-'0');
else break;
0 1 2 3
s 1 2 3 \0
i s[i] s[i]-?0? n = n*10+(s[i]-'0')
0?1? 1 0*10+1 = 1
1?2? 2 1*10+2 =12
2?3? 3 12*10+3 =123
3?\0?
字符串小结字符串:一个特殊的一维字符数组 ‘ \0?
把字符串放入一维字符数组(存储)
数组长度足够
字符数组初始化,static char s[80]=,Happy";
赋值,s[0]='a'; s[1]='\0';
输入,输入结束符 ==> 字符串结束符 '\0'
i=0;
while((s[i]=getchar( ))!='\n') i++;
s[i]='\0';
s[0] s[1] s[5]
s H a p p y \0
把字符串放入一维字符数组(存储)
对字符串的操作 ===> 对字符数组的操作只针对字符串的有效字符和字符串结束符 '\0'
检测
for(i=0; s[i]!='\0'; i++)
putchar(s[i]);
s[0] s[1] s[5]
s H a p p y \0