C语言数组是编程中基础且重要的概念,它们是存储同类型元素序列的一种方式。数组名在C语言中具有特殊的含义,它不仅仅是一个指向数组首地址的常量指针,但其行为在不同上下文中有不同的解释。
数组名本质上表示的是一个内存区域的起始地址,这个内存区域连续存放了数组的所有元素。例如,声明一个整型数组`int array[] = {1, 2, 3};`,`array`在这里代表了数组开始的内存位置。`sizeof(array)`返回的是整个数组占用的字节数,对于这个例子来说,是3个整型元素的总大小,即12(假设每个整型占4字节)。然而,当我们使用`array[i]`来访问数组元素时,`array`看起来更像一个指向数组首元素的常量指针,因为`array[0]`等价于`*(array + 0)`,这里的`array`可以被解释为类型为`int *`的指针。
在函数参数传递时,C语言的数组通常按引用传递,而不是值传递。这意味着当数组作为参数传递给函数时,例如`foo(int a[])`,实际上传递的是数组的首地址,而不是整个数组的副本。因此,尽管在函数内部`sizeof(a)`可能会返回4(假设指针大小为4字节),这是因为编译器将函数参数视作指针,而不是数组本身。
字符数组在C语言中扮演着特殊的角色。字符串字面量,如`"abc"`,会被存储在字符常量区,并且自动在末尾添加一个终止符`\0`。当声明`char *str1 = "abc"`时,`str1`是一个指向字符常量区中`"abc\0"`的指针。而`char str2[] = "def"`则会将`"def\0"`复制到栈上的一个字符数组中,`str2`指向这个栈内的数组。`char str[] = {'x', 'y', 'z'}`则直接在栈上创建一个字符数组,不涉及字符常量区。
二维数组是多维数组的一种形式,可以看作是一系列的一维数组。例如,`int array[][3] = { {1, 2, 3}, {4, 5, 6} }`定义了一个2行3列的数组。访问`array[i][j]`时,`array`被视为指向`int[3]`类型的指针,`array[i]`返回的是第i行数组的地址,类型为`int *`,然后通过`*(array[i] + j)`来访问第i行第j个元素。
理解C语言数组的关键在于把握数组名的多重含义以及在不同情况下的行为,包括数组作为函数参数的行为、字符数组与字符串字面量的区别,以及如何访问和操作二维数组。这有助于编写更高效、准确的C语言代码。