关于自定义类型

在c语言的自定义类型中,主要就是结构体,联合,位段,枚举这几种。今天就让我们详细讲述一下他们各自的特点。

在这几种自定义类型中,应用最广泛的我觉得就是结构体了吧。

比如我们定义一个结构体。

struct A{  
        char job[20];  
        int age;  
        char *p;
       float c;  
}a,*p;  

struct 是结构体的类型,A 是结构体的名称,而其中的  char job[20];   int age;   float height;等都是结构体的成员,最后的a *p  都是 定义出来的结构体变量。

在结构体定义创造的过程中,结构体的名称的存在保证了你可以以 struct A a;的形式在函数内定义结构体局部变量,如果把A 省去,则只能在结构体定义的最后像a这样定义全局变量,结构体变量可以省略吗?当然可以。结构体内可以没有结构体成员吗?不可以,定义要求结构体内部至少有一个结构体变量。

那什么时候可以省略结构体名称还可以在函数内部定义结构体变量?

typedef struct A{  
        int i;  
        char pc[0];  
}s;

通过typedef 定义过的类型可以直接在函数内部 s   arr[ 3 ];的形式 结构体变量。

在这里我们注意,我们不可以在结构体内套一个结构体,很容易理解,这样在开辟空间的时候会崩溃,一个结构体,套一个结构体,这个结构体大小无法计算。所以,我们通常通过嵌套结构体指针的方式进行定义。

 struct A{  
        int i;  
        char pc[2];  
        struct A *p;
}s;


在我们学习结构体的时候,我们很容易联想到另一个类型,数组,他们之间有很多相似处,比如,他们都是一起开辟的一段连续的内存单元;他们的地址都和首元素的地址在数值上相同,今天我们又特别强调一点,他们初始化也是相似的,也就是说结构体可以整体初始化。 struct A a={1,{1,2},NULL };

当然我们也可以用memset函数进行初始化0;

内存中,不是所有位置都可以访问的,而结构体内部个成员变量的类型是不同的,这样就存在内存对齐问题。

在考虑内存对齐问题中,我们重点注意四点。

1.结构体的第一个成员在内存中存储时,偏移量为0,也就是说默认是对齐的,也可以认为她不用对齐。

2.结构体的其他元素对齐到自身对齐数的整数倍,(对齐数:就是系统默认对齐数,和自身成员大小的较小值,系统默认的对齐数linux平台下是4,vs编译器下是8)

3.结构体的总大小要求是成员中最大对齐数的整数倍。

4.当结构体嵌套结构体时,内部的结构体的对齐数为其内部成员的最大对齐数,而外部的结构体在计算最大对齐数时应包含内部结构体的对齐数。

这样就可以解释,为什么计算我们用sizeof求结构体大小 并非是类型大小累加了。


关于位段,是按比特位分配存储的,他的功能是尽可能的压缩、节省空间。

struct node
{
    int a:4;     //位段a,占4位
    unsigned int  :0;     //无名位段,占0位
    unsigned int b:4;     //位段b,占4位
    int c:32;             //位段c,占32位
    int  :6;              //无名位段,占6位
};

当一个 字节剩余的空间可以放下当前变量时,就放,不能完全放下时,则开辟新的字节存放。

关于枚举,其实就是整形,他列举了一件事件所有发生的可能性,这样增强了程序的可读性,规范性。建议使用。

enum DAY
{
      MON=1, TUE, WED=4, THU, FRI, SAT, SUN
};

联合共用体 是指一段空间被多个变量共同使用,空间大小,为最大的变量大小。

union data{
 int n;
 char ch;
 double f;
};
union data a, b, c;

以上就是我个人关于自定义类型学习的一点小总结。




猜你喜欢

转载自blog.csdn.net/weixin_40921797/article/details/78942481