初始化指针指针数组

这个例子工作正常:

static char *daytab[] = { "hello", "world" }; 

这不是:

 static char *daytab[] = { {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} }; 

我看到它的方式是第一个示例创建一个数组,该数组填充了指向两个字符串文字(它们本身就是数组)的指针。 第二个例子,IMO应该是相同的 – 创建一个数组并用指向两个char数组的指针填充它。

有人可以向我解释为什么第二个例子是错的吗?

PS你可能会这样写(没有测试过):

 static char a[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static char b[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; static char *daytab[] = { a, b }; 

但这看起来太多了:)。

这个:

 {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} 

只是一个数组初始化器。 它本身不会创建一个数组。 第一个例子,当你为一个指针分配一个字符串文字时,DID在静态存储中创建这些字符串(隐藏给你),然后只分配指向它们的指针。

所以基本上,没有办法用数组初始化器初始化你的char *。 您需要创建一个实际的数组,并将这些数字分配给它。 你必须做类似的事情:

 char a[][] = { {32, 30, 0}, {34, 32, 33, 0} }; // illegal 

但这是非法的。

您需要单独构建数组并将它们分配到数组中,就像上一个示例一样。

尝试:

 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} }; 

那些不是char *的。 它们也不是char。 你可能想要:

 static int daytab[][13] ... 

好吧,这个线程已经有点老了,但我正在处理同样的问题,并找到了一种方法来初始化一个指向数组的指针数组,如下所示:

 #include  using namespace std; int *a[] = { (int[]) { 0 } , (int[]) { 1 , 2 } , (int[]) { 3 , 4 , 5 } , (int[]) { 6 , 7 , 8 , 9 } }; main() { cout << a[0][0] << endl << a[1][0] << " " << a[1][1] << endl << a[2][0] << " " << a[2][1] << " " << a[2][2] << endl << a[3][0] << " " << a[3][1] << " " << a[3][2] << " " << a[3][3] << endl; } 

我得到输出,用gnu​​ g ++编译

 0 1 2 3 4 5 6 7 8 9 

并使用intel icpc进行编译

 0 1 1 40896 32767 -961756724 0 32767 4198878 0 

因此,语法似乎原则上是正确的,只是因为英特尔编译器没有正确地支持它,可能是由于缺乏这种风格的常见用法。


---编辑---

这里也是一个C版本(如需要):

 #include  int *a[] = { (int[]) { 0 } , (int[]) { 1 , 2 } , (int[]) { 3 , 4 , 5 } , (int[]) { 6 , 7 , 8 , 9 } }; int main() { printf( "%d\n" , a[0][0] ); printf( "%d %d\n" , a[1][0] , a[1][1] ); printf( "%d %d %d\n" , a[2][0] , a[2][1] , a[2][2] ); printf( "%d %d %d %d\n" , a[3][0] , a[3][1] , a[3][2] , a[3][3] ); } 

我用gcc和clang测试了它,它打印出正确的结果。 顺便说一句。 intel编译器的错误输出是编译器错误。

 static char **daytab; daytab=(char**)malloc(2*sizeof(char*)); daytab[0]=(char*)(char[]){0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; daytab[1]=(char*)(char[]){0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; 

第二个示例的语法是多维数组文字的语法。

多维数组不是指向数组的指针数组。

如果一件事的语法也是不同事物的语法,这将是令人惊讶的,这取决于它被声明的类型。

在第一个示例中,因为字符串文字被计算为指针而不是数组值,所以该值被计算为指针数组。 因为数组文字被计算为数组值而不是指针,所以第二个示例是一个多维数组 – 一个数组,其元素是数组值,而不是一个数组,其元素是指向数组值的指针。

以下代码演示了多维数组,指向数组的指针,指针数组和指针指针的组合。 在这三个中,只有指针数组和指针指针彼此兼容:

 void multi_array (int x[][4], size_t len) // multidimensional array { for (size_t i = 0; i < len; ++i) for (size_t j = 0; j < 4; ++j) putchar( 'a' + x[i][j] ); putchar('\n'); } void ptr_array (int (*x)[4], size_t len) // pointer to an array { ... as multi_array } void array_ptr (int *x[], size_t len) // array of pointers { ... as multi_array } void ptr_ptr (int **x, size_t len) // pointer to pointer { ... as multi_array } int main() { int a[][4] = { { 1,2,3,4 } }; int b[] = { 1,2,3,4 }; int* c[] = { b }; multi_array( a, 1 ); multi_array( (int[][4]) { { 1,2,3,4} }, 1 ); // literal syntax as value ptr_array( &b, 1 ); array_ptr( c, 1 ); ptr_ptr( c, 1 ); // only last two are the same return 0; } 

请注意,您的第一个示例也不起作用。 它需要是:

 static const char *daytab[] = { "hello", "world" }; 

注意const

编辑:并且通过“不工作”,我的意思是糟糕的做法,容易出错,这可能会更糟。