首页 > 代码库 > C/C++基础笔试题1.0(字节对齐)

C/C++基础笔试题1.0(字节对齐)

传说中博文标题带有笔试、面试等点击率都会非常高呢?我也试试!

众生皆是码农命,我们这样的即将战秋招的渣渣。既没有超凡的能力。也没有流弊的项目,怎么破?

只有苦苦怒刷基础,笔试题,面试题。由于曾经经常刷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;
}

结果是什么呢?这个依据我们的“分床”规则。非常easy理解的。

以下我们来另外一个样例。

#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(字节对齐)