当前位置: 首页 > article >正文

Linux-----结构体与联合体,大小端模式

 目录

结构体和联合体

结构体: 

联合体:

大小端模式

大端

小端

判断自身环境是大端还是小端


结构体和联合体

结构体: 

结构体会存在字段对齐的情况:

#include <stdio.h>

struct Fitz {
    char b;
    int a;
};

int main(int argc, char const *argv[])
{
    struct Fitz fitz;
    printf("%d\n", sizeof(fitz));
    
    return 0;
}

 案例,判断下面结构体字节数:

struct data {
    char name[10];
    int age;
};

答案:16个字节

 一个int 是4字节,上面有10个char,需要10个字节,根据结构体字段空间对齐的特性,应该按照4个字节划分,应该划分为4,4,4,4,第三个4实际上只存储了2个char类型,所以整体就是16个字节,如果按照下面的情况的话就存储满了,刚好满16字节。

struct data {
    char name[10];
    char a;
    char b;
    int age;
    
};
struct data {
    char name[10];
    int age;
    char a;
};

答案: 20个字节

划分为4,4,4,4,4,最后一个char需要另外一个4字节空间

struct data {
    char name[10];
    int age;
    char a;
};

struct node {
    struct data d;
    struct node* next;
};

 答案:node是32字节

在64位操作系统指针一般是8字节,32位是4字节,所以根据结构体对齐划分应该是8,8,8,8  所以一共32字节。64为操作系统为例:对于data这个结构体,原本是20个字节的,划分为4,4,4,4,4,如果扩展为8位的话,前两个4组成一个8,中间两个4组成一个8,剩下最后一个4扩展为一个8,所以划分8,8,8,一共24字节,最后加上指针占8字节,总共32字节。

联合体:

这玩意跟结构体写法上很像,比如

union main
{
    char name[10];
    int age;
};

union 中,所有成员共享相同的内存区域,因此 union 的大小是它 所有成员中占用空间最大的成员的大小,并可能进行适当的对齐填充,对齐方式如下:

  • 能够容纳成员中最大空间的成员的大小
  • 大小必须是对齐单位的倍数,而对齐单位取决于成员中对齐要求最大的成员。

所以根据这两个规则,上面那个联合体大小应该是12,首先选取对齐单位,显然是int 为4自己,然后最大成员是char name[10]是10字节,所以选择4最小倍数能大于10,所以是12字节。

 然后就是联合体值的问题,这里跟结构体不一样,结构体每一个成员都有自身的空间,所以你可以对这些成员分别赋值,但是联合体你只能选择其中一个成员赋值,如果第二次选择另外一个成员赋值的话就会把上一个成员清空掉,因为大家都是共享内存的,等于擦掉黑白重新写字一样。

    union main fitz;
    strcpy(fitz.name, "fitz");
    
    fitz.age = 18;
    printf("%s\n", fitz.name);
    printf("%d\n", fitz.age);

大小端模式

参考:什么是大小端?如何确定大小端?-CSDN博客

大小端(Big-endian 和 Little-endian)是计算机存储数据的一种方式,描述了多字节数据在内存中的排列顺序。

看下面案例就明白了。 

大端

说白了就是高位数据存放在低地址,低位数据存放高地址

小端

高位数据存放在高地址,低位数据存放低地址 

判断自身环境是大端还是小端

很简单,一个联合体就搞定了。成员只需要使用一个short类型(两个字节),还有两个连续char类型即可,然后对short类型赋值,方别查看低地址的char类型和高地址char类型对应的值是什么就行了: 

#include <stdio.h>

union main
{
    short a;
    char  b[2];
};


int main(int argc, char const* argv[])
{
    union main fitz;
    fitz.a = 0x1234;
    printf("%x\n", fitz.b[0]);
    printf("%x\n", fitz.b[1]);
    return 0;
}

可以看出输出结果低地址对应的是低位的0x34,高地址对应的是高位0x12,显然就是小端模式。 


http://www.kler.cn/a/473380.html

相关文章:

  • 比较procfs 、 sysctl和Netlink
  • Android车载音频系统目录
  • 详细讲一下什么是闭包,为什么会产生闭包,闭包会导致什么,闭包可以帮助我们在开发中干什么
  • 最近在盘gitlab.0.先review了一下docker
  • _decl_class_registry 与 metadata.sorted_tables的区别
  • Java-数据结构-链表-高频面试题(1)
  • 高等数学学习笔记 ☞ 函数的求导法则
  • Maven核心与单元测试
  • Linux-Ubuntu之I2C通信
  • iOS 逆向学习 - iOS Architecture Media Layer
  • Ubuntu 上安装 Docker
  • Kotlin OpenCV 画画
  • QPS和TPS 的区别是什么?QPS 大了会有什么问题,怎么解决?
  • Java基础概念
  • EasyExcel上传校验文件错误信息放到文件里以Base64 返回给前端
  • springboot + vue+elementUI图片上传流程
  • TypeScript语言的数据库交互
  • 【JavaEE进阶】获取Cookie/Session
  • OpenCV相机标定与3D重建(48)对三台相机进行极线校正(rectification)函数rectify3Collinear()的使用
  • vue3使用vue3-video-play播放m3u8视频
  • CTF知识点总结(二)
  • Linux中彻底卸载Oracle 19.25单实例数据库
  • Ubuntu更改内核
  • Docker 部署 elasticsearch:7.14.0 与 kibana:7.14.0
  • HDMI转DVI或DVI转HDMI电路设计实例
  • 【Web】软件系统安全赛CachedVisitor——记一次二开工具的经历