03. bool,const,引用,默认参数

一.bool

bool val = true;//vs中占1字节,内存中数值为0x01
val = false;//内存中数值为0x00
val = 100;//内存中数值为0x01,warning C4305: “=”: 从“int”到“bool”截断
val = -1;//内存中数值为0x01,warning C4305: “=”: 从“int”到“bool”截断

  

结论:非0即true,0为false

 

二.const

1.宏在预处理阶段发生文本替换,所以调试时看不到符号信息。

const int val = 10;
*(int *)&val = 0;//通过地址强行改,观察内存发现确实改变了,为0x00000000
int num = val;//但是num依旧是10
cout << num << " " << val;//打印2个10

  

结论:引用const的变量在编译时,就将const变量直接用数值代替,而不是在运行时访问const变量的内存获取数值。

 

2.const和指针结合

2.1 const*左侧,代表指针指向的对象是const类型

int n = 10;
const int *p = &n;
int const *q = &n;//和上一句等价
//*p = 123;//指针指向的内容不能修改
p = nullptr;//指针本身可以修改

  

2.2 const*右侧,代表指针自身是const类型

int n = 10;
int *const p = &n;
*p = 123;//指针指向的内容可以修改
//p = nullptr;//指针本身不能修改

  

2.3 const*左右两侧,代表指针指向的对象是const类型,指针自身也是const类型

int n = 10;
const int *const p = &n;
//*p = 123;//指针指向的内容不能修改
//p = nullptr;//指针本身不能修改
const int *p2 = p;//把常量p的值拷贝给p2。p和p2都满足“指向的内容不能改”的限制

  

 

三.引用

1.指针的缺点:空指针,野指针

2.引用的用法

void foo1() {
	int n = 10;
	int &rn = n;//给n取了个别名rn
	rn = 999;//n的值被改为999
	cout << n;


	char ch = 'a';
	char *p = &ch;
	char *&ref = p;//给指针变量p取了个别名
	char ch2 = 'b';
	ref = &ch2;//改变p,现在p保存ch2的地址
}

void foo2() {
	int n = 1;
	int m = 2;
	int &r = n;//引用必须初始化
	r = m;//r是n的别名,把m赋值给n
	cout << n << endl;//输出2

	int *p = &n;
	int *&rp1 = p;//p是变量,引用绑定到指针变量
	int *const &rp2 = &n;//n的地址编译时确定,无法运行时修改,引用绑定到地址常量

	++ *rp1;//n变成3
	++ *rp2;//n变成4
	cout << n << endl;//输出4

	int &r2 = *rp2;//引用绑定到指针指向的内容
	r2 = 5;
	cout << n << endl;//输出5
}

  

  

3.引用的限制:

3.1 引用必须初始化

3.2 引用绑定一个变量后,不能再绑定另一个变量

3.3 不要返回局部变量的指针或引用

//int &r;//引用必须初始化

float f = 1.0;
//int &rf = f;//error C2440: “初始化”: 无法从“float”转换为“int &”

  

4.引用作为函数参数:

用引用的方式交换两个变量,单步到第8行时,内存窗口中第一个方框内是变量a的地址,第二个方框内是变量b的地址。可见引用隐式传递了变量地址。

 

 

 

四.默认参数

1.基本用法

int foo(int n = 123, int m = 456) {
    return n + m;
}
int res = foo(1, 2);//提供了参数,用提供的
res = foo();//不提供参数,用默认的

  

2.规则:一旦某个形参被赋予了默认值,它后面的所有形参都必须有默认值,例如有如下错误

int foo(int n = 123, int m) {//没给m提供默认值,编译报错
    return n + m;
}

  

3.分离式编译时,默认参数的声明放在头文件中,实现放在cpp文件中,且实现中不加默认参数。例如:

foo.h文件中放声明:

int foo(int n = 123, int m = 456);

  

foo.cpp文件中放实现:

#include "foo.h"
int foo(int n, int m) {
    return n + m;
}

  

main.cpp文件中调用:

int res = foo(1, 2);//提供了参数,用提供的
res = foo();//不提供参数,用默认的

  

如果在foo.h和foo.cpp中都有默认参数,编译器报错:

error C2572: “foo”: 重定义默认参数 : 参数 1

error C2572: “foo”: 重定义默认参数 : 参数 2

 

如果在foo.h中没有默认参数,而foo.cpp中有,编译发现对foo()的调用时,找不到接收0个参数的foo的函数声明,编译器报错:

error C2660: “foo”: 函数不接受 0 个参数

 

posted @ 2020-05-07 09:41  八转达人  阅读(551)  评论(0)    收藏  举报