C语言:(5.初级数组)

📅 2026/7/25 3:18:06 👁️ 阅读次数 📝 编程学习
C语言:(5.初级数组)

一、什么是数组?

  • 数组是一组相同类型元素构成的集合

Type Name[Size];

组成部分含义示例
Type每个元素的类型int, char, double
Name数组的名字arr, brr
Size元素个数10, 20
  • 数组的每一个成员Name[0]Name[Size-1]

计算机中所有序号从0开始!

int arr[5]; printf("%d\n", sizeof(arr)); // 20(5个int × 4字节)

二、数组的分类

分类语法说明内存大小(假设int 4字节)
一维数组int arr[10]10个int40字节
二维数组int arr[3][4]3个int[4]48字节
三维数组int arr[2][3][4]2个int[3][4]96字节
  • 一维数组内存布局(起始地址1000):
成员字节范围地址
arr[0]1-41000-1003
arr[1]5-81004-1007
arr[2]9-121008-1011
arr[3]13-161012-1015
arr[4]17-201016-1019

三、数组的三种初始化

1.初始化一:直接定义并初始化
int arr[5] = {1, 2, 3, 4, 5}; int arr2[] = {1, 2, 3, 4, 5}; // Size可以省略 int arr3[10] = {1, 2, 3}; // 后面7个自动补0 int arr4[10] = {}; // 全部为0

2.初始化二:先定义后赋值

int brr[5]; brr[0] = 1; brr[1] = 2; brr[2] = 3; brr[3] = 4; brr[4] = 5;
// 循环赋值 int crr[5]; for (int i = 0; i < 5; i++) { crr[i] = i + 1; }

注意:这种初始化方式Size不可以省略

3.初始化三:从键盘获取
int drr[5]; printf("请输入5个整数:"); for (int i = 0; i < 5; i++) { scanf("%d", &drr[i]); }

注意:Size也不可以省略!

四、二维数组

  • 二维数组是“由一组相同的数组类型构成的集合”。

内存布局(行优先存储):

arr[0][0] arr[0][1] arr[0][2] arr[0][3] arr[1][0] arr[1][1] ... 1 2 3 4 5 6 ...
  • 二维数组的三种初始化:
// 初始化一 int arr[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }; // 初始化二 int brr[3][4]; int temp = 1; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { brr[i][j] = temp++; } } // 初始化三 int crr[3][4]; for (int i = 0; i < 3; i++) { for (int j = 0; j < 4; j++) { scanf("%d", &crr[i][j]); } }

五、三维数组

  • 三维数组是“由一组相同的二维数组类型构成的集合”。
int arr[2][3][4] = { { // 第一组二维数组 {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12} }, { // 第二组二维数组 {13, 14, 15, 16}, {17, 18, 19, 20}, {21, 22, 23, 24} } };
  • 三维数组遍历:
for (int i = 0; i < 2; i++) { for (int j = 0; j < 3; j++) { for (int k = 0; k < 4; k++) { printf("%d ", arr[i][j][k]); } printf("\n"); } printf("\n"); }

六、数组长度公式

// 一维数组长度 int len1 = sizeof(arr) / sizeof(arr[0]); // 二维数组行数和列数 int rows = sizeof(brr) / sizeof(brr[0]); int cols = sizeof(brr[0]) / sizeof(brr[0][0]); // 三维数组各维度长度 int d1 = sizeof(arr) / sizeof(arr[0]); int d2 = sizeof(arr[0]) / sizeof(arr[0][0]); int d3 = sizeof(arr[0][0]) / sizeof(arr[0][0][0]);

七、数组名(面试必考)

int arr[10] = {0}; printf("%d\n", sizeof(arr)); // 40 - 整个数组的大小 printf("%p\n", &arr); // 整个数组的地址 printf("%p\n", arr); // 首元素的地址 printf("%p\n", arr + 1); // 首元素地址 + 4 printf("%p\n", &arr + 1); // 整个数组地址 + 40
  • 数组名的三种身份:
情况含义类型
sizeof(数组名)整个数组的大小Type [Size]
&数组名整个数组的地址Type(*) [Size]
其他情况首元素的地址Type*
int main() { int arr[10] = {0}; printf("%p %p\n", arr, arr + 1); // 差4字节(int*) printf("%p %p\n", &arr, &arr + 1); // 差40字节(整个数组) printf("%d %d\n", sizeof(arr), sizeof(&arr)); // 40 和 4 return 0; }

八、常用数组操作

1. 求和
int sum = 0; for (int i = 0; i < len; i++) { sum += arr[i]; }
2. 最大值(擂台法)
int max = arr[0]; for (int i = 1; i < len; i++) { if (arr[i] > max) { max = arr[i]; } }
3. 最小值
int min = arr[0]; for (int i = 1; i < len; i++) { if (arr[i] < min) { min = arr[i]; } }
4. 平均值
double avg = (double)sum / len;
5. 冒泡排序
void BubbleSort(int arr[], int len) { for (int i = 0; i < len - 1; i++) { for (int j = 0; j < len - i - 1; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }

九、面试考点与避坑指南

  • 考点1:数组名与指针的区别
int arr[10]; int *p = arr; sizeof(arr); // 40 sizeof(p); // 4(指针大小)
  • 考点2:二维数组的指针类型
int arr[3][4]; // arr的类型是 int(*)[4](指向有4个int的数组的指针) // arr + 1 跳过了 4个int = 16字节
  • 考点3:数组作为函数参数会退化
void func(int arr[10]) { printf("%d\n", sizeof(arr)); // 4!不是40! } // 因为数组参数退化为指针:int arr[] 等价于 int *arr

正确做法:同时传递长度

void func(int arr[], int len) { for (int i = 0; i < len; i++) { printf("%d ", arr[i]); } }
  • 考点4:常见错误
//数组不能整体赋值 int arr1[5] = {1, 2, 3, 4, 5}; int arr2[5]; arr2 = arr1; // 错误! //用循环或memcpy for (int i = 0; i < 5; i++) { arr2[i] = arr1[i]; }

总结

知识点要点
数组初始化三种方式,Size可省略的情况
数组名sizeof和&时是整体,其他情况是首元素地址
二维数组行优先存储,arr[i][j]=*(*(arr+i)+j)
数组传参会退化为指针,需要额外传长度
常见坑数组不能整体赋值,不能返回局部数组