预处理、const、static和sizeof
使用#define宏定义时需要注意的地方
1 |
|
如果是上面这个方式,由于宏定义展开是在预处理时期,也就是编译之前,此时b并没有被赋值,这是b只是一个符号,则a=(b+2*b+2),所以应该将define的内容改为
1 |
宏参数的连接
使用#把宏参数变为一个字符串,用##把两个宏参数贴合在一起。
const的作用
1、用于定义常量,编译器可以对其进行数据静态类型安全检查
2、修饰函数形式参数,将“值传递”改为“const &传递”可以提高效率
3、修饰函数的返回值,返回值不能被直接修改
4、修饰类的成员函数,任何不会修改数据成员的函数都应该用const来修饰
常量和指针常量
1 | int j=0; |
const与define区别
define只是用来做文本替换的。
在编译的时候,就将define的所有内容进行替换了,它的生命周期止于编译期,它存在于程序的代码段,在实际程序中,它只是一个命令中的参数或者是常数, 并没有实际的存在。
const存在于程序的数据段,并且在堆栈分配了空间,他在程序中可以被调用、传递,const常量有数据类型,而宏常量没有数据类型,编译器可以对const常量进行检查。
程序的内存分配
1 | int a = 0; //全局初始化区 |
栈区(stack)— 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。 (编译器自动分配释放,连续,高地址向低地址,空间限制,分配速度快,函数调用中先入下一条语句位置,从右到左的参数,局部变量)
堆区(heap) — 一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。 (不连续空间,速度慢,有碎片,向高地址扩展,比较灵活,大)
全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量、未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放
文字常量区—常量字符串就是放在这里的。程序结束后由系统释放
程序代码区—存放函数体的二进制代码。
1 | 程序段(Text):程序代码在内存中的映射,存放函数体的二进制代码。 |
static有什么作用
1、在函数体,一个被声明为静态的变量在这一函数被调用的过程中维持其值不变。
2、在模块内(但在函数体外),一个被声明为静态的变量可以被模块内所有函数访问,但不能被模块外其他函数访问。他是一个本地的全局变量。
3、在模块内,一个被声明为静态的函数只可被这一模块内的其他函数调用。那就是这个函数被限制在声明他的模块的本地范围内使用。
static全局变量和普通全局变量的区别
1、static全局变量与普通全局变量的区别,static全局变量只初始化一次,防止在其他文件单元被引用。
2、static局部变量和普通局部变量的区别,static局部变量只被初始化一次,下一次依据上一次结果值。
3、static函数与普通函数的区别是,static函数在内存中只有一份,普通函数在每个被调用中维持一份复制品。
sizeof计算函数类的空间大小
普通函数不占内存,只要有虚函数,就会占用一个指针大小的内存,系统多用了一个指针维护这个类的虚函数表,无论这个类里面有多少个虚函数,都不会再影响类的大小。
空类占一个字节,编译器会插一个char给空类,用来标记它的每一个对象
sizeof和strlen的区别
1、sizeof是操作符,strlen是函数。
2、sizeof操作符的结果类型是size_t,sizeof可以用类型做参数,strlen只能用char*做参数,且必须是以“\0”结尾。
#pragma pack的作用
可以设置对齐为其他数字,会导致sizeof结果变化。
inline函数的好处
1、inline定义的函数,函数的代码被放入符号表中,在使用的时候进行替换,没有了调用的开销,效率也很高。
2、类的内联函数是一个真正的函数,在调用的过程中,编译器会检查他的参数类型,保证调用正确。
3、inline可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。
inline函数的缺点
inline是以代码膨胀作为代价的。
1、如果函数体内的代码比较长,会导致内存消耗代价比较高。
2、如果函数体内出现循环,那么执行函数体内的代码的时间要比函数调用的开销大。
inline函数和宏的区别
1、inline函数在编译的时候展开,宏在预编译的时候展开。
2、在编译的时候,inline可以直接被镶嵌到目标代码里面,而宏只是一个简单的文本替换。
3、内联函数可以完成比如类型检测、语句是否正确等编译功能,宏就不具有这样的功能。
4、宏不是函数,inline函数是函数
5、宏在使用的时候要注意二义性,而inline则不会出现二义性。