初始化指针指针数组

时间:2009-03-03 22:31:38

标签: c arrays pointers

这个例子很好用:

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

但这看起来太多了:)。

6 个答案:

答案 0 :(得分: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 *的。它们也不是char。你可能想要:

static int daytab[][13] ...

答案 1 :(得分: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

但这是非法的。

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

答案 2 :(得分: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​​ 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 <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和clang测试了它,它打印出正确的结果。 顺便说一句。英特尔编译器的错误输出是编译器错误。

答案 3 :(得分: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};

答案 4 :(得分: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;
}

答案 5 :(得分:0)

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

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

请注意 const

编辑:由于“不起作用”,我指的是不良做法,容易出错,这可能会更糟。