C语言--struct和union

来源:互联网 发布:日本公安知乎 编辑:程序博客网 时间:2024/05/16 17:31

结构体

#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;}
原创粉丝点击