C++基础回顾2(函数, 指针和引用)
接着回顾函数、指针和应用。
函数
1、多维数组作为形参时,第一维的大小可以省略(也可以不省略),但是其他维的大小必须指定。比如二维数组形参,int array[3][]不正确,int arry[][10]正确。因为实参传来的是数组的起始地址,在内存中按行存放,但并不区分行和列,如果在形参中不指定列数,则系统无法确定应为多少行多少列。
2、在C++中,可以为参数指定默认值,在函数调用时,没有指定与形参相对应的实参就自动使用默认值。C++函数的默认参数可以是常数,也可以是全局变量或全局常量,甚至可以是一个函数调用。默认参数只能出现一次,如果在函数原型中给出,则在函数定义中不能再次给出。如果函数的定义在函数调用之前,程序中没有进行函数声明,则应在函数定义中给出默认值;否则,如果在函数原型中没有指定函数的默认值,而在定义中为参数给出了默认值,则调用时默认值不能使用。如果一个函数中有多个参数,则默认参数应从右至左逐个定义。
3、内联函数的定义必须出现在内联函数第一次被调用之前,这是因为编译程序在编译时,用内联函数的函数体替换函数调用语句。
4、一个函数不能既作为重载函数,又作为有默认参数的函数。如:int myMax(int x, inty); int myMax(int x, int y, int z = 100);,当调用函数时如果少些了一个参数,如调用“myMax(1,2)”,编译系统无法判定是利用重载函数还是利用默认参数的函数,出现二义性,系统无法执行。
5、运用全局运算符“::",可以在局部作用域中访问到全局变量。例如有全局变量x,并且又有一个局部变量x,在该局部变量的作用域中想要使用到全局变量x,那么就使用“::x”。
6、静态变量在程序编译时预分配,并在程序执行之前就被确定存储单元。定义静态的局部变量时,如果同时制定初值,该初值是在程序开始执行前就被设定的,以后每次调用函数时不再重新设定初值,而是保留上次函数调用结束时的值。
7、如果在定义静态变量时,未指定初值,则系统自动给静态变量赋一个二进制信息全为0的初值。(但为了程序便于移植、阅读和修改,在程序中应明确给出静态的局部变量的初值)
8、静态的全局变量对于同一源程序文件中的函数是可以访问的,但与一般的全局变量不同,它不能被任何其他源程序文件中的函数访问。(静态函数也具有同样的访问限制)
9、寄存器变量(register):只有int/char/指针型的局部变量和形参才可以是寄存器存储类的。将一个局部变量的存储类指定为寄存器的,是提醒编译程序,这个变量在程序中使用十分频繁,在为该变量分配内存时,有可能的话,尽可能为它分配寄存器,因为访问寄存器要比访问存储单元来得快。将一个形参的存储类指定为寄存器的,可能是因为要访问某些特殊的驱动程序,这些设备的驱动程序要求以寄存器为参数与系统传递信息。
10、可以用“# undef 标识符” 命令终止宏定义的作用域。
11、带参数的宏,宏展开是将程序中宏名后的圆括号内的实参从左到右原封不动替代宏题中的形参。
例:#define PI 3.1415
#define S(R) = PI * R * R
如果调用S(10.0 + 10.0),则无法得到我们期望的结果。实际结果为: 3.1415 * 10.0 + 10.0 * 10.0 + 10.0。如果使用内联函数,就可以解决这个问题。
指针和引用
1、用指针或者下标都能找到数组中的元素。用下标法比较直观,但是寻找数组元素费时较多。特别是在循环引用数组中的元素值时,用指针法则不必每次都重复计算地址。
2、指向常量的指针:一个指向常量的指针变量。例:const char *name = "fang"; 接着不能用以下类似语句name[3] = 'a'; 但是由于name是一个指向常量的普通指针变量,而不是常指针,因此可以改变name的指向,下面的语句是允许的name = "pei"。
3、常指针:将指针本身声明为常量,而不是将它指向的对象生命为常量。创建一个常指针就是创建一个不能移动的固定指针,但是它所指的数据可以改变。在定义指针常量时必须初始化。例:char * const name = "fang"; 允许name[3] = 'n',不允许name = "pei"。
4、指向常量的常指针:指针本身不能改变,指向的值也不能改变。例:const char * const name = "fang"。
5、引用:引用是对一个变量或者常量标识符起的别名。int val; int &rval =val; 则val和rval指的就是同一个变量,它们的使用方式也完全一样。
6、当编译程序看到"&"时,就不为其后面的标识符分配内存空间,而只是简单地将它所引用的那个标识符所具有的内存空间赋给它。
7、在声明一个引用类型变量时,必须同时对它进行初始化,即必须在声明引用时说明它所引用的对象。所引用的对象必须是已经有对应的内存空间的。(函数形参为引用类型,"没有初始化"是因为在调用函数时,实参赋给了形参)
8、不能声明void类型的引用(因为void本身就表示没有数据类型,对它的引用也就没有意义);不能对数组名引用(因为数组名表示的起始地址,它本身不是一个变量);不能定义指向引用类型的指针(因为引用本身只是一个符号,它没有任何内存空间)。
9、当用const来限定引用时,表示不能通过引用改变被引用的空间的值。另外,对一个常变量进行引用时,必须将这个引用定义为const的。
10、引用最大的用途是作为函数的参数或者返回值类型,从而扩充函数传递数据的功能。要注意的是:引用参数对应的实参必须具有对应的内存空间,即实参必须有一个合法的内存空间,以便能够对这个空间进行引用。引用作函数参数通常在下面两个场合:1)函数需要返回多个值的场合; 2) 函数的参数是结构或者类,因为此时一般会占用较多的内存空间,如果按值传递将需要分配较多的栈空间来存放形参的值,需要进行大量的数据复制操作,会消耗较多的空间和时间。(其实这两个场合使用指针都可以达到相同的效果)