C语言中结构体内部成员的对齐

说明:

******不同的编译器和处理器,其结构体内部的成员有不同的对齐方式。

******使用sizeof()运算符计算结构体的长度。

###结构体中每个成员相对于结构首地址的偏移量都是成员大小的整数倍,如果有需要编译器会在成员之间加上填充字。

###结构体的总大小是结构体最宽基本类型成员大小的整数倍。如果需要编译器会在最后一个成员之后加上填充字。

struct A
{
<span style="white-space:pre">	</span>unsigned short a;<span style="white-space:pre">	</span>//4bytes
	unsigned int b;<span style="white-space:pre">		</span>//4bytes
	unsigned char c;<span style="white-space:pre">	</span>//4bytes
}aa;

按结构体成员对齐,应该给c分配一个字节的空间,但是还得按结构体的对齐方式,所以给c分配4个字节。sizeof(aa)==12

结构体成员对齐,应当按结构体中最大基本数据类型来分配存储空间,例如:当一个成员A分配的空间大于自己本身的大小时,若是下个成员B所需空间,A分配空间的剩下空间足以满足存储B的时候,那么就不会给B分配了,但是,若不能满足B的存储的话,会给B按结构体最大数据类型来分配。

###计算结构体某个成员相对于结构体首地址的偏移量,通过宏offsetof()可以获得。

#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
//TYPE:结构体的类型
//MEMBER:结构体中某个成员
/*
 *offsetof(,)宏解析:
 *(TYPE  *)0:将0强制转换成指向结构体首地址的指针(结构体首地址为0地址)
 *((TYPE *)0)->MEMBER:结构体中某个变量
 * &((TYPE *)0)->MEMBER:取成员变量MEMBER(都是在0地址的基础上增加的)的地址
 * (size_t) &((TYPE *)0)->MEMBER:将取到的地址强制转换成size_t数据类型。
 */

结构体变量的初始化:

结构体:

struct A
{
	unsigned short b;
	unsigned int a;
	unsigned short c;
	unsigned short f;
	unsigned short g;
	unsigned short d;
	unsigned char e;

};

第一种初始化方法:

struct A aa={
	.b=2,
	.a=1,
	.c=3,
	.d=4,
	.e=5,
	.f=6,
	.g=7
	};

第二种初始化方法:

struct A aa={1,2,3,4,5,6,7};

第三种初始化方法:

struct  A aa;
aa.b=2;
aa.a=1;
aa.c=3;
aa.d=4;
aa.e=5;
aa.f=6;
aa.g=7;

C语言中结构体内部成员的对齐,布布扣,bubuko.com

时间: 2024-10-10 21:19:59

C语言中结构体内部成员的对齐的相关文章

OpenCV 中结构体IplImage 成员width widthStep使用注意事项

OpenCV 中结构体IplImage 成员width,widthStep使用注意事项 width 是指的图片宽度是多少个像素,而这里widthStep是指的图片中的每一行占用多少个字节. 而且,widthStep会有字节对齐. 当需要对每个像素进行操作的时候,这里最好用widthStep做行递增变换. 比方说这里就是一个例子,明显,ptr_pixel_tmp是指向double类型的三通道图像,而ptr_pixel_img是unsigned char类型的三通道图像,double占八个字节. 于

C语言中结构体赋值问题的讨论(转载)

今天帮师姐调一个程序的BUG,师姐的程序中有个结构体直接赋值的语句,在我印象中结构体好像是不能直接赋值的,正如数组不能直接赋值那样,我怀疑这个地方有问题,但最后证明并不是这个问题.那么就总结一下C语言中结构体赋值的问题吧: 结构体直接赋值的实现 下面是一个实例: #include <stdio.h> struct Foo { char a; int b; double c; }foo1, foo2; //define two structs with three different field

C语言中结构体在函数中的应用

一.结构体与函数参数结构体作函数参数可分为传值与传指针.1.传值时结构体参数会被拷贝一份,在函数体内修改结构体参数成员的值实际上是修改调用参数的一个临时拷贝的成员的值,这不会影响到调用参数.在这种情况下,由于涉及到结构体参数的拷贝,程序空间及时间效率都会受到影响,所以这种方法基本不用.例如:typedef struct tagSTUDENT{char name[20];int age;}STUDENT; void fun(STUDENT stu){printf("stu.name=%s,stu.

语言中结构体变量和结构体类型的定义

1.结构体类型定义 定义方式1: Typedef struct  LNode {    int  data;  // 数据域    struct LNode   *next;  // 指针域 } *LinkList; 定义方式2: struct  LNode {    int  data;  // 数据域    struct LNode   *next;  // 指针域 }: Typedef struct  LNode  *LinkList; 以上两个定义方式是等价的,是将*LinkList定义

c语言中结构体指针

1.指向结构体的指针变量: C 语言中->是一个整体,它是用于指向结构体,假设我们在程序中定义了一个结构体,然后声明一个指针变量指向这个结构体,那么我们要用指针取出结构体中的数据,就要用到指向运算符"->". 举例说明: struct SunLL { int a; int b; int c; }; struct SunLL  * p;               //定义结构体指针 struct SunLL A = {1,2,3};    //定义一个SunLL类型的变量A

C语言中结构体基本知识

1 声明结构体 声明结构体 关键字struct 结构体名字 {类型修饰符 成员名};声明一个学生的结构体 第一种方法 struct student{    char name[20]; // 结构体成员中可以使用另外的构造类型.    int number;   // 每个成员之间使用;隔开.    int age;    float score;}; typedef struct student Student; // 将现有的类型修饰符该别名为 Student 关键词 typedef 用于改

C语言中结构体变量之间赋值

最近,我阅读了某新员工小刘写的C语言代码,发现其对结构体变量之间的赋值不是很熟悉.对于两个相同类型的结构体变量,他均采用的是逐个成员变量直接赋值的形式.如下的代码示例: 如上代码所示,tEmployeeInfoSrc和tEmployeeInfoDest是两个类型相同的结构体变量,tEmployeeInfoSrc(源结构体变量)中的各个成员变量已赋初值.现要使tEmployeeInfoDest(目的结构体变量)中的各个成员变量的值与tEmployeeInfoSrc中对应成员变量的值相同.小刘采用的

c语言中结构体的定义、初始化及内存分配

#include <stdio.h> struct person { char *name; int age; }; int main() { //结构体可以定义在函数内,也可以定义到函数外 //相当于全局变量与局部变量 // struct person // { // char *name; // int age; // }; struct person p1; //补齐算法,分配的存储空间为结构体中占用内存最大成员所占用内存的整数倍 //person结构体中占用内存最大的成员为指针,占用8

黑马程序员——c语言中结构体的使用以及注意事项和实际应用

1.结构体和数组的区别①结构体:结构体可以由多个不同类型的数据构成,可以 包含int double等多种类型②数组:数组则只能由多个相同类型数据构成 2.结构体的定义①先定义结构体类型 struct Person { int age; //age height name 三个变量可以称之为结构体成员或者属性 double height; char*name; } ②根据结构体类型定义结构体变量 struct Person p={20,1.75,"tom"}; p.age=30; p.n