【问题标题】:default value for struct member in CC中结构成员的默认值
【发布时间】:2012-11-22 21:44:24
【问题描述】:

是否可以为某些结构成员设置默认值? 我尝试了以下方法,但会导致语法错误:

typedef struct
{
  int flag = 3;
} MyStruct;

错误:

$ gcc -o testIt test.c 
test.c:7: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
test.c: In function ‘main’:
test.c:17: error: ‘struct <anonymous>’ has no member named ‘flag’

【问题讨论】:

  • 你可以为结构创建一个初始化函数。
  • 不在 C 语言中。您可以创建一个函数,该函数返回具有您想要的值的结构。
  • 当你创建它时,你可以像这样初始化值:stackoverflow.com/questions/749180/default-values-in-a-c-struct
  • 对于C++ struct,可以在构造函数中初始化默认数据

标签: c struct


【解决方案1】:

结构是一种数据类型。您不会为数据类型赋值。您为数据类型的实例/对象赋值。
所以不,这在 C 中是不可能的。

相反,您可以编写一个对结构实例进行初始化的函数。

或者,您可以这样做:

struct MyStruct_s 
{
    int id;
} MyStruct_default = {3};

typedef struct MyStruct_s MyStruct;

然后始终将您的新实例初始化为:

MyStruct mInstance = MyStruct_default;

【讨论】:

  • 如果我有一个全局数组:'MyStruct arr[MAX_SIXE];',该函数如何使用? (注意:我不能有一个 init() 函数来遍历所有成员并设置标志)
  • MyStruct_default 应声明为 const。
  • 感谢您的回答。最终制作了一个代码沙箱来在线测试它,一开始连接所有东西时遇到了麻烦,希望这对其他人有帮助:ideone.com/knQ7xS
【解决方案2】:

你不能这样做

改用下面的

typedef struct
{
   int id;
   char* name;
}employee;

employee emp = {
.id = 0, 
.name = "none"
};

您可以使用宏来定义初始化您的实例。每次您想定义新实例并初始化它时,这会让您更轻松。

typedef struct
{
   int id;
   char* name;
}employee;

#define INIT_EMPLOYEE(X) employee X = {.id = 0, .name ="none"}

在您的代码中,当您需要使用员工类型定义新实例时,您只需调用此宏,如下所示:

INIT_EMPLOYEE(emp);

【讨论】:

  • 如果您想传递给参数而不满足要求,这似乎不太好。
【解决方案3】:

我同意 Als 的观点,即您不能在 C 中定义结构时进行初始化。 但是您可以在创建实例时初始化结构,如下所示。

在 C 中,

 struct s {
        int i;
        int j;
    };

    struct s s_instance = { 10 ,20 };

在 C++ 中,可以在如下所示的结构定义中给出直接值

struct s {
    int i;

    s(): i(10)
    {
    }
};

