C 数组
C - 数组
Section titled “C - 数组”数组(array)是 C 语言中一种基本数据结构(data structure),用于存储固定大小、顺序排列的**相同数据类型(same data type)**元素集合。可以将其视为同一类型的变量组,它们在内存中连续(contiguously)存储(一个接一个),可以通过一个公共名称和索引(index)进行访问。
与其声明诸如 score1, score2, score3, … 的单独变量,不如声明一个名为 scores 的数组变量,并使用索引访问各个元素:scores[0], scores[1], scores[2], …。
关键特性:
- 固定大小(Fixed Size): 标准 C 数组的大小必须在编译时确定,不能在运行时(runtime)改变。(C99 引入了可变长数组(Variable Length Arrays, VLAs),但其使用有局限性和潜在风险)。
- 同质元素(Homogeneous Elements): 数组内的所有元素必须具有相同的数据类型(例如,全部是
int,全部是float,全部是char)。 - 连续内存(Contiguous Memory): 数组元素存储在相邻的内存位置,这使得访问效率很高。
- 基于零的索引(Zero-Based Indexing): 第一个元素使用索引
0访问,第二个使用索引1,大小为N的数组的最后一个元素使用索引N-1访问。
要声明数组,你需要指定元素类型(element type)、数组名(array name)和包含在方括号 [] 中的元素数量(大小,size):
type arrayName[arraySize];arraySize 必须是大于零的整数常量表达式。type 可以是任何有效的 C 数据类型(data type)。
示例:
#define MAX_STUDENTS 50
// Declare an array of 10 integersint counters[10];
// Declare an array of 20 floating-point numbersfloat temperatures[20];
// Declare an array to hold grades for MAX_STUDENTSchar grades[MAX_STUDENTS];数组可以在声明时使用包含在花括号 {} 中的初始化列表(initializer list)进行初始化:
// Initialize an array of 5 doublesdouble balances[5] = { 1000.0, 2.0, 3.4, 7.0, 50.0 };
// Initialize an array of integersint sequence[6] = { 1, 1, 2, 3, 5, 8 };重要的初始化规则:
{}中的初始化器数量不能超过声明的数组大小。- 部分初始化(Partial Initialization): 如果提供的初始化器数量少于数组大小,剩余的元素将自动初始化为零(对于算术类型(arithmetic types))或 NULL(对于指针(pointers))。
- 省略大小(Omitting Size): 如果提供了初始化列表但省略了数组大小,编译器会根据初始化器的数量自动确定大小。
// Partial initialization: first 3 elements initialized, last 7 are zero.int partial[10] = { 5, 10, 15 };
// Omitting size: compiler creates an array of size 4.char vowels[] = { 'a', 'e', 'i', 'o', 'u' }; // Size is 5
// String literal initialization (includes null terminator)char message[] = "Hello"; // Size is 6 ('H','e','l','l','o','\0')// 字符串字面量初始化(包含空终止符)访问数组元素
Section titled “访问数组元素”单个数组元素使用数组名后跟方括号 [] 中的元素索引(index)来访问。
记住:第一个元素的索引是 0,最后一个元素的索引是 arraySize - 1。
示例:
int values[5] = { 10, 20, 30, 40, 50 };
int firstValue = values[0]; // Access first element (value is 10)int thirdValue = values[2]; // Access third element (value is 30)
values[4] = 99; // Modify the last element (index 4)
// Attempting to access values[5] would be an error (out of bounds)重要警告: C 语言不对数组访问执行自动边界检查(bounds checking)。访问超出有效索引范围的元素(例如,array[-1] 或 array[arraySize])会导致未定义行为(undefined behavior)。这可能导致程序崩溃(crashes)、数据损坏(corrupt data)或引发严重的安全漏洞(security vulnerabilities)(缓冲区溢出,buffer overflows)。程序员(programmer)有责任确保所有数组访问都在有效边界内。
示例:声明、初始化和访问
Section titled “示例:声明、初始化和访问”#include <stdio.h>#include <stddef.h> // For size_t
#define ARRAY_SIZE 10
int main(void) { int numbers[ARRAY_SIZE]; // 声明一个包含 10 个整数的数组 size_t i; // 使用 size_t 表示数组索引/大小 - 这是标准做法
// 使用循环初始化元素 printf("Initializing array...\n"); for (i = 0; i < ARRAY_SIZE; ++i) { numbers[i] = (int)(i * i); // 存储平方值:0, 1, 4, 9... }
// 访问并打印每个元素的值 printf("\nArray elements:\n"); for (i = 0; i < ARRAY_SIZE; ++i) { // 防御性检查(可选,但在复杂场景中是良好实践) if (i < ARRAY_SIZE) { printf("Element[%zu] = %d\n", i, numbers[i]); } else { printf("Error: Index %zu out of bounds!\n", i); // 适当处理错误 } }
return 0;}编译并执行后,输出如下:
Initializing array...
Array elements:Element[0] = 0Element[1] = 1Element[2] = 4Element[3] = 9Element[4] = 16Element[5] = 25Element[6] = 36Element[7] = 49Element[8] = 64Element[9] = 81更多数组概念
Section titled “更多数组概念”数组是一个基础主题,还有更高级的方面:
| 概念 | 描述 |
|---|---|
| Multi-dimensional arrays | 数组的数组,用于表示表格或矩阵(例如,int matrix[3][4];)。 |
| Passing arrays to functions | 当数组名传递给函数时,它会“衰退”为指向其第一个元素的指针。除非单独传递,否则大小信息会丢失。 |
| Returning arrays from functions | 函数不能直接返回整个数组。常用技术包括返回指向动态分配数组的指针,返回指向静态数组的指针(谨慎使用),或将数组封装在结构体(struct)中。 |
| Pointers and Arrays | 指针和数组在 C 语言中有很强的关联性。数组名本身在很多上下文中表现得像指向第一个元素的指针(例如,arrayName 等同于 &arrayName[0])。 |
| Variable Length Arrays (VLAs) | C99 引入,允许数组大小在运行时(runtime)确定。声明方式类似 int arr[n];,其中 n 是变量。在 C11/C17/C23 中变为可选特性。如果 n 很大,可能存在栈溢出(stack overflow)风险。谨慎使用;动态分配(malloc)对于运行时大小的数组通常更安全。 |
这些主题通常会在后续章节或教程中更详细地介绍。