C语言--struct和union

结构体

#include <stdio.h>

struct weapon{
    char name[6];
    int atk;
    int price;
} ; 

int main(){
    struct weapon weapon_1 = {"AK47",100,200};
    printf("%s\n",weapon_1.name);  // AK47 

    // 结构体指针
    struct weapon *w;
    w=&weapon_1;
    printf("%s\n",(*w).name);   // AK47 
    printf("%s\n",w->name);     // AK47 

    struct weapon weapon_2[2] = {
        {"AK48",110,210},
        {"AK49",120,220}    
    };

    struct weapon *p;
    p = weapon_2;
    printf("%s\n",p->name);     // AK48 
    p++;
    printf("%s\n",p->name);     // AK49

    // 总长度:字节对齐 
    printf("%d\n",sizeof(struct weapon)); // 16:8+4+4 

    return 0;
}

联合体

#include <stdio.h>

union data{
    char a;
    int b;
    int c;
} ; 

int main(){

    union data data_1;
    data_1.b= 10;

    // 变量地址相同   
    printf("%p\n",data_1.a);        // 0000000A
    printf("%p\n",data_1.b);        // 0000000A 
    printf("%p\n",data_1.c);        // 0000000A

    // 总长度为最长变量长度       
    printf("%lu\n",sizeof(union data));     // 4

    return 0;
}

结构体嵌套结构体指针

结构体如下:

struct head{
    unsigned int len;
};

struct cmap{
    struct head *h;
    long key;
    float value;

};

像上述这种指针结构体嵌套有指针的,或是但凡有指针的内存分配,都必须为每个指针变量单独分配内存空间!否则运行的时候,程序便会挂掉。

#include <stdio.h>

struct head{
    unsigned int len;
};

struct cmap{
    struct head *h;
    long key;
    float value;

};

int init_cmap(struct cmap* cm){
    // 需先为指针分配内存
    cm->h = (struct head *)malloc(sizeof(struct head));
    if( NULL == cm->h ){
        return -1;
    }

    // memset(&(cm->h->len),0,sizeof(unsigned int));
    cm->h->len =1;
    cm->key = 2;
    cm->value = 3;  

    return 0;
}


int main()
{
    struct cmap cm;

    init_cmap(&cm);
    printf("%hu\n%lu\n%f\n",cm.h->len,cm.key,cm.value); 

    free(cm.h); 

    return 0;
}

补充:

若是清0,可以用memset()函数:

int init_cmap(struct cmap* cm){

    memset(cm,0,sizeof(struct cmap));   
    cm->h = (struct head *)malloc(sizeof(struct head));
    if( NULL == cm->h ){
        return -1;
    }
    memset(cm->h,0,sizeof(struct head));

    return 0;
}

但是注意:

如果是字符数组的话,memset可以随便用,但是如果是其他类型的数组,一般只用来清零,如果是填充数据就不合适了,如:

memset(a, 1, sizeof(a));

想用这个来把a所有元素设置为1,是不成功的,为什么呢?因为memset函数每次填充的数据长度为一个字节,即为0x01,而a的一个元素长度为4个字节,即0x00000000,如果把0x01填充进去,则填充的结果是0x01010101,而不是我们期待的0x00000001,所以是不合适的,多用与结构体清零!且上述场景必须要先将外结构体数据清0,再将结构体内指针清0。

若需要结构体拷贝,可使用memcpy()函数:

void cpy(struct cmap * a, struct cmap * b){

    memcpy(a,b,sizeof(a));
    //a->h =b->h;
    a->key = b->key;
    a->value = b->value;

}

但注意:memcpy(a,b,sizeof(a)) 只能拷贝其中的指针对象;
且需注意如用sizeof(b),可能会造成a的内存溢出,例如:char a[100],b[50]; memcpy(a, b, sizeof(b));。

指向结构体的void*指针

void即“无类型”,void *则为“无类型指针”,可以指向任何数据类型。

如果我们用void*指向上述cmap结构体,那么必须先为外层结构体指针分配内存,再为内部节结构体指针分配内存

#include <stdio.h>

struct head{
    unsigned int len;
};

struct cmap{
    struct head *h;
    long key;
    float value;

} *cm;

int init_cmap(void **state){
    // 需先为外层结构体指针分配内存,再为内部节结构体指针分配内存 
    cm = (struct cmap *)malloc(sizeof(struct cmap));
    cm->h = (struct head *)malloc(sizeof(struct head));
    if( NULL == cm || NULL == cm->h ){
        return -1;
    }
    cm->h->len =1;
    cm->key = 2;
    cm->value = 3;  

    *state = (void *)cm; //强制转换

    return 0;
}


int main()
{
    void* state;

    init_cmap(&state);  
    printf("%lu\n%f\n",((struct cmap*)state)->key,((struct cmap*)state)->value); //强制转换

    free(cm->h); 
    free(cm);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值