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) 函数的参数是结构或者类,因为此时一般会占用较多的内存空间,如果按值传递将需要分配较多的栈空间来存放形参的值,需要进行大量的数据复制操作,会消耗较多的空间和时间。(其实这两个场合使用指针都可以达到相同的效果)
C++基础回顾2(函数, 指针和引用)的更多相关文章
- C/C++基础知识:函数指针和指针函数的基本概念
[函数指针] 在程序运行中,函数代码是程序的算法指令部分,它们和数组一样也占用存储空间,都有相应的地址.可以使用指针变量指向数组的首地址,也可以使用指针变量指向函数代码的首地址,指向函数代码首地址的指 ...
- JS基础回顾_函数
函数 不要使用C风格的大括号 // log function return1() { return { name: 'oceans', } } function return2() { return ...
- 从cocos2dx中寻找函数指针传递的方法
目的 看到群里有个朋友搞了好几天函数指针传递,没搞好.所以写一篇文章,旨在从cocos2dx中帮朋友们找到如何传递指针. 旧版本的函数指针传递 全局函数函数指针调用 一般在C++11之前,我们一般是这 ...
- C++第四篇--重载_指针_引用
C++第四篇--重载_指针_引用 1. 基础知识 重载:函数名相同,根据参数不同(类型.数量.顺序不同)调用同名函数 指针和引用:引用就是别名,引用时必须初始化,引用你定义的变量. int a; in ...
- 1、C语言中的函数指针
一 通常的函数调用 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int argc, char* argv[]) { MyFun ...
- 对指针和引用的理解(c++)
1.指针 typedef说明一种新类型名,来代替已有类型名. a.案例:typedef char* String_t和#define String_d char *这两句在使用上的区别? 1)前者声明 ...
- 关于C++成员函数指针的使用
在做项目的时候,遇到了在类中根据不同的调用函数,在被调用函数的某处需要做不同的处理,本来就想着直接在类中设个标记变量判断下就好了,不过觉得这样代码可能看起来会有些凌乱,而且效率估计有些低,于是想起来使 ...
- C 函数指针详解
一 通常的函数调用 一个通常的函数调用的例子://自行包含头文件 void MyFun(int x); //此处的申明也可写成:void MyFun( int ); int main(int a ...
- C++基础——函数指针 函数指针数组
==================================声明================================== 本文版权归作者所有. 本文原创,转载必须在正文中显要地注明 ...
随机推荐
- 上传jar包到Apache Archiva本地仓库
1.登录archiva,点击左侧的upload Artifact 2 jar 包名称 为:java-client-4.1.2.jar 网上的pom配置为: <!-- https://mvnrep ...
- SYNATXAHIGHLIGHTER IN WLW HAS PROBLEMS
System.Reflection.TargetInvocationException: 调用的目标发生了异常. ---> System.ArgumentException: 字体“Consol ...
- javascript中this、apply、call、bind的用法和区别
参考阮一峰文章链接:http://javascript.ruanyifeng.com/oop/basic.html#toc10
- (转)iOS keychain API及其封装
一. Keychain API KeyChain中item的结构为: 1.增加keychain Item OSStatus SecItemAdd (CFDictionaryRef attributes ...
- 魅蓝Note2跑分 MT6753性能究竟如何
MT6753实力究竟如何? 采用LP工艺的MT6753实际上在性能和功耗方面并不比MT6752高,相反,同频下功耗要高1/3左右.并且其内存带宽是5.3G/s,小于MT 6752的6.4G/s 而且没 ...
- poj 2454 Jersey Politics dfs
这个题目第一步还是比较明显的,先把最小的n个值去掉,剩下的问题就是能不能把数据分成两半,使得每一半和都大于n*500,这个刚开始考虑了下dp的做法,但是复杂度不满足要求. 那么能想到的就是搜索了,实际 ...
- 定时改变App主题的方案
1.将接口返回的图片缓存到本地,由于写data到本地是耗时操作,为了不阻塞主线程,可开启子线程来做此操作 dispatch_queue_t queue = dispatch_queue_create( ...
- CentOS yum Fatal Error 处理一例
环境说明 [root@thatsit ~]# cat /etc/redhat-release CentOS Linux release (Core) [root@thatsit ~]# uname - ...
- Android -------- 用XmlPullParser解析器解析XML文件
- uva 10038 - Jolly Jumpers
#include <iostream> #include <cstdio> #include <stdlib.h> using namespace std; ], ...