linux c结构体、联合、枚举

2018-05-16 08:03:21

结构体可以用来表示复杂的数据结构,提高表示数据的能力,让你能创造新的形式。

//定义结构体
struct person {
    char name[10];
    int age;
};

//定义结构体变量
struct person p1;

//访问赋值
strcpy(p1.name, 'freecls');
p1.age = 27;

//定义结构体指针
struct person * p2;
p2 = &p1;

//用指针访问赋值
strcpy(p2->name,'freecls_2');
p2->age = 2;


重点:

1.结构体可以按值传递给函数,也可以从函数内返回,结构体可以赋值给另一个结构体,如果只是想改变结构体,建议按指针传递(速度快,无额外内存拷贝)

例子

typedef struct person {
    char name[10];
    int age;
} P;

struct person set_age_1(struct person p, int age);
void set_age_2(struct person * p, int age);

void main()
{
    struct person p1,p2;
    strcpy(p1.name, "freecls");
    strcpy(p2.name, "baidu");
    p1 = set_age_1(p1, 27);
    set_age_2(&p2, 22);
    
    printf("%s %d\n", p1.name, p1.age);
    printf("%s %d\n", p2.name, p2.age);
    
    //另一种声明
    P p3 = {"sina", 23};
    printf("%s %d\n", p3.name, p3.age);
    
    //进阶用法
    P *p4 = malloc(sizeof(P));
    p4->age = 24;
    strcpy(p4->name, "csdn");
    printf("%s %d\n", p4->name, p4->age);
    
}

//按值传递并返回结构体多了2次内存复制
struct person set_age_1(struct person p, int age){
    p.age = age;
    
    return p;
}


void set_age_2(struct person *p, int age){
    p->age = age;
}


位字段

位字段可以节省空间,通过一个结构体来声明,位字段是一个signed int或unsigned int类型变量中的一组相邻的位。
1.用结构体声明的位字段变量,占用的内存为unsigned int大小的整数倍,也就是就算你只用了1位,实际也占用了4个字节大小。
2.如果总位数超过32位,则会开辟下一个unsigned int大小的内存
3.一个字段不允许跨越unsigned int之间的边界,也就是即占用上一个unsigned int一部分,又占用下一个unsigned int一部分。
4.未命名的字段可以拿来填充,使用一个未命名的宽度为0的字段会填充满当前的unsigned int大小,即强制下一个字段会从下一个unsigned int开始。

#include<stdio.h>

void main()
{
    struct{
        unsigned int a : 1;
        unsigned int b : 1;
        unsigned int c : 1;
        unsigned int d : 1;
    } bit_1;
    
    //a,b,c,d只能为1或0
    bit_1.b = 0;
    bit_1.c = 1;
    
    //0    1    4
    printf("%d %d %d\n", bit_1.b, bit_1.c, sizeof(bit_1));
    
    struct{
        unsigned int a : 8;
        unsigned int : 16;      //填充了16位
        unsigned int b : 4;
        unsigned int : 0;       //填充了剩余的4位,刚好用完32位
    } bit_2;
    bit_2.a = 122;
    
    //122    4
    printf("%d %d\n", bit_2.a, sizeof(bit_2));
    
    struct{
        unsigned int a : 1;
        unsigned int : 0;       //填充了剩余的31位,刚好用完32位
        unsigned int b : 1;     //在下一个unsigned int的第1位,所以共占用8个字节
    } bit_3;
    bit_3.a = 1;
    
    //1    8
    printf("%d %d\n", bit_3.a, sizeof(bit_3));
}



联合是种数据类型,它能在内存中存储不同的数据类型,在例子中讲解

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef union hold{
    int i;
    double d;
    char l;
} u_h;

void main()
{
    //4 8 1
    printf("%d %d %d\n", sizeof(int),sizeof(double), sizeof(char));
    
    //由于这个union中double占用8个字节且是该联合中最大的数据类型
    //所以每次声明变量时不管你存的是int型还是char,都占用8字节
    u_h u1;
    u1.i = 22;      //存入int型22
    u1.d = 3.33;    //删除上面的22,改成3.33double型
    u1.l = 'a';     //删除上面的3.33,改成存'a'
    printf("%c\n", u1.l);
    
    char *tmp = (char *)&u1;
    printf("%c\n", tmp[0]);
    
}
/*
4 8 1
a
a
*/


枚举声明符号名称来表示整形常量关键字enum,枚举内部表示的是int型常量。虽然枚举符如one,two是int型,但是枚举变量可以是任意整数型,比如一个枚举的返回是0-2,所以编译器可以用unsigned char来表示。

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//0 1 2
enum days {zero,one,two};

//4 5 6
enum color {red=4,green,blue};

void main()
{
    printf("%d\n", green);
    
    //因为two是整形常量,所以可以这样写
    int arr[two] = {1,2};
    printf("%d %d\n", arr[0], arr[1]);
    
    //c1为枚举变量
    enum days c1 = one;
    printf("%d %d\n", c1, sizeof(c1));
    
}
/*
5
1 2
1 4
*/


总结

1.本文对linux c结构体、联合、枚举做了详细的介绍,下一篇再介绍字符串相关操作,如果有疑问可以给我留言
2.gcc4.8,运行环境centos7 64位
3.原文地址http://www.freecls.com/a/2712/23

©著作权归作者所有
收藏
推荐阅读
简介
天降大任于斯人也,必先苦其心志。