C++ main函数的返回值
main函数通过返回值把整个程序的执行情况告诉调用者(通常是操作系统,但是操作系统通常会忽视main函数的返回值),一般情况下return 0表示正常结束,return -1表示非正常结束。
main函数也可以不写return语句,这时当执行完最后一条语句后自动执行一条“return 0;”语句。
其他函数的返回值原理同此。
C++ 标识符的作用域
包括:局部作用域、全局作用域、文件作用域、函数作用域、函数原型作用域、名空间作用域、类作用域
注意:潜在作用域,也就是同名变量的作用域问题。
1. 局部作用域
指在函数定义或者复合语句中,从标识符的定义点开始到函数或者复合语句结束之间的程序段。
在同一个局部作用域内不能出现相同名字的两个局部变量(包括形参)。
一个函数内的复合语句又是一个局部作用域,也就是在函数内有某个变量时,复合语句中可以有另外一个同名字的变量。
2. 全局作用域
指对构成C++程序的所有源文件。
在C++标准中,把全局作用域归于连接控制范畴。
C++ 宏与内联函数
通常把全局标识符的生命放在某个头文件中。
3. 文件作用域
指单独的一个源文件。
在全局标识符的定义中加上static修饰符,该全局标识符就变成了具有文件作用域的标识符。
4. 函数作用域
指由整个函数定义所构成的程序段。
语句标号(如goto语句中使用的语句标识)是唯一的具有函数作用域的标识符。
5. 函数原型作用域
指用于函数声明的函数原型,其中的形参的作用域从函数原型开始到函数原型结束。
如:void f(int x, double y); //其中的x和y的作用域从“(”开始到")"结束。
6. 名空间作用域
无名的名空间定义不能在其他地方调用
7. 类空间作用域
C++ 变量的生存期
变量的生存期是指其在程序运行时占用内存空间的时间段。
1. 静态生存期
从程序开始执行时分配到程序结束时收回。
如:全局变量
2. 自动生存期
从程序执行到定义它们的复合语句时分配到复合语句执行完毕时收回。
如:局部变量、函数的参数
3. 动态生存期
用new操作或者malloc函数来进行分配,用delete操作或者调用free函数来收回。
附:
1. 在定义局部变量时,使用auto、static、register来显式指出它们的生存期。
auto: 默认,自动生存期
static: 静态生存期,在函数多次调用时,可以保留上次调用的结果。
register: 自动生存期,与auto不同在于,建议(不是一定)编译程序把该局部变量的空间分配在CPU寄存器中,其目的是为了提高对局部变量的访问效率。
2. 内存空间分为四个部分:静态数据区、代码区、栈区、堆区
静态数据区:全局变量、static存储类的局部变量、常量
代码区: 函数代码
栈区: auto存储类的局部变量、函数的形参、函数调用时的有关信息(如返回值)
堆区: 动态变量
静态数据区和代码区的大小是固定的,而栈区和堆区的大小随程序的运行不断变化(不过操作系统会对其空间最大值有一定的限制)。
3. 编译程序隐式自动将静态生存期的变量按位模式初始化为0,其他变量不对其进行初始化(使用空间中的已有值,因此是不固定的)
C++ 宏与内联函数
因为函数调用需要开销(如:保护调用者的运行环境、参数传递、执行调用指令等),所以函数调用会带来程序执行效率的下降,特别是对一些小函数的频繁调用将是程序的效率有很大的降低。
C++提出了两种解决方法:宏、内联函数。
1. 宏
宏是C++编译预处理系统处理的实体。
宏定义的4种格式:
1)#define <宏名> <文字串>
在编译前进行使用文字串进行宏替换
#define PI 3.14
2)#define <宏名>(<参数表>) <文字串>
在编译前进行使用文字串进行宏替换
#define max(a,b) a>b?a:b
3)#define <宏名>
只是告诉编译程序该宏名已经被定义,不做任何文字串替换,其用于条件编译
如:#define OUTPUTFILE
#ifdef OUTPUTFILE
//输出到文件的代码
#endif
4)#undef <宏名>
用于取消宏名的编译
不足:1)重复计算,如max((x+1),(y+2)),因为其只是进行单纯的文字替换
2)不进行参数类型检查和转换
3)不利于一些工具对程序的处理(如C++程序编译后,所有宏都不存在了)
2. 内联函数
在函数定义中的返回值类型之前加上一个关键字 inline
其作用是建议(具体有没有不一定,有些函数加上也不会作为内联函数对待,如递归函数)编译程序把该函数的函数体展开到调用点,这样就避免了函数调用的开销,从而提高了函数调用的效率。
inline int max(int a,int b)
{return a>b?a:b;}
注意:内联函数名具有文件作用域。