传说中博文标题带有笔试、面试等点击率都会很高呢?我也试试!
众生皆是码农命,我们这种即将战秋招的渣渣,既没有超凡的能力,也没有流弊的项目,怎么破?
唯独苦苦怒刷基础,笔试题,面试题,因为以前常常刷OJ,所以很多面试题的编程题倒是可以解,但是笔试题或者基础题我就不记得了,唯独慢慢回想。
况且,写这种面试题,谁能写得赢JULY神。
今天首先讲得是字节对齐。
注意:我是一个渣,所以我只能按自己的理解来说了(要不然怎么会这么惨呢?)。如果你想看大神的解释,请看这里
来看个题目
#include <iostream> using namespace std; struct A{ char b; int a; }; int main() { A a; cout<<sizeof(a); return 0; }
请问上述输出的是什么呢?A.5,B.6.C7.D.8
答案是:D,如果你选A,那么恭喜你,你不知道什么叫字节对齐。(我也不知道,╮(╯▽╰)╭)
按我的理解来说,在结构体中,分配的空间,是有“格式”的,好比宿舍,我们住人的时候,床总是一样的,有些人可能会短,有些人可能会比较长,但是他们谁的床要一样的,为什么?一就是统一,二就是高效(统一是为了不同硬件上做出的效果一致,高效是源于读取规律性强)。
我们的床的长度决定于“最长的人的长度”(奇怪,为什么我总是要用长短来形容人,不科学。)
之后我们就可以分配床了,但是有时候会出现几个人睡一张床,看例子吧。
例子1
#include <iostream> using namespace std; struct A{ char b; int a; }; struct B{ char b; char c; int a; }; struct C{ char b,c,d; int a; }; int main() { A a; B b; C c; cout<<sizeof(a)<<" "<<sizeof(b)<<" "<<sizeof(c)<<endl;; return 0; }
输出的结果是8,8,8,
为什么?
最长的是4,那么就是4个字节为一张床啦,你能一起睡就一起睡,不能就自己再开一张呗。
最后来看一看这个题目,你觉得输出是什么?
之后你自己再用你的机器跑一下试试。
#include <iostream> using namespace std; struct A{//四个字节对齐 char b; int a; }; struct B{//四个字节对齐,b,c"共床" char b; char c; int a; }; struct C{//d开“新床” char b,c; int a; char d; }; struct D{//8字节对齐,short占两个字节的! short a; int b; long long c; }; struct E{//a开新床 int b; long long c; short a; }; struct F{//什么都没有,也要占一个 }; struct G{//那么double呢?8个字节 int b; double c; short a; }; int main() { A a; B b; C c; D d; E e; F f; G g; cout<<sizeof(a)<<" "<<sizeof(b)<<" "<<sizeof(c)<<" "<<sizeof(d)<<" "<<sizeof(e)<<" "<<sizeof(f)<<" "<<sizeof(g)<<endl;; cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C)<<" "<<sizeof(D)<<" "<<sizeof(E)<<" "<<sizeof(F)<<" "<<sizeof(G)<<endl;; return 0; }
结果是什么呢?这个根据我们的“分床”规则,很容易理解的。
下面我们来另外一个例子。
#include <iostream> using namespace std; #pragma pack(4) // 4字节对齐方式 struct A{//四个字节对齐 char b; int a; }; struct B{//四个字节对齐,b,c"共床" char b; char c; int a; }; struct C{//d开“新床” char b,c; int a; char d; }; struct D{//8字节对齐,short占两个字节的! short a; int b; long long c; }; struct E{//a开新床 int b; long long c; short a; }; struct F{//什么都没有,也要占一个 }; struct G{//那么double呢?8个字节 int b; double c; short a; }; #pragma pack() int main() { A a; B b; C c; D d; E e; F f; G g; cout<<sizeof(a)<<" "<<sizeof(b)<<" "<<sizeof(c)<<" "<<sizeof(d)<<" "<<sizeof(e)<<" "<<sizeof(f)<<" "<<sizeof(g)<<endl;; cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C)<<" "<<sizeof(D)<<" "<<sizeof(E)<<" "<<sizeof(F)<<" "<<sizeof(G)<<endl;; return 0; }
上面用到了#program pack(4),其意思为系统所给定的字节对齐为4,我们在实际采取的字节对齐是什么呢?取得是min(给定的,和结构体里面最大的)。
再下来,看这个例子就明白了
#include <iostream> using namespace std; #pragma pack(8) // 8字节对齐方式 struct A{//四个字节对齐 char b; int a; }; struct B{//四个字节对齐,b,c"共床" char b; char c; int a; }; struct C{//d开“新床” char b,c; int a; char d; }; struct D{//8字节对齐,short占两个字节的! short a; int b; long long c; }; struct E{//a开新床 int b; long long c; short a; }; struct F{//什么都没有,也要占一个 }; struct G{//那么double呢?8个字节 int b; double c; short a; }; #pragma pack() int main() { A a; B b; C c; D d; E e; F f; G g; cout<<sizeof(a)<<" "<<sizeof(b)<<" "<<sizeof(c)<<" "<<sizeof(d)<<" "<<sizeof(e)<<" "<<sizeof(f)<<" "<<sizeof(g)<<endl;; cout<<sizeof(A)<<" "<<sizeof(B)<<" "<<sizeof(C)<<" "<<sizeof(D)<<" "<<sizeof(E)<<" "<<sizeof(F)<<" "<<sizeof(G)<<endl;; return 0; }
来到这里,我想说的是,自己手动凑一凑对齐,可以节省一点空间,虽然在实际中这点空间并不会影响很大。
即
struct{
char a;
int b;
char c;
};
尽量改为
struct{
char a,c;
int b;
}
如果你有什么疑问,或者有什么不对的,记得评论指出我,不然难得会看我博客的人都被害了~
最后,想跟大家说,有些知识,不是别人说出来就是对的,要自己试,自己试觉得有理就是有理。
THEN
应博友的要求,我们谈一下栈对齐,大家可以看这里,按我肤浅的看法。
其实所谓栈对齐,就是在分配栈空间时候会按照2字节或者4字节对齐,这个要看具体编译环境。
在微软和GCC下效果数不一样,实际上我也不是特别懂,所以我也不好说怎么样。
C/C++基础笔试题1.0(字节对齐),布布扣,bubuko.com