两者只有部分等价,其中区别在于:
static char daytab[2][13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
声明一个二维数组,其中包括为数组设置空间并确保daytab
引用该内存。但是:
static char (*daytab)[13] = {
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
在这段代码中,只声明了一个指针。因此,您尝试使用一个数组初始化程序来初始化指针,这并不像预期的那样工作。没有数组;没有为数组分配内存。相反,初始化器中的第一个数字被赋给指针daytab
,并且编译器会生成一个警告以让您知道已指定了许多额外的值,它们将被忽略。由于初始化器中的第一个数字是0
,因此您只是以一种相当冗长的方式设置daytab
为NULL
。
所以,如果您想要进行这种类型的初始化,请使用第一种版本--它会衰减为您在第二种版本中明确声明的相同指针类型,因此您可以以相同的方式使用它。第二个版本,使用数组指针,当您希望动态分配数组或获取对另一个已存在的数组的引用时需要使用它。
因此,您可以执行以下操作:
static char arr[2][3] = { { 1, 2, 3 }, { 4, 5, 6 } };
static char (*ptr)[3] = NULL;
ptr = arr;
...然后可以互换使用ptr
和arr
。或者这样:
static char (*ptr)[3] = NULL;
ptr = malloc(2 * sizeof(*ptr));
获取一个动态分配的二维数组(不是指针数组,而是真正的二维数组)。当然,在这种情况下它没有被初始化。
两种变体的“等价性”意味着,当2D数组衰减成指向其第一个元素的指针时,它会衰减为在第二个变量声明中声明的指针类型。一旦指针版本实际指向一个数组,两者就是等效的。但是,2D数组版本设置了数组的内存,而指针声明则没有… 指针可以被赋予新值(指向不同的数组),而2D数组变量不能。
在C99中,您可以这样做(如果至少不是static
):
char (*daytab)[13] = (char [][13]){
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31},
{0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
};
(*(daytab + leap))[i]
。 - Vladimir