你可能不知道的编程小问题:预处理、sizeof

面试题9、用一个定义宏FIND求一个结构体stuct里某个变量相对stuct的偏移量。
struct aa
{
	int a;
	char b[20];
};

答案--#define FIND(struct,e) (size_t)&(((struct*)0)->e)。FIND(aa,a);//等于0;FIND(aa,b);//等于4面试

解析--(struct *) 0表示把一段地址(以0开头的地址)看做struc(认为这里存储一个stuct变量);((struc *) 0)->e指向它的成员e;&(((struc*) 0)->e)取这个成员的地址,由于该结构体的首地址为0,因此就获得成员e距离结构体首地址的偏移量。(size_t) &(((struc*) 0)->e)把地址硬转为size_t类型(typedef unsigned int size_t)数组

注意:宏在C语言里及其重要,而在C++里的第一规则是:毫不应该去使用它,除非你不得不这样作!函数


面试题10、下面代码的输出结果是什么?spa

struct
{
	short a1;
	short a2;
	short a3;
}A;
struct
{
	long a1;
	short a2;
}B;
struct
{
	double a1;
	float a2;
	int b;
	char c;
}C;

int main()
{
	char s1[] = "0123456789";
	char* s2 = "0123456789";
	int s3[100];
	int* s4 = s3;
	
	cout<<sizeof(s1)<<endl;
	cout<<sizeof(s2)<<endl;
	cout<<sizeof(s3)<<endl;
	cout<<sizeof(s4)<<endl;
	cout<<sizeof(A)<<endl;
	cout<<sizeof(B)<<endl;
	cout<<sizeof(C)<<endl;
}
答案--

11-----s1表明一个数组,使用sizeof会返回该数组分配到了字节(虽然数组名跟指针同是地址,但表明的意义不同指针

4-------s2是一个指针,其长度是固定的,4字节code

400---s3分配了400个字节继承

4-------同s2字符串

6-------这里涉及到告终构体的对齐问题,结构体内的数据以最长的数据元素为对齐单位。a一、a二、a3都是2字节,因此sizeof(A)为6编译

8-------B中a1取4字节,a2去2字节,以4字节对齐,因此sizeof(B)为8class

24-----C中a1去8字节,a二、a3共占8字节、a4取1字节,因此sizeof(C)为24


面试题12、且看下列代码(sizeof和strlen的区别)

char s1[100] = "0123456789";
	int s2[100];

	cout<<sizeof(s1)<<" "<<strlen(s1);
	cout<<sizeof(s2)<<" "<<strlen(s2);//编译会出错
答案--100  10

解析--上题已经说到,sizeof返回该数组(类型)分配到的字节,sizeof(int)为4,它是一个运算符,返回类型是unsigned int <size_t>

strlen是一个函数,用来计算字符串的长度,只能用char* 作参数,且必须是以“\0”结尾的,若是你这样作:char* a; strlen(a);那么恭喜你,你的程序会立刻死掉。


面试题十3、且看下面代码(空类占用的空间)

class A
{

};
class A2
{

};
class B : public A
{

};
class C : public A,public A2
{

};
class D : public virtual A
{

};
class E
{
	virtual void f(){};
};

int main()
{
	cout<<sizeof(A)<<" ";
	cout<<sizeof(A2)<<" ";
	cout<<sizeof(B)<<" ";
	cout<<sizeof(C)<<" ";
	cout<<sizeof(D)<<" ";
	cout<<sizeof(E)<<" ";
}
答案--1  1  1  1  4  4

解析--空类占1字节空间(规定),单一继承和多重继承仍是占用1字节,可是涉及到虚函数、虚继承的有个虚表(虚指针),因此占用4字节。