【讨论】:

    【解决方案4】:

    你可以这样做:

    struct employee_s {
      int id;
      char* name;
    } employee_default = {0, "none"};
    
    typedef struct employee_s employee;
    

    然后你只需要记住在声明一​​个新的员工变量时进行默认初始化:

    employee foo = employee_default;
    

    或者,您始终可以通过工厂函数构建您的员工结构。

    【讨论】:

      【解决方案5】:

      像其他答案提到的那样创建一个默认结构:

      struct MyStruct
      {
          int flag;
      }
      
      MyStruct_default = {3};
      

      但是,上面的代码在头文件中不起作用——你会得到错误:multiple definition of 'MyStruct_default'。为了解决这个问题,在头文件中使用extern代替:

      struct MyStruct
      {
          int flag;
      };
      
      extern const struct MyStruct MyStruct_default;
      

      c 文件中:

      const struct MyStruct MyStruct_default = {3};
      

      希望这可以帮助任何遇到头文件问题的人。

      【讨论】:

      • 几年后的评论:如果您可以直接在头文件中执行此操作可能更有意义。
      【解决方案6】:

      如果您使用gcc,您可以在对象创建中提供designated initializers

      typedef struct
      {
         int id=0;
         char* name="none";
      }employee;
      
      employee e = 
      {
       .id = 0;
       .name = "none";
      };
      

      或者,简单地使用像数组初始化。

      employee e = {0 , "none"};

      【讨论】:

      【解决方案7】:

      更重要的是,要添加现有答案,您可以使用隐藏结构初始化程序的宏:

      #define DEFAULT_EMPLOYEE { 0, "none" }
      

      然后在你的代码中:

      employee john = DEFAULT_EMPLOYEE;
      

      【讨论】:

        【解决方案8】:

        你可以实现一个初始化函数:

        employee init_employee() {
          empolyee const e = {0,"none"};
          return e;
        }
        

        【讨论】:

        • 请注意,当定义它的块退出时,C 结构变量对象 e(无论是否为 const)将消失。如果是指针,则会导致悬空指针问题。因此,如果返回类型是指针,这不是一个好的解决方案。最好的方法是使用 C 结构初始化程序拥有一个具有默认值的静态全局结构变量对象,并使用变量的 set 和 get 函数在程序运行时更改其值。或者将局部结构变量对象作为参数传递给 set 函数,并在 set 函数内更改其属性值。
        • 抱歉,这是错误的@ecle。返回值是一个裸结构,而不是指针。它将被复制,而不是通过引用返回。老实说,编译器可能会优化它。
        • @bismask 不要误会我的意思。我确实提到了函数是否返回指针如果它是指针。也许你在我最近的编辑之前评论了我之前的评论。
        【解决方案9】:

        你可以使用一些函数来初始化struct,如下所示,

        typedef struct
        {
            int flag;
        } MyStruct;
        
        MyStruct GetMyStruct(int value)
        {
            MyStruct My = {0};
            My.flag = value;
            return My;
        }
        
        void main (void)
        {
            MyStruct temp;
            temp = GetMyStruct(3);
            printf("%d\n", temp.flag);
        }
        

        编辑:

        typedef struct
        {
            int flag;
        } MyStruct;
        
        MyStruct MyData[20];
        
        MyStruct GetMyStruct(int value)
        {
            MyStruct My = {0};
            My.flag = value;
            return My;
        }
        
        void main (void)
        {
            int i;
            for (i = 0; i < 20; i ++)
                MyData[i] = GetMyStruct(3);
        
            for (i = 0; i < 20; i ++)
                printf("%d\n", MyData[i].flag);
        }
        

        【讨论】:

        • 好吧,如果我想要一个全局结构数组怎么办,你建议如何调用 GetMyStruct()?
        • GetMyStruct 不应该使用 malloc 吗?
        【解决方案10】:

        您可以使用C preprocessor functions with varargscompound literalsdesignated initializers 的组合以获得最大的便利:

        typedef struct {
            int id;
            char* name;
        } employee;
        
        #define EMPLOYEE(...) ((employee) { .id = 0, .name = "none", ##__VA_ARGS__ })
        
        employee john = EMPLOYEE(.name="John");  // no id initialization
        employee jane = EMPLOYEE(.id=5);         // no name initialization
        

        【讨论】:

          【解决方案11】:

          如果你只使用这个结构一次,即创建一个全局/静态变量,你可以删除typedef,并立即初始化这个变量:

          struct {
              int id;
              char *name;
          } employee = {
              .id = 0,
              .name = "none"
          };
          

          然后,之后您可以在代码中使用employee

          【讨论】:

            【解决方案12】:

            结构体的初始化函数是授予它默认值的好方法:

            Mystruct s;
            Mystruct_init(&s);
            

            甚至更短:

            Mystruct s = Mystruct_init();  // this time init returns a struct
            

            【讨论】:

            • 如果我有一个全局数组:'MyStruct arr[MAX_SIXE];',该函数如何使用? (注意:我不能有一个 init() 函数来遍历所有成员并设置标志)
            【解决方案13】:

            默认值的另一种方法。创建一个与结构相同类型的初始化函数。这种方法在将大代码拆分为单独的文件时非常有用。

            struct structType{
              int flag;
            };
            
            struct structType InitializeMyStruct(){
                struct structType structInitialized;
                structInitialized.flag = 3;
                return(structInitialized); 
            };
            
            
            int main(){
                struct structType MyStruct = InitializeMyStruct();
            };
            

            【讨论】:

              【解决方案14】:

              你可以为它创建一个函数:

              typedef struct {
                  int id;
                  char name;
              } employee;
              
              void set_iv(employee *em);
              
              int main(){
                  employee em0; set_iv(&em0);
              }
              
              void set_iv(employee *em){
                  (*em).id = 0;
                  (*em).name = "none";
              }
              

              【讨论】:

                【解决方案15】:

                如果结构允许,另一种方法是使用带有默认值的#define:

                #define MYSTRUCT_INIT { 0, 0, true }
                
                typedef struct
                {
                    int id;
                    int flag;
                    bool foo;
                } MyStruct;
                

                用途:

                MyStruct val = MYSTRUCT_INIT;
                

                【讨论】:

                  【解决方案16】:

                  我认为你可以通过以下方式做到这一点,

                  typedef struct
                  {
                    int flag : 3;
                  } MyStruct;
                  

                  【讨论】:

                  猜你喜欢
                  • 2016-09-19
                  • 1970-01-01
                  • 1970-01-01
                  • 2010-11-17
                  • 1970-01-01
                  • 2010-10-19
                  • 1970-01-01
                  • 2010-11-07
                  相关资源
                  最近更新 更多