结构体

2018-09-29  本文已影响14人  Scott丶Wang

一、了解结构体

在C语言中,除了最常见用的数据类型,字符类型(char)、整数类型(short、int、long )、实型(float、double)......最常见也是最经典的还有一种数据类型,那就是结构体。

二、结构体经典面试题:

(1)什么是结构体?
(2)一般在什么情况下用到结构体?
(3)什么是结构体内存对齐?为什么要对齐?怎样对齐?
(4)对齐参数如何设置?可以设置为按照任意字节数对齐吗?
(5)如何知道结构体某个成员相对于结构体起始位置的偏移量?

三、 下面,我们围绕以上提出的6个问题来解释结构体。

(1)什么是结构体?
定义:结构体是一系列数据的集合这些数据可能描述了一个物体,也可能是对一个问题的抽象。举个栗子,简单的说,对于人,人有名字,性别,年龄,身高,体重等个人信息,那么,我们在定义这种个体的时候,就不能说它能用一个字符或整型变量来定义。 这时候,就需要结构体闪亮登场了。
eg:

struct People {
    char name[20];
    int age;
    char gender[3];
    float height;
};

(2)一般在什么情况下用到结构体?

(3)什么是结构体内存对齐?为什么要对齐?怎样对齐?
eg:

struct A {
    int a;
    char b;
    double c;
    char d;
};

解析:
在windows系统32位平台上:
int占4个字节
char占1个字节
float占4个字节
double占8个字节
int a从0偏移开始,占四个字节,即占用0,1,2,3,现在可用偏移为4偏移,接下来存char b; 由于4是1的倍数,故而,b占用4偏移,接下来可用偏移为5偏移,接下来该存double c; 由于5不是8的倍数,所以向后偏移5,6,7,都不是8的倍数,偏移到8时,8是8的倍数,故而c从8处开始存储,占用8,9,10,11,12,13,14,15偏移,现在可用偏移为16偏移,最后该存char d ;因为16是1的倍数,故d占用16偏移,接下来在整体向后偏移一位,现处于17偏移,min(默认对齐参数,类型最大字节数)=8;因为17不是8的倍数,所以继续向后偏移18…23都不是8的倍数,到24偏移处时,24为8的整数倍,故而,该结构体大小为24个字节。


20171021163101071.png

方法总结:

(4)对齐参数如何设置?可以设置为按照任意字节数对齐吗?
解析:在windows中,VS编译器下,默认对齐数为8;
在Linux中,默认对齐数为4
设置对齐参数可在结构体struct之前加上#pragma pack(对齐数),在struct之后加上#pragma pack;便可以设置对齐参数。
eg:

#pragma pack(4)
struct A {
    int a;
    char b;
    double c;
    char d;
};
#pragma pack;

对齐参数不能任意设置,只能是内置类型已有的字节数,如:char(1)、short(2),int(4),double(8)…不能是3,5…任意数。

(5)如何知道结构体某个成员相对于结构体起始位置的偏移量?
使用offsetof宏来判断结构体中成员的偏移地址。使用offsetof宏需要包含stddef.h头文件,该宏定义如下:

#define offsetof(type,menber) (size_t)&(((type*)0)->member)

巧妙之处在于将地址0强制转换为type类型的指针,从而定位到member在结构体中偏移位置,编译器认为0是一个有效的地址,从而认为0是type指针的起始地址。

上一篇 下一篇

猜你喜欢

热点阅读