struct test { short a; int b; char c; }; sizeof(struct test)
答案为:12
2、
#define P(a,b) a&b #define Q P(3,2)<<P(3,1) #undef P #define P(a,b) a+b void main() { printf("%d",Q); getchar(); }
答案为:80。分析:运算符+优先级大于<<,故为80。
3、
void main() { const int a = 1; int *p = const_cast<int*>(&a); *p = 2; const bool isEqual = &a==p; printf("%d,%d,%d",a,*p,isEqual?1:0); getchar(); }
答案为:1,2,1。
4、()、()类型的成员变流量只能在初始化列表中初始化。
答案:const修饰的、引用
5、请用三种方法交换int a,b。
答案:swap a with b
int a; int b 1. a = a + b; b = a - b; a = a - b; 2. a=a^b; b=a^b; a=a^b; 3. a=a*b; b=a/b; a=a/b;
6、不用除法实现A/3
答案:
unsigned divby3( unsigned x ) { return ((unsigned long long)x * 0xaaaaaaab) >> 33; }
7、请写出三个最影响CPU效率的指令()、()、()。
答案:暂无。
8、为什么经常把类的析构函数写为虚函数?
答案:当你可能通过基类指针删除派生类对象时。
虚函数绑定到对象的类的代码,而不是指针/引用的类。如果基类有虚析构函数,delete basePtr时(译注:即基类指针),*basePtr 的对象类型的析构函数被调用,而不是该指针的类型的析构函数。这通常是一件好事情。
TECHNO-GEEK WARNING; PUT YOUR PROPELLER HAT ON.
从技术上来说,如果你打算允许其他人通过基类指针调用对象的析构函数(通过delete这样做是正常的),并且被析构的对象是有重要的析构函数的派生类的对象,就需要让基类的析构函数成为虚拟的。如果一个类有显式的析构函数,或者有成员对象,该成员对象或基类有重要的析构函数,那么这个类就有重要的析构函数。(注意这是一个递归的定义(例如,某个具有重要析构函数的类,它有一个成员对象(它有基类(该基类有成员对象(它有基类(该基类有显式的析构函数))))))
END TECHNO-GEEK WARNING; REMOVE YOUR PROPELLER HAT
如果你对以上的规则理解有困难,试试这个简单的:类应该有虚析构函数,除非这个类没有虚函数。原理:如果有虚函数,说明你想通过基类指针来使用派生对象,并且你所可能做的事情之中,可能包含了调用析构函数(通常通过delete隐含完成)。一旦你在类中加上了一个虚函数,你就已经需要为每一个对象支付空间代价(每个对象一个指针;注意这是理论上的编译器特性;实际上每个编译器都是这样做的),所以这时使析构函数成为虚拟的通常不会额外付出什么。
9、何时用dynamic_cast?
dynamic_cast可以转换指针和和引用(基类到派生类),不能用来转换对象。
10、inline函数可以定义在cpp中么?为什么?
inline可以放在.cpp中,但此时只有本cpp文件可以用它。如果要做成公用的,就必须放在.h中,如果不想放在.h中,就必须每个cpp文件拷贝一份。其实即使放在.h中,也是每个cpp文件拷贝一份,只不过是编译器替你完成这种拷贝罢了。inline函数重复出现不会导致连接错误,即可以重复定义。
11、分别用STL中的vector和list存储1000万个如下数据,分别会占用多少内存?请说明理由。
struct test { int a; short b; char c; };
答案:暂无。
12、多线程用锁的时候需要考虑什么?
答案:暂无。
13、请实现unsigned的任意大的整数类,并实现这个类型的两个任意大的整数乘法。
答案:暂无。