6.1 宏定义
面试题1,2:考点
1)#define的语法不能以分号结束
2)宏定义中变量要小心的用括号包起来
3)宏定义和inline都是代码嵌入方式,为达到性能要求,嵌入代码经常是必须的方法
6.2 const
面试题1:考点,const修饰指针的4种常见情况和const修饰成员变量
const修饰指针4种常见情况
1)const int* a = b
2)int const* a = b
1)2)const在*号的左面,表示const修饰的是变量,即*指向的变量是const类型的
int b = 500;
const int* a = &b;
*a = 600; //错误,a的指向内容为常量,不可更改
b = 600; //正确,b并未定义为常量
cout << *a << endl; // 输出为600
int c = 600;
a = &c; //正确,a本身并不是常量,是a指向变量是常量,因此a的指向可以更改
const int * a; // 正确,a本身并不是常量,可以先定义不进行初始化
3)int* const a = &b
3)指针本身就是常量,这种情况下不能对指针本身进行更改,指针指向内容可以更改
int b = 500, c = 600;
int* const a; // 错误,const变量要初始化
int* const a = &b;
*a = 600; // 正确,允许改值
cout << a++ << endl; // 错误,a本身不能改
4)const int* const a = &b
4)指针本身和所指内容均为常量,都无法更改
const成员函数
1)const定义在函数后
int getY() const;// 这个成员函数不能改变类中成员变量(mutable定义变量除外),且只能调用类中其余const成员函数
2)const定义在函数前
const int getY(); // 函数返回值是常量
面试题2:考点,const与#define相比有什么不同
在c++中,const可完全替代#define,相比之下,const优势体现在
1)const可以定义数据类型,编译器会对数据类型进行安全检查
2)有些集成化的调试工具可以对const常量进行调试
但是注意,在c中,const不能替代#define!原因不写了
面试题3:考点,const修饰成员函数能且只能更改类中有mutable修饰的成员变量
6.3 sizeof
面试题1:考点,
1)指针大小是一个定值,4个字节
2)string用隐藏字符‘\0’
3)结构体对齐(为提高性能)
面试题2:考点,类和结构体对齐问题
class B{
bool a;
bool b;
int c;
}
class C{
bool a;
int c;
bool b;
}
结构体会在编译期间进行字节对齐
B
|bool|bool|–|--|
|--------int------|
C
|bool|–|--|–|
|------int-----|
|bool|–|--|–|
因此sizeof(B)=8,sizeof(C)=12,注意定义时的变量排放顺序!
面试题3:考点,静态变量是放在全局数据区的,在sizeof计算的时候,是不算其大小的。
面试题4:考点,sizeof和strlen的区别
1)sizeof操作符的结果类型是size_t。
2)sizeof是运算符(针对变量进行操作可以不加括号),strlen是函数
3)sizeof可以用类型作为参数,strlen只能用char*做参数,且必须是以"\0"结尾的。
short f(); // sizeof(f()) = 2
char ss[100] = "0123456789"; // sizeof(ss) = 100, strlen(ss)=10
4)大部分编译程序在编译的时候就已经把sizeof算过了,strlen需要等到运行的时候才能计算出来
5)sizeof不能返回动态分配数组或外部传入数组的大小,同时,c++中数组作为变量在函数之间传递,传递的是首地址,因此在函数中无法获得数组大小,数组大小需要传递进去
6)计算结构体大小的时候需要考虑对齐问题
面试题5:考点,sizeof的使用场合(不是很明白)
1)与存储分配和IO系统那样的例程进行通信
2)看某种类型对象在内存中所占字节
3)动态分配对象时,让系统知道要分配多少内存
4)便于一些类型的扩充
5)由于操作数的字节数在是现实可能出现变化,建议在涉及操作数字节大小时,用sizeof代替常量
6)如果操作数是函数中数组形参或函数类型的形参,sizeof给出其指针的大小
面试题6,7,8,9,10:sizeof的一些计算,忽略
注意,空类所占空间为1,继承空类所占空间仍为1,但虚继承类的大小为4。
6.4 内联函数和宏定义
面试题:内联函数和宏定义的差别在哪里
内联函数与普通函数相比可以加快程序的运行速度,因为内联函数是在编译的时候直接嵌入到目标代码里的,而不是像普通函数那种进行中断调用的。宏只是一个简单的替换。
内联函数要做参数的类型检查,这个是内联函数和宏相比的一个主要的优势。
inline是通过增加空间消耗来提高效率的,这个方面其和宏是相同的。
inline一般用于以下情况
1)一个函数被不断的重复调用
2)函数只有简单的几行,且函数里没用for,while,switch语句
宏在c中很重要,在c++中用的少多了。关于宏的第一条规则就是不要轻易去使用他。
内联inline是用于实现的关键字而不是用于声明的关键字
inline void f();
void f(){}; // 内联不生效
inline void g() {}; // 内联生效
以下情况不适合使用内联:
1)函数体内代码较长
2)函数体内出现循环