C语言malloc创建struct同时初始化成员变量

本文介绍如何在C语言中使用malloc创建struct的同时初始化成员变量,借助GCC的扩展特性和C99的语法,可以实现一行代码完成这个任务。通过示例代码展示具体操作,并引用了相关StackOverflow问题的链接以供参考。

写过C程序都知道,malloc了新的struct之后,经常跟着一大串的赋值\初始化语句。其实这些可以用一行漂亮的代码搞定。

先上代码:

#define new(type, ...) ({\
       type* __t = (type*) malloc(sizeof(type));\
       *__t = (type){__VA_ARGS__};\
       __t; })

使用示例:

struct S {
    union {
        int x, y;
    };
    enum {AA, BB} e;
};
int main() {
    struct S *s1 = new(struct S);
    struct S *s2 = new(struct S, 12);
    struct S *s3 = new(struct S, 12, BB);
    struct S *s4 = new(struct S, .e = BB, .x = 12);
}

这段代码仅在GCC里work,因为用到了GCC的一个扩展特性,加了括号的block(({ }))可以带有返回值,即最后一个语句的返回值。

还用到了C99的一个feature,就是那个非常酷炫的.field =的赋值。

另外三个点的宏定义,看例子就差不多明白了吧。

Ref.
http://stackoverflow.com/questions/2679182/have-macro-return-a-value
http://stackoverflow.com/questions/3016107/what-is-tagged-structure-initialization-syntax
http://gcc.gnu.org/onlinedocs/cpp/Variadic-Macros.html

<think>嗯,用户想了解如何在C语言同时声明和初始化变量。我需要先回忆一下C语言的基础知识,变量声明和初始化的基本规则。根据引用[1]和引用[2],显式初始化就是在声明的时候直接赋值。比如int a = 10; 这样。 用户可能需要具体的例子,所以应该给出不同类型的变量初始化示例,比如整型、浮点型、字符型,甚至指针和结构体。引用[3]提到了指针变量的初始化,比如int *ip = &a;。而引用[4]则涉及结构体初始化,比如struct Student s = {"Tom", 18, 1};。 还要注意未初始化的变量可能会导致未定义行为,特别是局部变量,这点引用[5]强调了。所以在回答中需要提醒用户在使用前必须初始化,尤其是局部变量。 可能用户是初学者,所以步骤要分清楚,先讲声明和初始化的基本语法,再分类型举例,最后注意事项。这样结构清晰,容易理解。同时要引用相关的文献来支持每个点,比如显式初始化引用[2],结构体初始化引用[4]等。 确保回答中的代码示例正确,比如变量声明的语法,结构体的定义方式。还要检查是否有遗漏的情况,比如数组的初始化或者指针的特殊情况。可能需要提到数组如int arr[3] = {1,2,3};这样的例子。 最后,生成相关问题时要围绕变量初始化的扩展内容,比如不同数据类型的初始化、未初始化的后果、结构体和指针的初始化等,这样用户可以有进一步学习的方向。</think>### 如何在C语言中声明并初始化变量? 在C语言中,变量的**声明与初始化**可以同步完成,即在定义变量时直接赋予初始值。这种操作能确保变量在使用前具有明确的初始状态,避免因未初始化导致的未定义行为[^1][^2]。以下是具体分类和示例: --- #### 一、基本数据类型初始化 1. **整型变量** ```c int a = 10; // 直接初始化 int b = 3 + 5; // 用表达式初始化 ``` 2. **浮点型变量** ```c float c = 3.14f; double d = 2.71828; ``` 3. **字符型变量** ```c char ch = 'A'; // 字符初始化 char str[] = "Hello"; // 字符数组初始化 ``` --- #### 二、指针变量初始化 指针变量需初始化为有效内存地址,可指向已存在的变量或动态分配的内存[^3]: ```c int num = 100; int *p = &num; // 指向整型变量num int *arr = (int*)malloc(5 * sizeof(int)); // 动态分配内存 ``` --- #### 三、结构体变量初始化 结构体初始化支持两种方式: 1. **按成员顺序赋值** ```c struct Student { char name[20]; int age; }; struct Student s1 = {"Alice", 20}; // 直接初始化[^4] ``` 2. **指定成员赋值(C99后支持)** ```c struct Student s2 = {.age = 22, .name = "Bob"}; ``` --- #### 四、数组初始化 数组可通过列表初始化: ```c int arr1[3] = {1, 2, 3}; // 完全初始化 int arr2[5] = {0}; // 全部元素初始化为0 char str[] = "C Language"; // 自动推断长度 ``` --- #### 五、注意事项 1. **局部变量必须显式初始化** 未初始化的局部变量值为随机值,可能导致程序异常[^5]: ```c void func() { int x; // 错误:未初始化 int y = 0; // 正确:显式初始化 } ``` 2. **全局变量默认初始化为0** 全局变量和静态变量若未显式初始化,系统会自动赋值为0: ```c int global_var; // 默认初始化为0 static int static_var; // 同样初始化为0 ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值