C语言(四)——数组
目录
一维数组
二维数组
数组越界
数组作为函数参数
一维数组
数组是一组相同类型元素的集合。
创建数组
type arr[n] = {...}
type是数组的元素类型; arr 是数组名; n 是常量或常量表达式,用来指定数组的大小。
根据数组的索引来获取对应元素,索引从 0 开始。
不写 n 的值,则根据大括号中的元素个数自动分配空间。
在C99标准之前,数组的大小必须是常量或常量表达式。
在C99标准之后,数组的大小可以是变量,为了支持变长数组,变长数组不能初始化。
数组的初始化
数组的初始化是指,在创建数组的同时给数组的内容一些合理的初始值(初始化)。
如 intarr[10] = {1,2,3} // 不完全初始化,剩下的元素默认初始化为0
一维数组的使用
[] , 下标引用操作符。它其实就是数组访问的操作符。
计算数组元素个数
sizeof ( arr ) / sizeof ( arr[0] )
一维数组在内存中的存储
数组在内存中是连续存放的。随着数组下标的增加,地址也按数组元素大小的跨度(step)增加。
二维数组
二维数组创建
type arr[a][b] // 创建一个 a 行 b 列的数组
例:int arr[2][3] = {1,2,3,4,5,6}; // 按元素个数自动分配
例:int arr[2][3] = { {1, 2} , { 3, 4, 5} }; // 自己定义每行的元素
例:int arr[ ][3] = {1,2,3,4,5,6}; // 可以省略行数,但不能省略列数
二维数组的使用
行和列的索引都是从 0 开始的。
可以通过嵌套循环的方式遍历数组。
计算二维数组的元素个数
sizeof (arr) / sizeof (arr[0][0])
二维数组在内存中的存储
同一维数组一样,二维数组在内存中也是连续存放的。二维数组的存放按 行 展开(reshape(1, -1))。随着数组下标的增加,地址也按数组元素大小的跨度(step)增加。
数组越界
数组的下标是有范围限制的。
数组的下标规定是从0开始的,如果数组有n个元素,最后一个元素的下标就是 n-1。
所以数组的下标如果小于0, 或者大于 n-1, 就是数组越界访问了,超出了数组合法空间的访问。
C语言本身是不做数组下标的越界检查,编译器也不一定报错(越界的部分会打印随机值),但是编译器不报错,并不意味着程序就是正确的。
数组作为函数参数
注意:当数组作为参数传递给函数时,不能在函数内部计算数组的大小。
因为传进函数的数组名(arr)是数组首元素地址(&arr[0])
// 数组传参, 形参有两种写法
// 数组的形式,指针的形式
// 形参是数组的形式
void bubble_sort(int arr[], int sz) {
// 趟数
// 传进来的arr是首元素的地址,无法使用sizeof计算数组的长度,应该直接传递一个sz的参数
//int sz = sizeof(arr) / sizeof(arr[0]);
int i = 0;
for (i = 0; i <= sz - 1; i++) {
// 一趟冒泡排序
int j = 0;
// 每增加一趟,每趟冒泡排序的次数就少一次
for (j = 0; j < sz-1-i; j++) {
if (arr[j] > arr[j + 1]) {
// 交换
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
// 冒泡排序,升序
int main() {
int arr[] = {9,8,7,6,5,4,3,2,1,0};
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz); // 数组传参只传数组名
for (int i = 0; i < sz; i++) {
printf("%d ", arr[i]);
}
return 0;
}
数组名确实能表示首元素的地址
但是有两个例外:
1.sizeof(数组名), 这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
int main() {
int arr[] = { 1,2,3,4,5 };
printf("%p\n", arr);
printf("%p\n", arr+1); // 加的是一个元素的长度
printf("----------------------\n");
printf("%p\n", &arr[0]);
printf("%p\n", &arr[0]+1); // 加的是一个元素的长度
printf("----------------------\n");
printf("%p\n", &arr);
printf("%p\n", &arr+1); // 加的是一个数组的长度
return 0;
}
二维数组的数组名(arr)也表示首元素地址, 表示的是 arr[0] 这一行的地址。
int main() {
int arr[3][4];
int sz = sizeof(arr);
printf("%zu\n", sz);
// 打印行数
int sz_row = sizeof(arr) / sizeof(arr[0]);
printf("%zu\n", sz_row);
// 打印列数
int sz_col = sizeof(arr[0]) / sizeof(arr[0][0]);
printf("%zu\n", sz_col);
printf("%p\n", arr);
printf("%p\n", arr+1);
return 0;
}