【问题标题】:Definition of structures and arrays结构和数组的定义
【发布时间】:2015-08-14 16:06:32
【问题描述】:

我有以下代码:

struct dmparam {
    char *p;
    char *v;
};

struct dmobj {
    int a;
    int b;
    struct dmparam *dmparam;
};


struct dmarray {
    struct dmobj *dmobj;
    struct dmentry {
        int func;
        struct dmarray *dmarray;
    } *dmentry;
};

struct dmarray atest = {
    {//objs
    {1, 11, NULL},
    {2, 22,
        {//params
        {"p1", "v1"},
        {"p2", "v2"},
        }//params
    }
    },//objs
    {//arays
        {101, {
                {//objs
                {1, 11, NULL},
                {2, 22,
                    {//params
                    {"p1", "v1"},
                    {"p2", "v2"},
                    }//params
                }
                },//objs
                NULL
        }
        }
    }//arrays
};

此代码生成以下编译警告:

test.c:26:2: warning: braces around scalar initializer [enabled by default]
  {//objs
  ^
test.c:26:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: braces around scalar initializer [enabled by default]
  {1, 11, NULL},
  ^
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: excess elements in scalar initializer [enabled by default]
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:27:2: warning: excess elements in scalar initializer [enabled by default]
test.c:27:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:28:2: warning: braces around scalar initializer [enabled by default]
  {2, 22,
  ^
test.c:28:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:28:2: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:28:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:28:2: warning: excess elements in scalar initializer [enabled by default]
test.c:28:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:29:3: warning: braces around scalar initializer [enabled by default]
   {//params
   ^
test.c:29:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:30:3: warning: braces around scalar initializer [enabled by default]
   {"p1", "v1"},
   ^
test.c:30:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:30:3: warning: initialization from incompatible pointer type [enabled by default]
test.c:30:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:30:3: warning: excess elements in scalar initializer [enabled by default]
test.c:30:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: braces around scalar initializer [enabled by default]
   {"p2", "v2"},
   ^
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: initialization from incompatible pointer type [enabled by default]
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: excess elements in scalar initializer [enabled by default]
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:31:3: warning: excess elements in scalar initializer [enabled by default]
test.c:31:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:32:3: warning: excess elements in scalar initializer [enabled by default]
   }//params
   ^
test.c:32:3: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:33:2: warning: excess elements in scalar initializer [enabled by default]
  }
  ^
test.c:33:2: warning: (near initialization for ‘atest.dmobj’) [enabled by default]
test.c:35:2: warning: braces around scalar initializer [enabled by default]
  {//arays
  ^
test.c:35:2: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:36:3: warning: braces around scalar initializer [enabled by default]
   {101, {
   ^
test.c:36:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:36:3: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:36:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:36:3: warning: braces around scalar initializer [enabled by default]
test.c:36:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:37:5: warning: braces around scalar initializer [enabled by default]
     {//objs
     ^
test.c:37:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: braces around scalar initializer [enabled by default]
     {1, 11, NULL},
     ^
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: excess elements in scalar initializer [enabled by default]
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:38:5: warning: excess elements in scalar initializer [enabled by default]
test.c:38:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:39:5: warning: braces around scalar initializer [enabled by default]
     {2, 22,
     ^
test.c:39:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:39:5: warning: initialization makes pointer from integer without a cast [enabled by default]
test.c:39:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:39:5: warning: excess elements in scalar initializer [enabled by default]
test.c:39:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:40:6: warning: braces around scalar initializer [enabled by default]
      {//params
      ^
test.c:40:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:41:6: warning: braces around scalar initializer [enabled by default]
      {"p1", "v1"},
      ^
test.c:41:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:41:6: warning: initialization from incompatible pointer type [enabled by default]
test.c:41:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:41:6: warning: excess elements in scalar initializer [enabled by default]
test.c:41:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: braces around scalar initializer [enabled by default]
      {"p2", "v2"},
      ^
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: initialization from incompatible pointer type [enabled by default]
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: excess elements in scalar initializer [enabled by default]
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:42:6: warning: excess elements in scalar initializer [enabled by default]
test.c:42:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:43:6: warning: excess elements in scalar initializer [enabled by default]
      }//params
      ^
test.c:43:6: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:44:5: warning: excess elements in scalar initializer [enabled by default]
     }
     ^
test.c:44:5: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:47:3: warning: excess elements in scalar initializer [enabled by default]
   }
   ^
test.c:47:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]
test.c:47:3: warning: excess elements in scalar initializer [enabled by default]
test.c:47:3: warning: (near initialization for ‘atest.dmentry’) [enabled by default]

我做错了什么?

最好的写法是什么?

【问题讨论】:

  • 你能不能至少告诉我们你的目标是什么以及你想要达到的具体目标是什么?
  • struct dmarray 的第一个初始化器必须是指向 struct dmobj 的指针。您不能在那里为 struct dmobj 编写初始化程序。冲洗,重复。
  • @mah 即使我将其定义为指针 struct dmarray *atest 我也遇到了同样的问题
  • 你的类型定义是struct dmarray { struct dmobj *dmobj; …。因此,在您的初始化定义struct dmarray atest = { … 中,代替 的第一项需要是struct dmobj *(指针),而不是struct dmobj(结构)。
  • MSVC - 给出一个错误:"too many initializers" 和两个警告:"'initializing' : 'dmobj *' 在间接级别上与 'int 不同'""'initializing' : 'dmentry *' 在间接级别上与 'int'" 不同。

标签: c


【解决方案1】:

此代码编译为完整的源文件:

struct dmparam {
    char *p;
    char *v;
};

struct dmobj {
    int a;
    int b;
    struct dmparam *dmparam;
};

struct dmarray {
    struct dmobj *dmobj;
    struct dmentry {
        int func;
        struct dmarray *dmarray;
    } *dmentry;
};

struct dmparam dp1 = { "abc", "xyz" };
struct dmparam dp2 = { "Mercury", "Uranus" };

struct dmobj do1 = { 1, 1, &dp1 };
struct dmobj do2 = { 2, -987, &dp2 };

struct dmentry de1 = { 0, 0 };

struct dmarray da1 = { &do1, &de1 };

观察你实际上拥有:

struct dmentry {
    int func;
    struct dmarray *dmarray;
};

struct dmarray {
    struct dmobj *dmobj;
    struct dmentry *dmentry;
};

所以每个struct dmarray 中只有两个项目,都是指针。此外,struct dmentry 的范围不受限制; C++中的规则不同。

所有这些都是标准 C90 代码(以及 C99 和 C11)。在 C99 或更高版本中,您还可以像这样进行初始化:

struct dmarray da2 =
{
    .dmobj = &(struct dmobj){ 9, 99, &(struct dmparam){ "Frigid", "Roasting" } },
    .dmentry = &(struct dmentry){ 1, &(struct dmarray){ 0, 0 } }
};

请注意,在初始化另一个指针时,您最终需要一个指向 struct dmarray 的指针。我躲开了并在嵌套结构中使用了一个空指针,但如果你愿意,你可以更深入。

仅作记录,代码在 Mac OS X 10.10.5 上使用 XCode 6.4 中的“gcc”(实际上是 clang)进行了测试:

$ gcc -std=c99 -pedantic -O3 -g -Wall -Wextra -Werror -c so.32014285.c
$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/usr/include/c++/4.2.1
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
$

有一个外部机会,尽管要求严格遵守 C99 标准,GCC 还是允许扩展。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-18
    • 2012-10-20
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 2013-11-09
    • 2014-08-11
    • 2018-10-20
    相关资源
    最近更新 更多