C语言基本概念----字节与对齐

1. 字节(byte)

字节的概念是明确的,字节是存储器中可寻址的最小单元,而且每个单元都是由一系列连续的比特组成。每个字节都对应一个存储器地址,该地址称为字节地址 ,简称地址。

我们平时遇到的平台,其字节的长度大多数是8比特的,即一个字节由8个二进制位组成。但在C标准的各版本中并没有定义字节的长度,它由实现而定。比如一些计算机的字节长度是9比特,C实现时就按9比特定义字节的长度。因此,在C中,一个字节所包含的比特数是由实现定义的,但要求不能少于8比特。C实现在头文件limits.h中定义了字节的长度,我们可以在该文件中找到宏CHAR_BIT,它的数值可能会随着平台的不同而不同,但无论如何它都是定义了一个字节所包含的比特数。

2. 对齐(alignment)

受硬件布线的限制,或者为了提高存储器访问效率,要求特定类型的对象在存储器中的位置只能开始于某些特定的地址,而该地址是 N 的倍数( N 是2的幂,不超过物理内存芯片可以提供的实际地址范围),我们就称该地址是 N 字节对齐 (alignment)。当地址以二进制表示时,一个 N字节对齐的地址最低位至少有

个位是零。例如:假设int的尺寸是4个字节,即按对齐要求,int类型的对象,可以位于0x08000004、0x08000008和0x0800000C等字节地址上,它们都是4的倍数,这些对象是对齐于4 的。long long int类型的对象(8字节),只能位于0x08000000、0x08000008、0x08000010、0x08000020等字节地址上,它们都是8的倍数。

当被访问的对象为 N 字节长且内存地址为N字节对齐时,称内存访问为对齐 。当内存访问未对齐时,称为未对齐 。注意,根据定义,字节内存访问总是对齐的,即N 为1时,被访问的对象总是1字节对齐。

在C语言中,按照对齐来分配存储器时,各种类型的对象分配的内存的地址是不一样的。在Dev C++环境中,char对象是1字节对齐,int对象是4字节对齐,long long int对象是8字节对齐。

每个完整的对象类型都有一个称为对齐要求的属性,它是一个 size_t 类型的整数值,表示为该类型的对象分配的连续存储地址之间的字节数。有效的对齐值是 2 的非负整数幂。

一个类型的对齐要求可以用_Alignof(C11起)或 alignas查询。

为了满足结构中所有成员的对齐要求,可以在某些成员之后插入填充字节。

复制代码
#include <stdio.h>#include <stdalign.h>
struct S {    char a; // size: 1, alignment: 1    char b; // size: 1, alignment: 1}; // size: 2, alignment: 1// S.a和S.b可以分配到任何地址,因此,// 结构S的对象可以分配到任何地址
struct X {    int n;  // size: 4, alignment: 4    char c; // size: 1, alignment: 1    // 填充3个字节}; // size: 8, alignment: 4// 因为int的对齐要求(通常)是4,所以, // X.n必须在4字节的边界上分配,// 结构X的对象必须在4字节的边界上分配
int main(void){    printf("sizeof(struct S) = %zu\n", sizeof(struct S));    printf("alignof(struct S) = %zu\n", alignof(struct S));    printf("sizeof(struct X) = %zu\n", sizeof(struct X));    printf("alignof(struct X) = %zu\n", alignof(struct X));}

程序的运行结果可能是:

每个对象类型都将其对齐要求强加给该类型的每个对象。任何类型中最严格(最大)的基本对齐是max_align_t的对齐。最小(弱)的对齐方式是char、 signed char和 unsigned char类型的对齐方式,对齐值等于1。

如果使用_Alignas使对象的对齐比max_align_t更严格(更大),则它具有扩展的对齐要求。成员具有扩展对齐的结构或共用体类型是过度对齐的类型(over-aligned types)。如果支持过度对齐的类型,且它们的支持在每种存储期中可能不同,则由实现定义(C11起)。

相关推荐
听风说ml5 小时前
socket编程 【C语言】
c语言·udp·tcp·socket编程
学逆向的7 小时前
C 局部静态变量
c语言·开发语言·网络安全
UIU1147 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
论文复现现场7 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi7 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
秋天的怀念_David9 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
碧海银沙音频科技研究院9 小时前
在PC电脑上用Whisper→Marian算法实现离线语音翻译功能
算法·whisper
niyongsheng10 小时前
3D 装箱算法工程化:数据结构、放置启发式与支撑规则
数据结构·算法·rust
j7~12 小时前
【穷举、深搜与回溯算法】一棵决策树讲透全排列与子集
数据结构·c++·算法·leetcode·回溯·递归
傅科摆 _ py13 小时前
DP,贪心,堆和栈,二分力扣复习
开发语言·python·算法