【问题标题】:Initializing an array of pointers to pointers初始化指向指针的指针数组
【发布时间】:2010-10-11 03:30:14
【问题描述】:

这个例子运行良好:

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

有人能解释一下为什么第二个例子是错误的吗?

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

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

但这看起来工作量太大了:)。

【问题讨论】:

  • 4 个答案,但我只看到一个?怎么会?
  • 前几天我也遇到过这种情况。所以似乎需要一段时间才能完全解决已删除的答案。它会“很快”稳定到正确的计数。

标签: c arrays pointers


【解决方案1】:

试试:

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] ...

【讨论】:

  • 嗯,这将使主数组的每个元素的大小为 13。如果我想要指向不同大小的数组的指针怎么办?至于 char - char 可以用于小整数值,所以这里没有问题。
  • 如果您指定第二个维度,则第一个维度将通过初始化列表定义。
  • 对不起,您的回答与我最初的评论无关。如果我按照你说的做,“这将使主数组的每个元素的大小为 13”。我所追求的是初始化一个指向不同大小数组的指针数组。
  • 你不能分配给任意大小的维度——这需要 Perl 和它的同类。我向您展示了一种有限的方法,您可以通过该方法解决问题的“这不是”部分。
【解决方案2】:

这个:

{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

但这是非法的。

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

【讨论】:

  • 不。如果指定第二个维度,第一个可以留[],所以你的例子/char a[][12] = {"hello", "world"};/是合法的。
  • 第一个例子是完全合法的——我不需要创建指向字符串的显式指针。然而,问题在于第二个例子。
  • 为什么我可以在第一个示例中将它们都留空,但不能在第二个示例中留空?字符串文字是数组,我在第二个示例中也有数组?
  • 现在您已经编辑了答案,现在事情变得更加清晰了。谢谢。
【解决方案3】:

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

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

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

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

下面的代码演示了多维数组、数组指针、指针数组和指针指针的组合。这三个中,只有指针数组和指向指针的指针是相互兼容的:

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

【讨论】:

    【解决方案4】:

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

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

    注意const

    编辑:我所说的“不起作用”是指糟糕的做法并且容易出错,这可以说是更糟。

    【讨论】:

      【解决方案5】:

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

      #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 对其进行了测试,它打印出正确的结果。 顺便提一句。英特尔编译器的错误输出是编译器错误。

      【讨论】:

      • 好的,但问题与 C 严格相关(请参阅标签),因此如果您的示例不包含 C++ 代码会更好。
      • 也不完全一样。我正在寻找同样的问题,但我需要命名数组。
      【解决方案6】:
      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};
      

      【讨论】:

        猜你喜欢
        • 2015-04-28
        • 1970-01-01
        • 1970-01-01
        • 2016-11-09
        • 2012-12-19
        • 1970-01-01
        • 1970-01-01
        • 2013-07-24
        • 1970-01-01
        相关资源
        最近更新 更多