struct用法:
struct在C语言中作为结构体。
结构体定义:
struct stu{
char job[20];
int age;
float height;
};
使用:
struct stu a;
//或者省略关键字struct
stu a;
也可以定义和使用同时:
struct stu{
char job[20];
int age;
float height;
} a;
在后续使用中,出现结构体类型的地方都可以在前面加struct,用来提醒别人这个类型是自定义结构体;当然也可以省略struct不写。
如下:
void func(struct stu x){
}
//也可以省略struct
void func(stu x){
}
struct对齐:
比如在32位系统中,定义如下两个内容相同的结构体A和B,他们仅顺序不同,输出其大小。
#include <cstdio>
#include <iostream>
using namespace std;
struct A{
int a;
char b;
short c;
};
struct B{
char b;
int a;
short c;
};
int main (){
cout<<sizeof(A)<<endl;
cout<<sizeof(B)<<endl;
}
输出结果为: 8 12
其内存分配如下:
在32位系统中,每次取地址都是4个字节4个字节的取。
在结构体A的定义中,int类型的a占4字节,char类型的b和short类型的c可以共用4个字节,在访问b和c时取的地址都一样,需要再分出b和c来。
在结构体B的定义中,char类型的b占1个字节,后面的int要占用4个字节,但是只剩3个,所以int类型的a只好再重新找一个地址。后面的c顺次存放。
定义B时,如果没有struct的对齐,而是依次存放的话,那么a会占用2 3 4 5这四个字节,如下图:(暂时不考虑c)
那么在读取a时,我们需要先取前4位地址(1--4),从中找出a的3位,再取4位地址(5--8),找出a的1位,再拼接成a,这需要两次读取,分离和一次拼接,无疑是麻烦的。
所以对齐的目的是使得数据的存放适应系统环境,以舍弃一些空间为代价来提高存取效率。
在32位系统中,指针变量的大小是4字节,而在64位系统中,指针的大小是8字节。这也说明32位系统寻址是32位(4字节),64位系统的寻址是64位(8字节)。
可以用语句 #pragma pack (N) 来指定以N字节的方式对齐。
如下是以2字节对齐,结构体C占用8字节。
分配如下:
b | 空 | a | a | a | a | c | c |
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
#include <cstdio>
#include <iostream>
using namespace std;
#pragma pack (2) /*指定按2字节对齐*/
struct C
{
char b;
int a;
short c;
};
int main (){
cout<<sizeof(C)<<endl;
}
对齐原则:
1. 数据类型有其自身的对齐值,也就是其占用空间的大小。
[bool和char:1] 、[short:2] 、[ int 和float :4] 、[long long和double :8]
2. 结构体或者类的自身对齐值是其成员类型中自身对齐值最大的那个值。
比如结构体中有long long,那么结构体就按8字节对齐。
3. 用语句#pragma pack (value)可以指定对齐值为value。
4. 当存在指定对齐值时,我们实际的对齐值按照 结构体和类的自身对齐值和指定对齐值中小的那个值。