C++杂记

C++杂记


  • 不定期更新。
  • 都是个人总结,有任何错误希望指正。

字节对齐

数据在内存中需要按一定的字节数对齐排列,尽管内存是一个线性存储器,访问的时候会根据对齐字节数偏移访问。字节对齐是硬件要求的,主要是为了提高访问效率。
在了解了字节对齐的基本概念后,先了解一下C++各类型存储长度。

C++基本类型存储长度:

基本类型 32位编译器 64位编译器
int 4 4
unsigned int 4 4
short 2 2
long 4 4
long 8 8
float 4 4
double 8 8
char 1 1
int* 4 8

注:测试环境VS2013默认win32编译器和x64编译器。
具体测试代码见文章底部——代码1

  • 指针的大小跟指向类型无关,只跟编译器位数有关,通常64位机按8字节对齐,32位机按4字节对齐。这主要是因为指针存储的是地址,所以指针的大小只跟地址位数有关。

struct

struct结构体在C++中底层实现也是一个类,strcut在C++中存在的意义就是为了能够兼容C,也就是C和C++在内存存储上还是保持一致的。struct特别适合理解内存对齐问题,因为在基本类型使用上很难会让你感觉到需要内存对齐,而struct不同的成员变量组合会占用不同的内存空间,这就是内存对齐所带来的空间差别。下面举一个典型的实例:

struct A
{
    short a;
    int b;
    char c;
};

struct B
{
    int b;
    short a;
    char c;
};
sizepf(A) == sizeof(B) ?
sizeof(A) = ?
sizeof(B) = ?

回答这些问题必须弄清楚struct在内存中是如何存储的。实际存储如下:
A的内存存储结构:
C++杂记_第1张图片
B的内存存储结构:
C++杂记_第2张图片
由此可以很明显的看到struct在内存对齐下的影响。32位编译器下,内存按四字节对齐,struct A第一个short放下后,剩余两个字节,而int需要四个字节,所以放不下,只能放到下一个对齐单元格中。struct B类似,int放在第一个对齐单元格中,short接着放入第二个对齐单元格,还剩下两个字节,char只需要占一个字节,所以char可以接着放下。因此,可以很直观的得出,struct A在内存中占4 * 3=12字节,struct B在内存中占4 * 2 = 8个字节。
1. 具体测试代码见文章底部——代码2
2. 该代码在VS2013上64位编译器上运行结果会与32位编译器运行结果一致,按理论64位应该按8字节对齐了,可是在VS2013上的运行结果还是按4字节对齐,这是因为VS2013在代码生成时附带了默认对齐,默认按4字节对齐。如下图所示:
C++杂记_第3张图片

格式化输出

前些天参加腾讯实习生机试,在后面的编程题有一个关于格式化输出的题目,虽然当时用暴力求解出来,但是还是需要找到最适合的解决办法。
该题主要是考察输出格式为十六进制00000000八位输出。当时的解法就是每位分别输出,先判断有多少位,然后输出需要补多少个零。这种办法非常的累赘,速度慢,并且浪费空间。其实在printf中可以直接在前面补位,所以该题的解法为:

printf("%08x  ",c);

具体见代码3。

有空再更…


代码

代码1

/*基本数据类型长度测试代码*/
#include 

using namespace std;

int main()
{
    int integer;
    unsigned int uinteger;
    short shorter;
    long longer;
    long long llonger;
    float floater;
    double doubler;
    char character;
    int* pint;
    short* pshort;
    long* plong;
    long long* pllong;

    cout << "integer : " << sizeof(integer) << endl;
    cout << "unsigned integer : " << sizeof(uinteger) << endl;
    cout << "shorter : " << sizeof(shorter) << endl;
    cout << "long : " << sizeof(longer) << endl;
    cout << "long long : " << sizeof(llonger) << endl;
    cout << "float : " << sizeof(floater) << endl;
    cout << "double : " << sizeof(doubler) << endl;
    cout << "char : " << sizeof(character) << endl;
    cout << "point int : " << sizeof(pint) << endl;
    cout << "point short : " << sizeof(pshort) << endl;
    cout << "point long : " << sizeof(plong) << endl;
    cout << "point long long : " << sizeof(pllong) << endl;
    getchar();         //为了最后显示
    return 0;
}

代码2

/*sizeof(struct)*/
#include 

using namespace std;

struct A
{
    short a;
    int b;
    char c;
};

struct B
{
    int b;
    short a;
    char c;
};

int main()
{
    cout<< "A : " <<sizeof(A)<cout<< "B : " <<sizeof(B)<//为了最后显示
    return 0;
}

代码3

/*
输入:qwertyuiopasdfghqwertyuiopasdfghqwertyuiopasdfgh
输出:
00000000  71 77 65 72 74 79 75 69 6f 70 61 73 64 66 67 68  qwertyuiopasdfghqwertyuiopasdfghqwertyuiopasdfgh
00000010  71 77 65 72 74 79 75 69 6f 70 61 73 64 66 67 68  qwertyuiopasdfghqwertyuiopasdfghqwertyuiopasdfgh
00000020  71 77 65 72 74 79 75 69 6f 70 61 73 64 66 67 68  qwertyuiopasdfghqwertyuiopasdfghqwertyuiopasdfgh
*/

#include 
#include 
#include 

int main()
{
    char str[10005];
    gets_s(str);
    int len = strlen(str);
    long k = 0;
    for (int i = 0; i < len/16; ++i)
    {
        printf("%08x  ", k + i * 16);
        for (int j = 0; j < 16; ++j)
        {
            printf("%x ", str[j + i * 16]);
        }
        printf(" %s\n", str);
    }
    getchar();
    return 0;
}

你可能感兴趣的:(C++,c++,内存对齐,格式化输出,腾讯实习生机试)