数组(array)由一系列类型相同的元素构成
数组的声明:包括数组元素的数目和元素的类型,编译器根据这些信息创建合数的数组,数组元素可以具有同普通变量一样的类型:
int main(void)
{
int a[5]; // 包含5个整数的数组
float b[20]; // 包含20个浮点数的数组
char c[3]; // 包含3个字符的数组
...
}
数据的访问:使用下标数字(也称索引)表示数组中的单个元素,索引是从0开始的,例如a[0]表示数组a的第一个元素,a[4]表示数组a的第五个元素
一、数组的初始化
语法:
int main(void)
{
int arr[5] = {1, 2, 3, 4, 5}; // 使用花括号括起来的一系列数值初始化数组
// 数值之间用逗号隔开
// 只有ANSI C支持这种初始化方式
...
}
示例代码:打印每年12个月每个月的天数
#include <stdio.h>
#define MONTHS 12
int main(void)
{
int days1[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int days2[MONTHS] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int year;
int index;
printf("please enter the year(for example 2022): \n");
scanf("%d", &year);
if(year % 4)
{
for(index = 0; index < MONTHS; index++)
{
printf("Month %d has %d days. \n", index + 1, days1[index]);
}
}
else
{
for(index = 0; index < MONTHS; index++)
{
printf("Month %d has %d days. \n", index + 1, days2[index]);
}
}
return 0;
}
运行结果:
对数组使用const:
有时需要使用只读数组,在声明并初始化数组时,建议使用关键字const
const int days1[MONTHS] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
程序会把数组中每个元素当成常量处理
和普通变量一样,需要在声明const数组时对其进行初始化,因为在声明之后就不能再对其赋值
与普通变量一样,初始化之前数组元素的值是不确定的
初始化列表中的元素数目应该和数组大小移植;当数值数目少于数组元素数目时,多余的数组元素被初始化为0
如果不初始化数组,数组元素使不确定的值,如果部分初始化数组,未初始化的元素被设置为0
如果初始化列表中项目的个数大于数组大小,编译器会报错
当使用空的方括号对数组进行初始化时,编译器会根据列表中的数值数目确定数组大小
int days1[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
二、指定初始化项目(C99)
C99增加的新特性:指定初始化项目,即允许选择对某些元素进行初始化
int arr[5] = {0, 0, 1, 0, 0}; // 传统写法
int arr[5] = {[2] = 1}; // 把arr[2]初始化为1,未初始化的元素自动设置为0
1)如果在一个指定初始化项目之后跟有不止一个值,则这些数值将用来对后续的数组元素初始化
2)如果多次对一个元素进行初始化,则最后的一次初始化值有效
三、为数组赋值
数组声明之后,可以使用索引(即下标)对数组成员进行赋值
示例代码:
#include <stdio.h>
int main(void)
{
int arr[10];
int i;
for(i = 0; i < 10; i++)
{
arr[i] = i * i;
printf("arr[%d] is %d \n", i, arr[i]);
}
return 0;
}
运行结果:
四、数组的边界
使用数组时,尤其要注意的是数组的索引(下标)不能超过数组边界,因为编译器无法检查出这种类型的错误,程序的执行结果是不可知的
五、指定数组大小
C99引入变长数组(VLA,variable-length array),C99之前编译器不支持
int a[m]; // C99之前不允许