相濡以沫,不如相忘于江湖

专注,才是王道! 加班,代码,泡面,可乐。。
sizeof 各数据类型占空间大小
#include "stdafx.h"
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;

struct{

	short a1;
	short a2;
	short a3;
}A;
struct{

	long a1;
	short a2;
}B;

int main()
{
	char *ss1 = "0123456789";
	char ss2[] = "0123456789";
	char ss3[100] = "0123456789";
	int ss4[100];
	char q1[] = "abc";
	char q2[] = "a\n";
	char *q3 = "a\n";
	char *str1 = (char *)malloc(100);
	
	void *str2 = (void *) malloc(100);

	cout <<sizeof(ss1)<<" ";
	cout <<sizeof(ss2)<<" ";
	cout <<sizeof(ss3)<<" ";
	cout <<sizeof(ss4)<<" ";
	cout <<sizeof(q1)<<" ";
	cout <<sizeof(q2)<<" ";
	cout <<sizeof(q3)<<" ";
	cout <<sizeof(A)<<" ";
	cout <<sizeof(B)<<" ";
	cout <<sizeof(str1)<<" ";
	cout <<sizeof(str2)<<" ";

	return 0;
}

//----------------------------------------------------------

解析:

ss1是一个字符指针,指针的大小事一个定值,就是4,所以sizeof(ss1)是4。

ss2是一个字符数组,这个数组最初未定义大小,由具体填充值来定。填充值是“0123456789”。1个字符所占空间是1位,10个就是10位,再加上隐含的“\0”,所以一共是11位。

ss3也是一个字符数组,这个数组开始预分配100,所以它的大小一共是100位。

ss4也是一个整型数组,这个数组开始预分配100,但每个整型变量所占空间是4,所以它的大小一共是400位。

q1与ss2类似,所以是4.。

q2里面有一个“\n”,"\n"算做一位,所以它的空间大小是3.

q3是一个字符指针,指针的大小是一个定值,就是4,所以sizeof(q3)是4.


A和B是两个结构体。在默认情况下,为了方便对结构体内元素的访问和管理,当结构体内的元素的长度都小于处理器的位数的时候,便以结构体里面的最长的数据元素为对齐单位,也就是说,结构体的长度,一定是最长的数据元素的整数倍。如果结构体内存长度大于处理器位数的元素,那么就以处理器的位数为对齐单位。但是结构体内类型相同的连续元素将在连续的空间内,和数组一样。


结构体A中有3个short类型变量,各自以2字节对齐,结构体对齐参数按默认的8字节对齐,则a1,a2,a3都取2字节对齐,sizeof(A)为6,其也是2的整数倍。B中a1为4字节对齐,a2取2字节对齐,结构体默认对齐参数为8,则a1取4字节对齐,a2取2字节对齐;结构体大小6字节,6不为4的整数倍,补空字节,增到8时,符合所有条件,则sizeof(B)为8.


CPU的优化规则大致原则是这样的;对于n字节的元素(n=2,4,8...),它的首地址能被n整除,才能获得最好的性能。设计编译器的时候可以遵循这个原则:对于每一个变量,可以从当前位置向后找到第一个满足这个条件的地址作为首地址。例子比较特殊,因为即便采用这个原则,得到的结果也应该为6(long的首地址偏移量0000,short首地址偏移量0004,都符合要求)。但是结构体一般会面临数组分配的问题。编译器为了优化这种情况,干脆把它的大小设为8,这样就没有麻烦了,否则的话,会出现单个结构体的大小为6,而大小为n的结构体数组大小却为8X(n-1)+6的尴尬局面。IBM出这道题并不是在于考查理解语言本身和编译器,而是在于应聘者对计算机底层机制的理解和设计程序的原则。也就是说,如果让你设计编译器,你将怎样解决内存对齐的问题。


答案:

4,11,100,400,4,3,4,6,8,4,4。

posted on 2013-02-19 21:47  御剑江湖的专栏  阅读(326)  评论(0编辑  收藏  举报