4

我有一个结构:

typedef struct stock {
  const char* key1p2;    // stock code
  const char* key2p2;    // short desc
  const char* desc1;     // description
  const char* prod_grp;  // product group
  const char dp_inqty;   // decimal places in quantity
  const long salprc_u;   // VAT excl price
  const long salprc_e;   // VAT includive price
  const long b_each;     // quantity in stock
  const long b_alloc;    // allocated qty
  const char* smsgr_id;  // subgroup
  const char** barcodes; // barcodes
} stock_t;

我想在每个股票结构的一行代码中初始化这个结构的实例数组。

我试过了:

stock_t data_stock[] = {
    { "0001", "Soup",  "Tomato Soup",     "71", 0, 100, 120, 10, 0, "",   {"12345", "23456", NULL} },
    { "0002", "Melon", "Melon and Ham",   "71", 0, 200, 240, 10, 0, "",   {"34567", "45678", NULL} },
    ...
    { NULL,   NULL,    NULL,              NULL, 0,   0,   0,  0, 0, NULL, NULL         }
};

但它失败了:

data.c:26:74: warning: incompatible pointer types initializing 'const char **' with an expression of type 'char [6]'
      [-Wincompatible-pointer-types]
  { "0001", "Soup",  "Tomato Soup",     "71", 0, 100, 120, 10, 0, "",   {"12345", "23456", NULL} },
                                                                         ^~~~~~~

有问题的是条形码字段,因为它是 char**。

(那是铿锵声,但 GCC 报告了类似的错误,但帮助不大。)

就好像编译器忽略了“12345”之前的大括号。

我可以使用以下方法解决该问题:

const char *barcodes0001[] = {"12345", "23456", NULL};

stock_t data_stock[] = {
  { "0001", "Soup",  "Tomato Soup",     "71", 0, 100, 120, 10, 0, "",   barcodes0001 },

这个问题的原因是 char [] 和 char *之间的不同,还是有更微妙的东西。(也许您可以初始化结构数组,但不能初始化数组结构。)

4

2 回答 2

6

并不是编译器忽略了您的大括号,而是您的大括号忽略了语言的语法规则。:)

该字段barcode是单个指针(指向指针,但这不是重点)。您需要提供一个有效的指针值,而您提供的大括号内容不匹配。

你也不能这样做:

struct foo {
  int a, b;
};

struct foo *pointer_to_foo = &{ 1, 2 }; /* Not valid code. */

这在逻辑上与您尝试做的事情相同。或者,删除struct,您也不能这样做:

int *pointer_to_a = &12; /* Not valid code. */

您分解barcode数据的解决方案就是这样做的方法。

于 2012-06-29T12:11:20.507 回答
5

为了避免必须声明一个命名的虚拟变量,您可以使用复合文字

stock_t data_stock[] = {
    { "0001", "Soup",  "Tomato Soup",     "71", 0, 100, 120, 10, 0, "",   (const char*[]){"12345", "23456", NULL} },
    { "0002", "Melon", "Melon and Ham",   "71", 0, 200, 240, 10, 0, "",   (const char*[]){"34567", "45678", NULL} },
    ...
    { NULL,   NULL,    NULL,              NULL, 0,   0,   0,  0, 0, NULL, NULL         }
};

这是一种定义局部临时变量的方法,其语法(type){ initializers }自 c99 以来可用(clang 和 gcc 有它们)。

编辑:这些复合文字的生命周期与您的变量相同,data_stock所以我想这没关系。无论如何,我认为您应该将大部分字段也标记为const,例如const char*const key1p2;

此外,如果您使用指定的初始化程序,它会更 容易阅读

{ .keyp1 = "0001", ... }
于 2012-06-29T12:26:33.060 回答