C++的cosnt、static、宏定义、内联函数

const

C++中const的用法,C++是怎么处理的【在编译期间对于使用常量的地方用常量初始化的值直接替换】
①const是定义常量的,不能做左值被修改; 必须初始化;

②const常量的初始值如果是明确的值,那么常量在编译期间被常量初始值替换。

③const修饰常变量(C语言)时,不能做左值,其他与普通变量一样,比如不能定义数组大小;没有编译期替换规则。
④const修饰成员变量,成为类的常成员变量,所以其初始化写在初始化列表中。

⑤修饰成员函数,成为类的常成员函数。可以访问成员,但不可修改成员。普通对象和常对象都能调常方法,常对象只能调常方法。int const*const【常this指针】 <==>int *const【this指针】

static


C++中static的用法,C++是怎么处理的
①static修饰全局变量,使全局变量从global符号变为local符号,因此只能在当前文件可见,不参与链接。
②static修饰成员变量,必须在类外初始化。使其从栈内存或堆内存变成.data或 .bss(未初始化和初始化为0时),同类型对象共享静态成员变量。生命周期变长。
③static修饰成员函数,用类作用域调用,而不依赖对象(没有this指针)。。

宏定义:

c程序提供的预处理功能之一。包括带参数的宏定义和不带参数的宏定义。具体是指用一个指定的标志符来进行简单的字符串替换或者进行阐述替换。形式为:

#define标志符[(参数表)] 字符串

宏名

在上定义中的标志符被称为“宏名”。

宏展开

在c程序编译时将宏名替换成字符串的过程称为“宏展开”

define宏定义和const常变量区别:

1.define宏定义定义常量时,程序在预处理阶段将用define定义的内容进行了替换。因此程序运行时,常量表中并没有用define定义的常量,系统不为它分配内存。const定义的常量,在程序运行时在常量表中,系统为它分配内存。

2.define定义的常量,预处理时只是直接进行了替换。所以编译时不能进行数据类型检验。const定义的常量,在编译时进行严格的类型检验,可以避免出错。

3.define定义表达式时要注意“边缘效应”,例如如下定义
#define N 2+3 //我们预想的N值是5,我们这样使用N,int a = N/2; //我们预想的a的值是2,可实际上a的值是3。原因在于在预处理阶段,编译器将 a = N/2处理成了 a = 2+3/2;这就是宏定义的字符串替换的“边缘效应”因此要如下定义:#define N (2+3)。const定义的表达式则没有上述问题。const定义的常量叫做常变量原因有二:const定义常量像变量一样检查类型;const可以在任何地方定义常量,编译器对它的处理过程与变量相似,只是分配内存的地方不同。

在C++ 程序中只使用const 常量而不使用宏常量,即const 常量完全取代宏常量。

内联函数:

用关键字“inline”标明,类内定义的函数默认为inline.。在编译时是将函数直接嵌入调用程序的主体,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销,这样在运行时速度更快。而且内联函数是真正的函数,你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。

具体如何工作:如果定义为inline函数,编译器并不创建真实函数,内联函数不仅同普通函数一样经过检查后保存函数名称、参数类型和返回值类型,还会把内联函数的本体也一并存入符号表中,在之后的编译过程中一旦遇到该函数被调用时会首先检查调用是否合法,然后编译器会将inline函数的指令集合(函数代码)复制嵌入到主调函数中的调用位置,内联函数的代码就会直接替换函数调用,这样就不需要函数调用的跳转开销了。如果函数被调用了10次,就相当于内存中就包含10个相同指令集合的拷贝,没有一次调用。

        而当我们定义了一个函数之后,编译器会将其编译成一个指令集合。这个指令集合在程序运行的时候会出现在内存的代码区里,并且在调用此函数时程序执行的地址会跳转到这个指令集合的入口地址,当指令集合执行完后,再跳回到主调函数。换句话说,任何时候内存中只有一个指令集,如果该函数被调用10次,则运行时就会跳转到同一入口地址10次。

内联函数与宏的区别

使用宏和内联函数都可以节省在函数调用方面的时间和空间开销。二者都是为了提高效率,但是却有着显著的区别:
(1)、在使用时,宏只做简单的预处理器符号表(字符串)中的简单替换。而内联函数用编译器进行参数类型检查,且具有返回值(也能被强制转换为可转换的合适类型)。
(2)、内联函数首先是函数,函数的许多性质都适用于内联函数(如内联函数可以重载)。
(3)、内联函数可以作为某个类的成员函数,这样可以使用类的保护成员和私有成员。而当一个表达式涉及到类保护成员或私有成员时,宏就不能实现了(无法将this指针放在合适位置)。

猜你喜欢

转载自blog.csdn.net/qq_19525389/article/details/81537649