数组
之前我们编写过一个程序计算用户输入的数字然后求平均数。
#include <stdio.h>
int main( )
{
int x;
double sum = 0;
int cnt = 0;
scanf( "%d",&x);
while ( x!= -1 ) {
sum +=x;
cnt ++;
scanf("%d",&x);
}
if ( cnt >0 ) {
printf("%f\n", sum/cnt) ;
}
}
在这个程序中不需要记录输入的每一个数,那么我在上面的前提下我们修改一下题目要求。
如何写一个程序计算用户输入的数字的平均数,并输出所有大于平均数的数?
我们要满足这个程序就需要使用C语言中的数组。
#include <stdio.h>
int main( )
{
int x;
double sum = 0;
int cnt = 0;
int number[100];
scanf( "%d",&x);
while ( x!= -1 ) {
number[cnt] = x;
sum +=x;
cnt ++;
scanf("%d",&x);
}
if ( cnt >0 ) {
printf("%f\n", sum/cnt);
int i;
for(i=0;i<cnt;i++){
if(number[i]>sum/cnt){
printf("%d\n",number[i]);
}
}
}
}
定义数组
type arrayName [ arraySize ];
元素数量arraySize必须是一个大于零的整数常量
类型type可以是任意有效的 C 数据类型
C99之前:元素数量必须是编译时刻确定的字面量
数组
我们可以把数组理解为一种容器(放东西的东西),特点是:
- 其中所有的元素具有相同的数据类型;
- 一旦创建,不能改变大小
- 数组中的元素在内存中是连续依次排列的
数组的单元
数组的每个单元就是数组类型的一个变量
使用数组时放在[]中的数字叫做下标或索引,下标从0开始计数:
- grades[0]
- grades[99]
- average[5]
有效的下标范围
编译器和运行环境都不会检查数组下标是否越界,无论是对数组单元做读还是写
一旦程序运行,越界的数组访问可能造成问题,导致程序崩溃
如果你的程序出现segmentation fault
报错,可能就是你的程序因为下标越界导致的
但是也可能运气好,没造成严重的后果
所以这是程序员的责任来保证程序只使用有效的下标值:[0,数组的大小-1]
初始化数组
在 C语言中,可以逐个初始化数组,也可以使用一个初始化语句,如下所示:
double balance[5] = {1000.0, 2.0, 3.4, 7.0, 50.0};
大括号 { } 之间的值的数目不能大于我们在数组声明时在方括号 [ ] 中指定的元素数目。
如果省略掉了数组的大小,数组的大小则为初始化时元素的个数。因此,如果:
double balance[] = {1000.0, 2.0, 3.4, 7.0, 50.0};
集成初始化时的定位
int a[10] = {
[0] = 2,[2] = 3,6 ,
};
- 用[n]在初始化数据中给出定位
- 没有定位的数据接在前面的位置后面
- 其他位置的值补零
- 也可以不给出数组大小,让编译器算
- 特别适合初始数据稀疏的数组
数组的大小
sizeof给出整个数组所占据的内容的大小,单位是字节
sizeof(a)/sizeof(a[0])
sizeof(a[0])给出数组中单个元素的大小,于是相除就得到了数组的单元个数
这样的代码,一旦修改数组中初始的数据,不需要修改遍历的代码
数组的赋值
数组变量本身不能被赋值
要把一个数组的所有元素交给另一个数组,必须采用遍历
for ( i=0; i<length; i++ ) {
b[i] = a[i];
}
遍历数组
通常都是使用for循环,让循环变量i从O到<数组的长度,这样循环体内最大的i正好是数组最大的有效下标
常见错误是︰
- 循环结束条件是<=数组长度,或;
- 离开循环后,继续用i的值来做数组元素的下标!
访问数组元素
数组元素可以通过数组名称加索引进行访问。元素的索引是放在方括号内,跟在数组名称的后边。例如:
double salary = balance[9];
上面的语句将把数组中第 10 个元素的值赋给 salary 变量。
二维数组
int a[3][5];
通常理解为a是一个3行5列的矩阵
二维数组的遍历
for ( i=0; i<3; i++ ) {
for ( j=0; j<5; j++ ) {
a[i][j] = i*j;
}
}
a[i][i]是一个int
表示第i行第j列上的单元
二维数组的遍历
for ( i=0; i<3; i++ ) {
for ( j=0; j<5; j++ ) {
a[i][j] = i*j;
}
}
a[i][i]是一个int
表示第i行第j列上的单元
二维数组的初始化
int a[] [5] = {
{0,1,2,3,4},
{2,3,4,5,6},
};
列数是必须给出的,行数可以由编译器来数
每行一个{},逗号分隔
最后的逗号可以存在,有古老的传统
如果省略,表示补零
也可以用定位(*C99 ONLY)