C语言-----结构体知识点总结

结构体定义:

我们先来看一下结构体的定义。什么叫结构体呢?结构是一些值的集合,这些值叫做成员变量,总体称为一个结构体,结构体的每个成员可以使不同类型的变量。结构体类型是一种自定义类型。用户根据需求自己进行的类型。

结构体的声明:

用一个栗子说明一下吧。

struct Stu
{
    char name[20];
    int age;
    char sex[5];
    double tel;
};

上述声明了一个学生的结构体,struct结构体关键字,Stu叫做结构体名,大括号里是它的成员,其中包括名字,年龄,性别,电话。
当结构体声明好的时候,并没有向内存申请空间,当创建了结构体变量struct Stu s1时,才向内存申请了空间。
特殊声明:(匿名结构体类型)

struct
{
    char name[20];
    int age;
    char sex[5];
    double tel;
}s1,s2;

匿名结构体类型变量,在声明这个结构体的时候就要定义s1,s2这些变量。
匿名结构体类型在成员变量一样的时候,但因为匿名,它也会被编译器认为成两种不同的类型。所以这是非法的。

结构体成员:

struct Stu
{
    char name[20];
    int age;
    char sex[5];
};

如何去访问结构体的成员呢?用操作符 .或者->

struct Stu s1;
    strcpy(s1.name, "lili");
    s1.age = 20;
    strcpy(s1.sex, "male");
struct Stu *pstu;
    (*pstu).age = 20;
    pstu->age = 20;

结构体初始化:

struct Stu s1 = { “lili” , 20 , “nv” };
也可以在声明结构体定义变量的时候进行初始化。

struct Stu
{
    char name[20];
    int age;
    char sex[5];
}s1 =  { "lili" ,  20 ,  "nv" };

结构体传参:

结构体传参时,要传结构体的地址。
原因是在传递一个结构体对象时,结构体过大的话,参数要进行压栈,需要的系统开销就比较大,这就会导致性能下降。下面举一个简单的例子:

struct Stu
{
    char name[20];
    int age;
    char sex[5];
}s1 = {"lili",20,"nv"};
void print(struct Stu* ps)
{
    printf("%d\n", ps->age);
}
int main()
{
    print(&s1);
    system("pause");
    return 0;
}

位段:

什么是位段呢?位指的是比特位,位段是用结构体实现的。位段的成员类型成员需是 int,unsigned int,char 。位段的成员名后边有一个冒号和一个数字,表示占几个比特位。

struct A
{
    int _a : 2;
    int _b : 5;
    int _c : 10;
    int _d : 30;
};

这就是一个位段类型。它的大小是多少呢?
这里写图片描述
下来来看一下为啥结果是8?
那就得先来看一下位段是怎么进行内存分配了?

  1. 位段的成员可以是int,unsigned int, char ,char也属于整型家族。
  2. 位段上一次性开辟4 个字节空间(int,unsigned int)或者1 个字节空间(char)。
  3. 位段有什么不确定因素,是不跨平台的,可移植的程序应避免使用位段。

    因为是int类型,所以一开始申请四个字节空间大小,_a占2个比特位,_b占5个比特位,加起来就是7个比特位,_c占10个比特位,刚才第一个字节用了7个比特位,还有一个,不够_c存放,所以还需要二个字节空间才能放得下,就会还剩下6个比特位。_d占30个比特位,剩下申请的空间不够存放30个比特位,所以要重新开辟四个字节空间,因为位段开辟int类型一次需要开辟四个字节空间。所以结果输出是8,大小是8个字节。
    下来我们看一下位段的空间分配:

int main()
{
    char pub[4] = { 0 };
    struct S
    {
        char a : 3;
        char b : 4;
        char c : 5;
        char d : 4;
    }*ps;
    ps = (struct S*)pub;
    ps->a= 10;
    ps->b = 12;
    ps->c = 3;
    ps->d = 4;
    printf("%02x,%02x,%02x,%02x", pub[0],pub[1],pub[2],pub[3]);
    /*printf("%d\n", sizeof(struct A));*/
    system("pause");
    return 0;
}

结果:
这里写图片描述

看一下图解:
这里写图片描述
位段是不跨平台的,有以下几点注意的:

  1. int位段是有符号还是无符号是不确定的;
  2. 位段最大数目不确定;
  3. 位段成员在内存中从左向右分配,还是从右向左分配尚未定义;
  4. 当一个结构包含两个位段,第二个位段成员较大,无法容纳第一个位段剩余位时,是舍弃还是利用,也是不确定的。
    总结:位段可以很好地节省空间,但是存在跨平台问题。

猜你喜欢

转载自blog.csdn.net/abc_xixi111/article/details/80268777