C++初步之基础准备
文章目录
一、const关键字修饰指针以及形参
1.1 修饰指针——常量指针
常量指针意思是:指针指向的对象是常量,也就是说,其指向的值不可改变,但是,指针的方向可以改变。
如:const int* p = &a;
这里的p指针是一个常量指针。
1.2 修饰常量——指针常量
指针常量意思是:指针的方向不能改变,也就是说,其指向的值可以改变,但是,指针的方向不可改变。
如:int * const p = &a;
这里的p指针是一个指针常量
1.3 常量指针和指针常量的区别方法
记忆方法:“定性"分析谁是常量
解释:这两个名词中有共同点就是,包含指针和所指对象两个元素,其中一个元素是常量,不可变动;另一个是变量,可变动。我们只需定性分析谁是常量,如果所指对象是常量的,那么指针方向就可变,这个就是常量指针;如果指针是常量,那么所指对象可变,就是指针常量。
”定性“方法:
常量指针 => 常量的指针
指针常量 => 指针是常量
简便记忆法:const后面如果是指针,那么指针就是常量,如int * const p = &a,p为指针,在const后,那么p就是常量指针。反之即为指针常量。
1.4 配合引用作函数形参
- 防止误操作改变变量的值
- 可传入无实体常数作参数
注:const在配合引用时,可以作为重载条件;在无引用状态下,不可重载。当然注意这里说的是作为函数参数,而非 常函数,事实上常函数在类内可以作为重载条件。
-
const配合引用作函数参数:可重载
void func(int& x) {}
void func(const int& x) {}
//这样写是正确的
-
const直接作为参数:不可重载
void func(int x) {};
void func(const int x);
这样写是错误的
另外,const修饰函数返回值也不可作为重载的条件,后面会专门来讲重载的条件。
二、引用的相关事项
-
引用:引用是 C++ 的新增内容(相比于C),在实际开发中会经常使用;C++ 用的引用就如同C语言的指针一样重要,但它比指针更加方便和易用,有时候甚至是不可或缺的。同指针一样,引用能够减少数据的拷贝,提高数据的传递效率。
-
引用样例:
int a = 10; int &b = a;//这里使用引用相当于给变量a取别名,b就是a
-
注意事项:
-
引用必须对其初始化
错误写法:
int &a;
正确写法:
int &a = b;
-
引用一旦初始化,就不能更改成其他变量的别名
错误写法:
int &a = b; &a = c;
因为a是b的别名,a不能再成为其他变量的别名了。
-
引用作为函数的返回值:
-
不要返回局部变量的引用,如:
int& func() { int a = 10; return a; }
-
函数的调用可以为左值
int& func() {} func() = 1000;//这是合法的
-
-
-
引用的本质:内部实现了指针常量。这也是为什么一旦引用初始化后就不能更改为另一个变量的引用,但是其值可以更改的原因。
三、内存分区模型
内存分为四个区,在程序运前分为代码区和全局区,运行时分为栈区和堆区
(一)、程序运行前
1. 代码区:
- 存放CPU执行的机器指令,包括所有代码和注释
- 代码区是共享的,对于频繁执行的exe程序,内存中只有一份拷贝
- 代码区是只读的,生成exe程序后,不能改变
2. 全局区:
-
存放全局变量和静态变量
-
包含常量区:字符串常量和其他常量
常量的组成:
- 字符串常量:如"hello world"
- const 修饰的全局常量
-
特点:由操作系统释放
(二)、程序运行中
3.栈区:
- 存放局部变量和形参,由编译器释放
- 注意,不要返回局部变量的地址!
4. 堆区:
堆区是由程序员分配释放,由操作系统回收,利用new关键字可将数据开辟到堆区。
四、函数的默认、占位参数
4.1 函数的默认参数
形如:int func(int a, int b = 10, int c= 20)
这样,形参中有赋值的,称为默认参数。规则:形参默认值,如果传入其他值就用其他值
对于上例:如果是
func(10, 10)
,那么函数中c就是默认值20,如果是func(10)
,那么b就是默认值10、c就是默认值20。如果是func(10,20,30)
,那么a、b、c分别为10、20、30。
注意事项:
-
如果有一个形参有默认参数,那么这个形参后面的所有参数必须有默认参数,即
int func(int a, int b = 10, int c)
是错误的,这个c也必须有默认参数。 -
如果函数声明中有默认参数,那么函数实现就不能有默认参数,声明和实现留一个即可,如果声明中有默认参数,则实现不能有;如果声明中没有,那么实现时就必须有。
int func(int a, int b = 10); int main() { func(10, 20); return 0; } int func(int a, int b) //注意! { ... }
当然,这样写没问题:
int func(int a, int b = 10) //注意! { ... } int main() { func(10, 20); return 0; }
4.2 函数的占位参数
目前没发现有什么用,不过听说可以用占位参数重载
int func(int a);
int func(int a, int);
调用:
func(10); 第一个
func(10, 10);第二个
五、函数重载的简介
5.1 函数重载的条件
- 在同一个作用域下
- 函数名称相同
- 参数类型或个数不同
注意:函数的返回值不可用作重载的条件,引用可以作为重载条件
,如果函数重载碰到默认参数,可能会出现二义性!如:
int func(int a, int b = 0);//b为默认参数
int func(int a);
上述两个函数满足重载条件,
-
可运行:func(a, b),因为两个参数的func函数只有第一个是,所以这样调用是可以,会走第一个函数。
-
不可运行:func(a),因为默认参数的存在,使得对于这个具有两个形参的函数(其中一个为默认参数)来说,调用时传一个参数也可以运行
对于:int func(int a, int b = 0);//b为默认参数
func(a);//这是可以的
但是对于重载版本:
int func(int a, int b = 0);//b为默认参数
int func(int a);
会产生二义性,这时候编译器不知道应该走哪一个函数,会报错。
5.2 函数重载的意义
可以让函数名相同,提高函数的复用性。
THEEND…