C语言中字节对齐的几种方式小结

 更新时间:2025年12月18日 10:12:31   作者:青椒肉炒肉丝  
本文介绍了C语言中的字节对齐机制,包括自然对齐、预处理指令和编译器属性语法三种对齐方式,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

前言

C语言调试笔记,C语言中字节对齐的几种方式记录一下

字节对齐是指数据存储时按照一定的规则在内存中排列,使得数据的访问效率更高

一、自然对齐(默认对齐方式)

1.原理:

自然对齐是编译器默认的对齐方式。在这种方式下,数据类型按照其自身的长度进行对齐存储。

例如,char类型(通常为 1 字节)可以从任意地址开始存储,因为它的长度就是 1 字节;

short类型(通常为 2 字节)的存储地址是 2 的倍数;

int类型(通常为 4 字节)的存储地址是 4 的倍数;

double类型(通常为 8 字节)的存储地址是 8 的倍数等。

2.举例:

#include <stdio.h>
struct NaturalAlignment {
    char c;   // 1字节,地址可以是任意位置
    int i;    // 4字节,会自动对齐到4的倍数地址
    short s;  // 2字节,因为前面的int已经是4字节对齐,所以这里也自然对齐
};
int main() {
    struct NaturalAlignment na;
    printf("Size of struct NaturalAlignment: %ld\n", sizeof(na));
    // 输出结果通常为1 + (3 padding) + 4 + 2 = 10字节
    // 其中3字节是为了让int能从4的倍数地址开始存储而填充的字节
    return 0;
}

注意! 某些编译器可能执行结果是12,这跟32位和64位系统中机器字长有关。但是我们验证的是此种对齐方式

二、预处理指令

1.原理:

#pragma pack(n) 是一种预处理指令,用于指定结构体或联合体成员的对齐方式。

其中n表示对齐字节数,编译器会按照这个指定的字节数来对齐成员。

它会尽量按照不超过n字节的边界来对齐成员,但如果成员本身长度大于n,则按照成员自身长度对齐

2.举例

代码如下(示例):

#include <stdio.h>
#pragma pack(1)  // 指定按1字节对齐
struct PackedAlignment1 {
    char c;
    int i;
    short s;
};
#pragma pack()   // 恢复默认对齐方式
#pragma pack(2)  // 指定按2字节对齐
struct PackedAlignment2 {
    char c;
    int i;
    short s;
};
#pragma pack()   // 恢复默认对齐方式
int main() {
    struct PackedAlignment1 pa1;
    struct PackedAlignment2 pa2;
    printf("Size of struct PackedAlignment1: %ld\n", sizeof(pa1));
    // 输出结果为1 + 4 + 2 = 7字节,因为按1字节对齐,没有填充字节
    printf("Size of struct PackedAlignment2: %ld\n", sizeof(pa2));
    // 输出结果为1 + (1 padding) + 4 + 2 = 8字节
    // 因为按2字节对齐,char后填充1字节使int能从2的倍数地址开始存储
    return 0;
}

三、编译器一种属性语法

1.原理

这是 GCC 编译器提供的一种属性语法,用于指定变量或类型的对齐字节数。

它主要用于对结构体、联合体或者变量强制指定对齐方式,n为对齐字节数。

当用于结构体时,整个结构体的大小会是n的倍数。

2.举例

#include <stdio.h>
struct AlignedAttribute {
    char c;
    int i;
    short s;
}__attribute__((aligned(4)));  // 指定结构体按4字节对齐
int main() {
    struct AlignedAttribute aa;
    printf("Size of struct AlignedAttribute: %ld\n", sizeof(aa));
    // 输出结果为4 + 4 + 4 = 12字节
    // 因为按4字节对齐,char后填充3字节,short后填充2字节
    // 使整个结构体大小是4的倍数
    return 0;
}

总结

这些字节对齐方式在不同的场景下有不同的用途。在需要精确控制内存布局或者与硬件设备进行数据交互时,合理的字节对齐方式可以确保数据的正确读写和高效传输

到此这篇关于C语言中字节对齐的几种方式小结的文章就介绍到这了,更多相关C语言 字节对齐内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++无痛实现日期类的示例代码

    C++无痛实现日期类的示例代码

    凡是要写类必须要提到六大默认成员(六位大爷):构造函数、析构函数、拷贝构造函数、赋值重载函数、取地址重载函数(包括const对象和普通对象);那么这次的日期类又需要伺候哪几位大爷呢?本文就来详细说说
    2022-10-10
  • C语言:代码宏详解

    C语言:代码宏详解

    这篇文章主要介绍了 C语言宏定义使用实例详解的相关资料,需要的朋友可以参考下,希望能够给你带来帮助
    2021-09-09
  • 详解C语言数据结构之栈

    详解C语言数据结构之栈

    这篇文章主要为大家介绍了C语言数据结构之栈,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • 使用OpenCV实现检测和追踪车辆

    使用OpenCV实现检测和追踪车辆

    这篇文章主要为大家详细介绍了使用OpenCV实现检测和追踪车辆,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2018-01-01
  • C++课程设计之学生成绩管理系统

    C++课程设计之学生成绩管理系统

    这篇文章主要为大家详细介绍了C++课程设计之学生成绩管理系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-12-12
  • 在matlab中实现for循环的方法

    在matlab中实现for循环的方法

    for循环用来循环处理数据,break用于终止离它最近的一层for循环,continue用于跳过离它最近的一层for循环,接着执行下一次循环,本文重点给大家介绍在matlab中实现for循环的方法,感兴趣的朋友一起看看吧
    2021-11-11
  • centos 7 vscode cmake 编译c++工程的教程详解

    centos 7 vscode cmake 编译c++工程的教程详解

    这篇文章给大家介绍了centos 7 使用vscode+cmake配置简单c++项目的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧
    2020-05-05
  • C语言字符串与字符数组面试题中最易错考点详解

    C语言字符串与字符数组面试题中最易错考点详解

    这篇文章主要介绍了C语言字符串与字符数组面试题中最易错考点,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • C++获取字符串长度的几个函数方式

    C++获取字符串长度的几个函数方式

    这篇文章主要介绍了C++获取字符串长度的几个函数方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-12-12
  • 6个变态的C语言Hello World程序

    6个变态的C语言Hello World程序

    这篇文章主要介绍了6个变态的C语言Hello World程序,需要的朋友可以参考下
    2016-05-05

最新评论