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起)。

相关推荐
一个不知名程序员www20 小时前
算法学习入门---vector(C++)
c++·算法
云飞云共享云桌面20 小时前
无需配置传统电脑——智能装备工厂10个SolidWorks共享一台工作站
运维·服务器·前端·网络·算法·电脑
福尔摩斯张20 小时前
《C 语言指针从入门到精通:全面笔记 + 实战习题深度解析》(超详细)
linux·运维·服务器·c语言·开发语言·c++·算法
fashion 道格20 小时前
数据结构实战:深入理解队列的链式结构与实现
c语言·数据结构
橘颂TA20 小时前
【剑斩OFFER】算法的暴力美学——两整数之和
算法·leetcode·职场和发展
xxxxxxllllllshi21 小时前
【LeetCode Hot100----14-贪心算法(01-05),包含多种方法,详细思路与代码,让你一篇文章看懂所有!】
java·数据结构·算法·leetcode·贪心算法
前端小L21 小时前
图论专题(二十二):并查集的“逻辑审判”——判断「等式方程的可满足性」
算法·矩阵·深度优先·图论·宽度优先
铁手飞鹰21 小时前
二叉树(C语言,手撕)
c语言·数据结构·算法·二叉树·深度优先·广度优先
专业抄代码选手1 天前
【Leetcode】1930. 长度为 3 的不同回文子序列
javascript·算法·面试
[J] 一坚1 天前
深入浅出理解冒泡、插入排序和归并、快速排序递归调用过程
c语言·数据结构·算法·排序算法