在C语言编程中,有时为了达到减少运行的时间的目的,需要浪费一些空间;而有时为了节省空间,使它的运行时间增长。而字节对齐则是为了访问效率,用空间换取时间。

要掌握字节对齐,首先得明确一下四个概念:

1.基本数据类型的自身对齐值

在32位系统下基本数据类型有其自身的对齐值:

char  1个字节

short  2个字节

Int    4个字节

double  8个字节

2.程序指定的对齐值

用#pragma(value)显式指定对齐值value

3.自定义类型的自身对齐值

即结构体或类的成员自身对齐的最大值

4.自定义类型的有效对齐值

自定义类型的自身对齐值和指定对其中最小的值

#include<stdio.h>

typedef struct Test

{

char a;

double b;

int c;

}Test;

void main()

{

printf("sizeof(Test) = %d\n",sizeof(Test));

}

对于Test结构体来说,首先先列出来结构体中数据成员数据类型的大小:

char a占4个字节,double b占8个字节,int c占4个字节。求出结构体的大小分两个步骤:

1.从结构体的第一个元素往下看,下面的数据的大小是上面数据大小的整数倍,如b的大小为8,而a的大小为4,a不为b的整数倍,所以给a补4个字节,使为b的整数倍。注意上面的概念为这个数据上面的所有类型大小之和。

2.看是否与自定义类型的对齐值对齐。上面已经解释过了自定义类型的对齐值即结构体或类的成员自身对齐的最大值,对于这个例子来说,double数据类型的大小为Test结构体中最大的,所以Test结构体的对齐值为8.所谓对齐,就是看所有数据大小之和是否是自定义类型的对齐值的整数倍。

从上面我们发现,当数据排放位置不同,结构体所占大小会有所变化,当自定义类型中的元素按类型的大小从小到大排列时,所占空间最小。

当结构体中嵌套结构体时不要慌,只要把构体看成一个数据元素,求解顺序跟上面的步骤是一样的。

当结构体按一个字节对齐时,结构体大小就是各成员自身大小之和。

当程序用#pragma(value)指定对齐值为value时,就要考虑有效的对齐值,如上所言:自定义类型的自身对齐值和指定对其中最小的值,这是什么意思呢?就拿上面的例子来说,如果指定对齐的value为4的话,自定义类型自身的对齐值为8,但是程序指定对齐值为4,所以他的有效对齐值为二者中最小的那个,即结构体的有效对齐值为4.针对这个例子,b占8个字节,a占一个字节,c占4个字节,所以给a补齐3个字节,所以结构体的总大小就是16个字节,是4的整数倍,不再需要补齐。因此最终结构体的大小就是16.

当内嵌结构体有名字时,结构体上升为类型,不占空间大小,而内嵌结构体有名字时,可以简单地看做其内部数据成员,不过要受到内嵌结构的约束,并且内嵌结构体自身也要对齐。

C语言之字节对齐的更多相关文章

  1. 转载:C语言的字节对齐及#pragma pack的使用

    C语言的字节对齐及#pragma pack的使用   C编译器的缺省字节对齐方式(自然对界) 在缺省情况下,C编译器为每一个变量或是数据单元按其自然对界条件分配空间. 在结构中,编译器为结构的每个成员 ...

  2. 【C语言】字节对齐(内存对齐)

    数据对齐 1.  对齐原则: [原则1]数据成员对齐规则:结构(struct)(或联合(union))的数据成员,第一个数据成员放在offset为0的地方,以后每个数据成员的对齐按照#pragma p ...

  3. 【C语言】字节对齐问题(以32位系统为例)

    1. 什么是对齐? 现代计算机中内存空间都是按照字节(byte)划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问,这就需要各类型 ...

  4. C语言学习 - 字节对齐

    字节对齐 字节对齐就是数据在内存中的位置. 假设一个变量的内存地址正好位于它长度的整数倍,他就被称做自然对齐.比方在32位cpu下.假设一个整型变量的地址为0x00000004,那它就是自然对齐的. ...

  5. C语言:内存字节对齐详解[转载]

    一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...

  6. C语言:内存字节对齐详解

    转:http://blog.csdn.net/arethe/article/details/2548867 一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论 ...

  7. C语言中内存对齐方式

    一.什么是对齐,以及为什么要对齐: 1. 现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在访问特定变量的时候经常在特定的内存地址访问, ...

  8. <摘录>字节对齐(强制对齐以及自然对齐)

    struct {}node; 32为的x86,window下VC下sizeof(node)的值为1,而linux的gcc下值为0: 一.WINDOWS下(VC--其实GCC和其原理基本一样,象这种问题 ...

  9. C语言的struct/union字节对齐

    C语言的一大优势就是对内存空间的控制,当然,一般情况下对于开发人员来说都是透明的.看一个始终困扰初学者的问题:字节对齐! 先看四个重要的基本概念:1.数据类型自身的对齐值:对于char型数据,其自身对 ...

随机推荐

  1. vi/vim使用指北 ---- Introducting the ex Editor

    本章介绍ex编辑器,为什么要介绍这样一个新的编辑器呢:其实ex编辑器不能算是一个新的编辑器,vi只是它的visual model,它已经是一个更普遍,基于行的编辑器.ex提供更大机动和范围的编辑命令. ...

  2. HDU 4588 Count The Carries(找规律,模拟)

    题目 大意: 求二进制的a加到b的进位数. 思路: 列出前几个2进制,找规律模拟. #include <stdio.h> #include <iostream> #includ ...

  3. 控制台应用程序的Main方法

    总结一下Main方法规则: 1.Main 方法名大小写有规范. 2.Main 方法返回类型只有 void.int两种返回类型. 3.Main 方法的参数可以是string[] args,也可以为空,只 ...

  4. hdu 4352 XHXJ's LIS 数位DP

    数位DP!dp[i][j][k]:第i位数,状态为j,长度为k 代码如下: #include<iostream> #include<stdio.h> #include<a ...

  5. hdu 3118(二进制枚举)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3118 思路:题目要求是去掉最少的边使得图中不存在路径长度为奇数的环,这个问题等价于在图中去掉若干条边, ...

  6. YII框架的依赖注入容器与服务定位器简述

    依赖注入容器 依赖注入(Dependency Injection,DI)容器就是一个对象use yii\di\Container,它知道怎样初始化并配置对象及其依赖的所有对象. 依赖注入和服务定位器都 ...

  7. Junit单元测试学习笔记三

    一.     高级 Fixture 上一篇文章中我们介绍了两个 Fixture 标注,分别是 @Before 和 @After ,我们来看看他们是否适合完成如下功能:有一个类是负责对大文件(超过 50 ...

  8. Linux进程间通信(IPC)

    序言 linux下的进程通信手段基本上是从Unix平台上的进程通信手段继承而来的. 而对Unix发展做出重大贡献的两大主力AT&T的贝尔实验室及BSD(加州大学伯克利分校的伯克利软件发布中心) ...

  9. 深入理解MVC与MVP

    http://www.cnblogs.com/seaky/archive/2011/04/06/1982533.html 在深入分析MVC和MVP之前,我们有必要回顾下经典的三层架构.分层是计算机学科 ...

  10. Spring MVC配置DispatcherServlet的url-pattern

    在配置Spring MVC的核心过滤器DispatcherServlet的url-pattern时是有要求的. <servlet> <servlet-name>...</ ...