C++杂记

C++杂记


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

字节对齐

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

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

基本类型32位编译器64位编译器
int44
unsigned int44
short22
long44
long88
float44
double88
char11
int*48

注:测试环境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的内存存储结构:
struct A
B的内存存储结构:
struct B
由此可以很明显的看到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字节对齐。如下图所示:
vs2013align

格式化输出

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

printf("%08x  ",c);

具体见代码3。

有空再更…


代码

代码1

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

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 <iostream>

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)<<endl;
    cout<< "B : " <<sizeof(B)<<endl;
    getchar();         //为了最后显示
    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 <stdio.h>
#include <stdlib.h>
#include <string>

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;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值