结构体

首先来简单介绍一下结构体。结构体是一些值的集合,这些值成为它的成员。结构体的每个成员可能具有不同的类型,且都有自己的名字。所以结构体的成员由两部分构成,类型和名字。结构体创建的变量交结构变量,结构变量属于标量类型,可像对待其他标量类型那样执行相同类型的操作。

下边看一个例子来帮助理解这些概念。

结构体的声明

结构体在声明的时候必须要列出它包含的所有成员。

看如下两个结构体的声明

上边两种声明都是合法的。第一个结构体声明创建了一个名为x的结构变量,第二个结构体声明创建了一个y和一个z。y是一个包含了20个结构的数组,y的每一个元素都都包含结构体的这三个成员。而z是一个指针,它指向这个类型的结构。

虽然两个结构体的成员都相同,但是他们仍是两个不同的结构体,所以   z=&x  是非法的。

结构体可以在声明的同时定义变量,也可以先声明,在要用的时候再定义变量。定义的格式为struct   结构体名  变量名(struct  Simple  x)

再看下边这个例子

结构体的标签声明:

 此时 z=&x  是合法的。

结构体的typedef声明

 

注:如果想在多个源文件中使用同一种类型的结构体,应该吧标签声明或typedef的声明放在一个头文件中,当源文件需要这个声明是用#include 指令吧那个头文件包含进来就行了。

结构体的访问:

直接访问:通过点操作符(.)访问。访问格式为:结构体变量  .  需访问成员名(Stu .  name)。

间接访问:通过指向操作符(—>)访问。

p—>a  该式子可实现对成员a的访问。

结构体的初始化:

结构体是不能在声明的时候初始化的。

结构体是用一个位于花括号内部,由逗号分隔的初始值列表进行初始化

举个例子

结构的存储分配:

看如下例子:

#include <stdio.h>
#include <stdio.h>
struct LINE
{
      char a;
      int b;
      float c;
};
int main()
{
     printf("%d",sizeof(struct LINE));
     return 0;
}

它的最后结果会是什么呢?

会是几个成员类型大小的总和9么?来看一看程序的结果

可以看到并不是9,而是12.(可以自己去验证一下)

这是由于什么原因造成的呢,这就要提到内存对齐了。

首先来说一下内存对齐的3条规则(要牢记):

1、结构的第一个成员永远都放在结构的0偏移处。

      偏移就是往后挪,n偏移就是从系统默认开始分配内存的地方往后挪n个字节,0偏移就是挪0个,也就是相当于没有挪。

2、从第二个成员开始,都要对齐到某个对齐数的整数倍处。

      对齐数:结构体成员自身大小和默认对齐数的较小值。

      默认对齐数:VS-----8  linux-----4

3、结构体的总大小必须是最大对齐数的整数倍。

系统的默认对齐数是可以改的,使用#pragma pack( )设置默认对齐数

查看结构体中某个成员相对于结构体起始位置的偏移量

offsetof(A,a)  A是一个结构体变量,a是A的一个成员

4、如果结构体里边嵌套有一个结构体,对应的结构体成员要对齐到这个结构体的最大对齐数的整数倍。

现在以上边的例题来详细的讲解一遍

下面再举几个例子再熟悉一下这几条规则:

#include <iostream>
using namespace std;

struct B
{
	char d;    //占用0偏移   对齐数为1
	int e;	   //占用4-7偏移 对齐数为4
};

struct A
{
	int a;	   //占用0-3偏移  对齐数为4
	char c[6]; //占用4-9偏移  对齐数为1
	B b;       //占用12-19偏移,对齐数是4
		   //因为B类型的大小为8,对齐数为B的最大对齐数,即4。偏移位置为对齐数的整数倍
};

int main()
{
	cout << "size of A: " << sizeof(A) << endl;
	cout << "size of B: " << sizeof(B) << endl;
	cout << "a:" << offsetof(A, a) << endl;
	cout << "c:" << offsetof(A, c) << endl;
	cout << "b:" << offsetof(A, b) << endl;
	cout << "d:" << offsetof(B, d) << endl;
	cout << "e:" << offsetof(B, e) << endl;
	return 0;
}

讲了这么多关于内存对齐的规则和运用,那么为什么要内存对齐呢?

现在就来讲一下内存对齐的原因吧。

1、平台原因(移植原因):不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处去某些特定类型的数据,否则跑出硬件异常。

2、性能原因:数据结构(尤其是栈)应该尽可能地在自然边界上对齐。原因在于访问未对齐的内存,处理器需要作两次内存访问;而对齐的内存访问仅需要访问一次。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值