汕尾海湾 发表于 2024-8-16 19:59:44

自界说范例:结构体

一、结构体范例的声明

1、结构体的声明

结构体的声明:
struct tag
{
        member-list
};
2、结构体变量的创建和初始化

创建一个简单的学生信息结构体
struct student
{
        char name;
        int age;
        int score;
};
结构体默认初始化的顺序是结构体中创建变量的顺序。
初始化结构体:
struct student
{
        char name;
        int age;
        int score;
}s1, s2 = {"李华",18,88};//第一种初始化

struct student s3 = { "小明",20,100 };   //第二种初始化

int main()
{
        struct student s4 = { "张三",15,70 };    //第三种初始化
        struct student s5 = { .score = 99,.name = "小红",.age = 22 };//第四种初始化
        return 0;
}
https://i-blog.csdnimg.cn/direct/dacfcf233dee499786d514d758320def.png
3、特殊声明

匿名结构体
struct
{
        int a;
        char b;
        float c;
}x,*p;
匿名结构体只允许利用一次,p=&a黑白法请求
4、结构体的自引用

结构体是可以进行自引用的
错误的自引用:
struct stu
{
        int a;
        struct stu next;
};
正确的自引用:
struct stu
{
        int a;
        struct stu* next;
};
5、typedef重定名结构体

typedef struct Node
{
        int data;
        struct Node* next;
}Node;   //结构体命名为Node
二、结构体内存对⻬

1、对齐规则

把握结构体的对齐规则:

[*]结构体中第一个变量首对齐地址是偏移量为0的地址处。
[*]其他成员的对齐变量是范例的整数倍数的地址处。vs默认对齐量为8,linux中gcc没用对齐数,对齐数就是自身大小
[*]结构体的总大小为最大对齐数
[*]对于嵌套结构体,嵌套结构中对齐量是结构体中最大的一个变量整数倍数地址处,而竣事时是嵌套结构体的整数倍数
如盘算int 对齐数 4 8 4 int范例的大小对比默认值大小,谁小选谁是对齐数
//练习1
struct S1
{
        char c1;
        int i;
        char c2;
};
printf("%d\n", sizeof(struct S1));
//练习2
struct S2
{
        char c1;
        char c2;
        int i;
};
printf("%d\n", sizeof(struct S2));
//练习3
struct S3
{
        double d;
        char c;
        int i;
};
printf("%d\n", sizeof(struct S3));
//练习4-结构体嵌套问题
struct S4
{
        char c1;
        struct S3 s3;
        double d;
};
printf("%d\n", sizeof(struct S4));
https://i-blog.csdnimg.cn/direct/bda17a87776d4a42ab1965240c749d3a.png
在以上例题中,我们发现结构体中开辟的空间有许多空间被浪费了,以是在创建范例时,需要合理的排序
在例题1与例题2中,创建的范例是一样的,就由于范例创建的顺序不一样,导致占用内存不一样。
尽量使变量小的范例排在前面

2、为什么存在内存对齐

1、平台移植问题:不是全部的硬件平台都能访问任意地址上的任意数据
2、性能问题:假如没用地址对齐,处理器需要作两次的内存访问,而对齐的内存只需要访问一次
总结来说:拿空间换时间
3、修改默认对齐数

通过利用#pragma这个预处理指令,可以改变编译器的默认对齐数
#pragma pack(4)//设置对齐数变为4
struct stu
{
        char a;
        int b;
        char d;
        double c;
};
#pragma pack()//取消设置的对齐数,还原默认
int main()
{
        printf("%zd\n", sizeof(struct stu));
}
https://i-blog.csdnimg.cn/direct/7404bda230a141e69e709a40ca1fb327.png
三、结构体传参

struct stu
{
        char name;
        int age;
};

struct stu s1 = { "xiaoming",28 };

void print1(struct stu s1)
{
        printf("%d,%s\n", s1.age, s1.name);
}

void print2(struct stu* s1)
{
        printf("%d,%s\n", s1->age, s1->name);
}
int main()
{
        print1(s1);   //传值调用
        print2(&s1);//传址调用
        return 0;
}
输出:
https://i-blog.csdnimg.cn/direct/404a9de7efbe4fc28fb82ab5d4d20faa.png
结构体可以利用传值也可以利用传址,优先选用传址调用,如许不需要开辟新的空间,可以大大提高代码的运行效率。
四、结构体实现位段

1、什么是位段

位端可以限制结构体中创建变量占用内存的大小

[*]利用位段时,成名必须是unsigend int,int,sigent int,在c99中其他成员可以利用位段
[*]位段的创建在成员名后面加上一个冒号跟一个数字。
比如:
struct stu
{
        int _a : 4;
        int _b : 2;
        int _c : 1;
        int _d : 30;
};
2、位段的内存分配


[*]位段的成员可以是int,unsigent int ,signet int,char范例
[*]位段上的空间是以四个字节跟一个字节进行开辟空间的
[*]位段无法跨平台利用
struct stu
{
        int _a : 4;
        int _b : 10;
        int _c : 1;
        int _d : 20;
};

int main()
{
        printf("%zd\n", sizeof(struct stu));
        return;
}
输出:https://i-blog.csdnimg.cn/direct/75ec6a5a91534c469d4adcd7eea4bb80.png
假如没用位段,那么4个int范例的字节大小位12
位段是如何开辟空间的,如下:
https://i-blog.csdnimg.cn/direct/cd8f91b71d5f465a856a083cac57c62a.png
3、位段的跨平台问题

1、int位段是被当成有符号位还是无符号位是不确定的
2、位段中最大数是不确定的(有16位机器,假如设置段位超过16比特,那么就会出问题,32位机器同意也是)
3、内存是从左到右分配,还是从右到左分配是不确定的(vs是从右到左分配)
4、当一个结构体包罗两个位段时,第二个位段成员比较大,无法容纳第一个尾端剩余空间的时间,是否会舍弃剩余空间,这是不确定的。
总结:位段可以很好的节流空间,但存在跨平台问题
4、位段的应⽤

下图是⽹络协议中,IP数据报的格式,我们可以看到其中很多的属性只需要⼏个bit位就能描述,这⾥使⽤位段,可以或许实现想要的结果,也节流了空间,如许⽹络传输的数据报⼤⼩也会较⼩⼀些,对⽹络的畅通是有资助的。
https://i-blog.csdnimg.cn/direct/68813767d9db4e278e652c4c50308f6d.png
5、位段使⽤的留意事项

无法获取比特位的地址。
无法直接利用scanf来输入位段,但是可以赋值位段
struct stu
{
        int _a : 4;
        int _b : 10;
        int _c : 1;
        int _d : 20;
};

int main()
{
        struct stu s = { 0 };
        int n = 0;
        scanf("%d", &n);
        s._a = n;
        return;
}


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
页: [1]
查看完整版本: 自界说范例:结构体