
在讨论多维数组之前,我们还需要学习很多关于一维数组的知识。首先让我们学习一个概念。
考虑下面这些声明:
| int a; int b[10]; |
我们把a称作标量,因为它是个单一的值,这个变量是的类型是一个整数。我们把b称作数组,因为它是一些值的集合。下标和数名一起使用,用于标识该集合中某个特定的值。例如,b[0]表示数组b的第1个值,b[4]表示第5个值。每个值都是一个特定的标量。
那么问题是b的类型是什么?它所表示的又是什么?一个合乎逻辑的答案是它表示整个数组,但事实并非如此。在C中,在几乎所有数组名的表达式中,数组名的值是一个指针常量,也就是数组第一个元素的地址。它的类型取决于数组元素的类型:如果他们是int类型,那么数组名的类型就是“指向int的常量指针”;如果它们是其他类型,那么数组名的类型也就是“指向其他类型的常量指针”。
| 请问:数组首地址指针和数组名是等价的吗? |
答案是否定的。数组名在表达式中使用的时候,编译器才会产生一个指针常量。那么数组在什么情况下不能作为指针常量呢?在以下两种场景下:除了这俩种,其余都等价
|

| int arr[10]; //arr = NULL; //arr作为指针常量,不可修改 int *p = arr; //此时arr作为指针常量来使用 printf("sizeof(arr):%d\n", sizeof(arr)); //此时sizeof结果为整个数组的长度 printf("&arr type is %s\n", typeid(&arr).name()); //int(*)[10]而不是int* |
| int arr[] = { 1, 2, 3, 4, 5, 6 }; |
*(arr + 3) ,这个表达式是什么意思呢?
首先,我们说数组在表达式中是一个指向整型的指针,所以此表达式表示arr指针向后移动了3个元素的长度。然后通过间接访问操作符从这个新地址开始获取这个位置的值。这个和下标的引用的执行过程完全相同。所以如下表达式是等同的,且下标可以为负数。
| *(arr + 3) arr[3] |
问题1:数组下标可否为负值?
可以的,相当于解引用

问题2:请阅读如下代码,说出结果:
| int arr[] = { 5, 3, 6, 8, 2, 9 }; int *p = arr + 2; printf("*p = %d\n", *p); printf("*p = %d\n", p[-1]); |
那么是用下标还是指针来操作数组呢?对于大部分人而言,下标的可读性会强一些。