1

使用 gcc (GCC) 4.4.6 ,我尝试编译这个程序 -

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 
  4 int main(int argc, char *argv[])
  5 {
  6 
  7     struct B {
  8         int i;
  9         char ch;
 10     };
 11 
 12     struct B *ptr;
 13 
 14     ptr = (struct B*) calloc(1, sizeof(struct B));
 15 
 16     *ptr = {
 17         .i = 10,
 18         .ch = 'c',
 19     };
 20 
 21     printf("%d,%c\n", ptr->i, ptr->ch);
 22 
 23     return 0;
 24 }
 25 

$ make
gcc -g -Wall -o test test.c 
test.c: In function ‘main’:
test.c:16: error: expected expression before ‘{’ token
make: *** [test] Error 1
4

5 回答 5

3

您正在谈论的“结构初始化表示法”使用术语“初始化”是有原因的:它旨在用于初始化上下文。您要做的根本不是初始化。是任务。此语法不会立即在赋值上下文中起作用。

为了仍然使用这种方便的语法,您必须创建另一个相同类型的结构,使用此语法对其进行初始化,然后使用赋值将该结构复制到您的结构中。例如

ptr = calloc(1, sizeof *ptr);

const struct B INIT = {
  .i = 10,
  .ch = 'c',
};

*ptr = INIT;

这已经实现了您想要做的事情,但是您可以通过使用C 语言的复合文字功能使上述内容更加紧凑

ptr = calloc(1, sizeof *ptr);

*ptr = (struct B) {
  .i = 10,
  .ch = 'c',
};

基本上,后一个代码示例可能就是您正在寻找的。但是,请注意,从概念上讲,这仍然不是初始化。它是一个赋值,它创建一个临时类型的对象,struct B然后将它分配给你的*ptr对象。

于 2013-08-26T05:52:26.320 回答
2
*ptr = {
   .i = 10,
   .ch = 'c',
};

这种用法称为指定初始化器,顾名思义,它仅用于初始化结构或数组,但您要做的是分配

指定初始化器的正确用法:

strcut B foo = {.i = 10, .ch = 'c'};

要分配结构,您仍然需要使用:

 ptr->i = 10;
 ptr->ch = 'c';

编辑:或者你可以使用像@Andrey T's answer中的复合文字:

*ptr = (struct B) {
  .i = 10,
  .ch = 'c',
};
于 2013-08-26T05:16:30.563 回答
1

如果要初始化(分配值)动态分配的结构,则需要在赋值的 RHS 上使用 C99 复合文字:

#include <stdio.h>
#include <stdlib.h>

int main(void)
{
    struct B { int i; char ch; };
    struct B *ptr = (struct B*) calloc(1, sizeof(struct B));
    *ptr = (struct B){ .i = 10, .ch = 'c', };

    printf("%d,%c\n", ptr->i, ptr->ch);
    return 0;
}

该符号使用强制转换和初始化程序,而不仅仅是初始化程序。

于 2013-08-26T06:06:42.903 回答
0

在结构初始值设定项中,使用 ' 指定要初始化的字段的名称。fieldname=' 在元素值之前。例如,给定以下结构,

结构点 { int x, y; };

以下初始化

结构点 p = { .y = value1, .x = value2};

相当于

结构点 p = { value1, value2};

另一种具有相同含义的语法,'fieldname:',如下所示:

结构点 p = { y: value2, x: value1};

'[ index]' 或 '. fieldname' 被称为指示符。下面的代码将起作用。对于指针YU Hao已经告诉..

#include<stdio.h>
#include<stdlib.h>


 int main(int argc, char *argv[])
 {

     struct B {
         int i;
         char ch;
     } ;

    struct B name = {
         .i = 10,
         .ch = 'c',
     };

     printf("%d,%c\n", name.i, name.ch);

     return 0;
 }
于 2013-08-26T05:36:59.847 回答
0
*ptr = {
   .i = 10,
   .ch = 'c',
};

这种用法称为指定初始化器,仅在初始化时使用,不用于赋值。据我所知,它不是指针,因为任何指针只分配了 4 个字节。

于 2013-08-26T05:47:35.830 回答