首页 文章

如何根据C编程语言标准初始化结构

提问于
浏览
381

我想初始化一个struct元素,在声明和初始化中拆分 . 这就是我所拥有的:

typedef struct MY_TYPE {
  bool flag;
  short int value;
  double stuff;
} MY_TYPE;

void function(void) {
  MY_TYPE a;
  ...
  a = { true, 15, 0.123 }
}

这是根据C编程语言标准(C89,C90,C99,C11等)声明和初始化 MY_TYPE 的局部变量的方法吗?或者有什么更好或至少有效吗?

Update 我最后有一个静态初始化元素,我根据需要设置每个子元素 .

14 回答

  • 0

    我不喜欢这些答案,所以我自己做了 . 我不知道这是不是ANSI C,它只是GCC 4.2.1的默认模式 . 我永远不会记得包围,所以我从我的数据子集开始,并与编译器错误消息作斗争,直到它关闭 . 可读性是我的首要任务 .

    // in a header:
        typedef unsigned char uchar;
    
        struct fields {
          uchar num;
          uchar lbl[35];
        };
    
        // in an actual c file (I have 2 in this case)
        struct fields labels[] = {
          {0,"Package"},
          {1,"Version"},
          {2,"Apport"},
          {3,"Architecture"},
          {4,"Bugs"},
          {5,"Description-md5"},
          {6,"Essential"},
          {7,"Filename"},
          {8,"Ghc-Package"},
          {9,"Gstreamer-Version"},
          {10,"Homepage"},
          {11,"Installed-Size"},
          {12,"MD5sum"},
          {13,"Maintainer"},
          {14,"Modaliases"},
          {15,"Multi-Arch"},
          {16,"Npp-Description"},
          {17,"Npp-File"},
          {18,"Npp-Name"},
          {19,"Origin"}
        };
    

    数据可以作为制表符分隔的文件开始生活,您可以将其搜索替换为按摩其他内容 . 是的,这是Debian的东西 . 所以一对外{}(表示数组),然后是每个结构内部的另一对 . 用逗号分隔 . 把东西放在 Headers 中并不是绝对必要的,但是我的结构中有大约50个项目,所以我想把它们放在一个单独的文件中,这样既可以防止代码混乱,也更容易替换 .

  • 13

    可以声明和初始化C中的结构,如下所示:

    typedef struct book
    {
        char title[10];
        char author[10];
        float price;
    } book;
    
    int main() {
        book b1={"DS", "Ajay", 250.0};
    
        printf("%s \t %s \t %f", b1.title, b1.author, b1.price);
    
        return 0;
    }
    
  • 169

    正如Ron Nuni所说:

    typedef struct Item {
        int a;
        float b;
        char* name;
    } Item;
    
    int main(void) {
        Item item = {5, 2.2, "George"};
        return 0;
    }
    

    需要记住的重要一点是:在结构中甚至初始化一个对象/变量时,其所有其他变量都将初始化为默认值 .

    如果你没有初始化你的struct中的值(即如果你只是声明那个变量),那么 variable.members 将包含"garbage values", only if the declaration is local!

    如果声明是 global or static (就像在这种情况下),所有未初始化的 variable.members 将自动初始化为:

    • 0 用于整数和浮点数

    • '\0' for char (当然这与 0 相同, char 是整数类型)

    • NULL 指针 .

  • 17

    你几乎得到了......

    MY_TYPE a = { true,15,0.123 };
    

    search on 'struct initialize c' shows me this

  • 82
    void function(void) {
      MY_TYPE a;
      a.flag = true;
      a.value = 15;
      a.stuff = 0.123;
    }
    
  • 4

    我看到你已经收到了关于ANSI C 99的答案,所以我将抛出关于ANSI C 89的问题.ANSI C 89允许你以这种方式初始化结构:

    typedef struct Item {
        int a;
        float b;
        char* name;
    } Item;
    
    int main(void) {
        Item item = { 5, 2.2, "George" };
        return 0;
    }
    

    需要记住的重要一点是,即使在结构中初始化一个对象/变量,其所有其他变量也将初始化为默认值 .

    如果不初始化结构中的值,则所有变量都将包含“垃圾值” .

    祝好运!

  • 626

    我找到了另一种初始化结构的方法 .

    结构:

    typedef struct test {
        int num;
        char* str;
    } test;
    

    初始化:

    test tt = {
        num: 42,
        str: "nice"
    };
    

    根据GCC的文档,此语法为obsolete since GCC 2.5 .

  • 2

    你可以用compound literal来做 . 根据该页面,它适用于C99(也算作ANSI C) .

    MY_TYPE a;
    
    a = (MY_TYPE) { .flag = true, .value = 123, .stuff = 0.456 };
    ...
    a = (MY_TYPE) { .value = 234, .stuff = 1.234, .flag = false };
    

    初始化器中的名称是可选的;你也可以写:

    a = (MY_TYPE) { true,  123, 0.456 };
    ...
    a = (MY_TYPE) { false, 234, 1.234 };
    
  • 2

    如果MS未更新为C99,则MY_TYPE a = {true,15,0.123};

  • 35

    我已经阅读了Microsoft Visual Studio 2015 Documentation for Initializing Aggregate Types,所有用 {...} 进行初始化的形式都在那里解释,但用点进行初始化,名为''designator' ' isn' t . 它也不起作用 .

    C99标准章节6.7.8初始化解释了指示符的可能性,但在我看来,复杂的结构并不是很清楚 . C99 standard as pdf .

    在我看来,它可能会更好

    • 对所有静态数据使用 = {0}; -initialization . 它对机器代码的工作量减少了 .

    • 例如,使用宏进行初始化

    typedef MyStruct_t{ int x, int a, int b; } MyStruct; define INIT_MyStruct(A,B) { 0, A, B}

    可以调整宏,其参数列表可以独立于更改的结构内容 . 如果应该初始化更少的元素是适当的 . 它也适用于嵌套结构 . 一个简单的形式是:在子程序中初始化:

    void init_MyStruct(MyStruct* thiz, int a, int b) {
      thiz->a = a; thiz->b = b; }
    

    这个例程看起来像C中的ObjectOriented . 使用 thiz ,而不是 this 也用C编译它!

    MyStruct data = {0}; //all is zero!
    init_MyStruct(&data, 3, 456);
    
  • 12

    在(ANSI)C99中,您可以使用 designated initializer 初始化结构:

    MY_TYPE a = { .flag = true, .value = 123, .stuff = 0.456 };
    

    编辑:其他成员初始化为零:"Omitted field members are implicitly initialized the same as objects that have static storage duration."(https://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

  • 1

    a = (MYTYPE){ true, 15, 0.123 };

    在C99会很好

  • 0

    C编程语言标准 ISO/IEC 9899:1999 (通常称为C99)允许使用 designated initializer 来初始化结构或联合的成员,如下所示:

    MY_TYPE a = { .stuff = 0.456, .flag = true, .value = 123 };
    

    它在 paragraph 7 ,ISO / IEC 9899:1999标准的 6.7.8 Initialization 中定义为:

    如果指定人员有表格 . 标识符然后当前对象(在下面定义)应具有结构或联合类型,并且标识符应该是该类型成员的名称 .

    请注意,同一部分的 paragraph 9 表示:

    除非另有明确说明,否则为了本子条款的目的,结构和联合类型的对象的未命名成员不参与初始化 . 即使在初始化之后,未命名的结构对象成员也具有不确定的值 .

    在GNU GCC实现中,省略的成员被初始化为零或零类型适当的值 . 如GNU GCC文档的6.27 Designated Initializers部分所述:

    省略的字段成员与具有静态存储持续时间的对象一样进行隐式初始化 .

    根据官方博客文章C++ Conformance Roadmap,Microsoft Visual C编译器应该自2013版以来支持指定的初始化程序 . MSDN Visual Studio文档中Initializers文章的段落 Initializing unions and structs 表明,未命名的成员与GNU GCC类似地初始化为零类似的适当值 .

    新的 ISO/IEC 9899:2011 标准(通常称为C11)已取代ISO / IEC 9899:1999保留了 6.7.9 Initialization 部分下的指定初始化者 . 它还保持 paragraph 9 不变 .

  • 0

    我一直在寻找一种初始化我的结构的好方法,我必须使用下面的(C99) . 这允许我以与普通类型相同的方式初始化单个结构或结构数组 .

    typedef struct {
        char *str;
        size_t len;
        jsmntok_t *tok;
        int tsz;
    } jsmn_ts;
    
    #define jsmn_ts_default (jsmn_ts){NULL, 0, NULL, 0}
    

    这可以在代码中使用:

    jsmn_ts mydata = jsmn_ts_default; /* initialization of a single struct */
    
    jsmn_ts myarray[10] = {jsmn_ts_default, jsmn_ts_default}; /* initialization of
                                                        first 2 structs in the array */
    

相关问题