2009-03-03 213 views
3

这个例子正常工作:初始化指针数组的指针

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数组的指针填充它。

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

P.S.你可以这样写(没有测试过):

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

4答案,但我只看到一个?怎么来的? – Ree 2009-03-03 23:02:52

+0

已被作者删除。 – 2009-03-03 23:23:21

+0

我那天发生过。 SO似乎需要一段时间才能完全解释已删除的答案。它将尽快达到正确的数量。 – RBerteig 2009-03-03 23:47:25

回答

3

此:

{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 

但这是非法的。

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

3

尝试:

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 *的。它们也不是字符。你可能想:

static int daytab[][13] ... 
+0

那么,这将使大小为13的主数组的每个元素。如果我想要指向不同大小的数组的指针呢?至于char - char可以用于小整数值,所以这里不是问题。 – Ree 2009-03-03 22:44:09

0

第二个示例的语法是多维数组文本的语法。多维数组不是数组的指针数组。

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

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

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

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

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

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

注意常量

编辑:由“不起作用”,我的意思是不好的做法,容易出错,这可以说是更糟。

3

嗯,这个线程已经有点老了,但是我正在处理同样的问题,找到了一种方法来初始化数组的指针到数组,像这样:

#include <iostream> 
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克++

0 
1 2 
3 4 5 
6 7 8 9 

和英特尔ICPC编译

0 
1 1 
40896 32767 -961756724 
0 32767 4198878 0 

因此,语法的成书eems原则上是正确的,只是intel编译器不能正确地支持它,可能是由于缺乏这种风格的共同使用。


---编辑---

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

#include <stdio.h> 

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和铿锵测试,它打印出正确的结果。 Btw。 intel编译器的错误输出是一个编译器错误。

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