四、const
- c语言中const的用法:
1)、const就是定义一个常变量 const int a = 10;
2)、数据类型对于const是透明的(const int 等同于int const);
3)、const直接修的内容不能做左值;(左值:放在=符号左边,用写权限;右值:只可读不可写)
4)、const在权限传递时,只能同等或者缩小传递,不能放大传递;
因为在之前文章中有具体介绍c语言中const的具体用法,所以在此就不过多赘述。
- c++中const的基本特性及用法:
基本特性:
1)、const定义的是常量,值不允许改变。
例:
const int a = 10;
int arr[a];//ok,因为a是不可改变的常量。
2)、(const定义的)常量必须初始化。
因为c++中规定,在编译期的时候,将使用该常量的地方替换成常量的值。
所以常量在初始化时不给其赋值,则此常量就是无用常量。
例:
const int a = 10;
//const int a;//如果这样不初始化a,下边打印就会出现错误
int *p = (int *)&a;
*p = 20;
cout << *p << " " << a << endl;//输出:20 10
//在编译期生成指令的时候,本作用域内的a就会被10替换。
3)、const修饰的数据产生的符号是local的(此数据仅限于本文件使用)
因为在编译期的时候,会进行常量值的替换,此过程只在本文件中进行,所以外文件无法解析本文件const定义的常量。
4)、const定义的常量可退化成常变量(编译期无法确定其值的时候)
例:
情况1、int c = 10; const int a = c;
情况2、void fun(const int a)//作为形参的时候。
int c = 20;
const int d = c;//退化成常变量,因为c是变量,所以d的值是无法确定的。
int *p2 = (int *)&d;
*p2 = 30;
cout << *p2 << " " << d <<" "<<c <<endl;//输出:30 30 20
//d已退化成常变量,所以指针就会改变d的值。
基本用法:
1)、const修饰的类型是离他最近的完整类型
2)、const 修饰的内容是属于他修饰类型的内容
3)、const修饰的内容不允许改变
4)、不允许泄露常量的地址给非常量的指针
例:
int main()
{
int b = 10;
int *p1 = &b;
const int *p2 = &b;
int *const p3 = &b;
int *q1 = &b;
const int *q2 = &b;
int *const q3 = &b;
q1 = p1;//ok, int* -> int*
//q1 = p2;//error, const int* -> int*,泄漏了常量的地址给非常量
q1 = p3;//ok, int* -> int*
q2 = p1;//ok, int* -> const int*
q2 = p2;//ok, const int* -> const int*
q2 = p3;//ok, int* -> const int*
//q3 = p1;//error, p3被const直接修饰,则它的值不允许被修改
//q3 = p2;//error
//q3 = p3;//error
}
五、c++中的引用
1、基本特性:
1)、引用相当于变量的别名,对引用的操作与对变量直接操作完全一样。
例:
//交换函数
void swap(int *const a, int *const b)// 指针
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void swap(int &a, int &b) // 引用
{
int tmp = a;
a = b;
b = tmp;
}
2)、引用必须初始化。
例:
int main()
{
int a = 10;
int a1 = 30;
int *p = &a;
int &b = a;
//int &c; // error, 引用必须初始化
}
3)、底层是一个指针 ,在使用地方替换成了指针的解引用。
例:
// 接 2) 代码
b = 20;
//引用的底层实现
/*
002E554B mov eax,dword ptr [b]
002E554E mov dword ptr [eax],14h
*/
*p = 20;
//指针的底层实现
/*
002E5554 mov eax,dword ptr [p]
002E5557 mov dword ptr [eax],14h
*/
4)、不允许泄露常量的引用给非常量引用
例:
const int a = 10;
const int &p1 = a;
int &p = p1; // error , 将常量的引用泄露给了非常量引用
2、基本用法:
1)、引用产生的临时量问题:
1、标准类型产生的临时量是常量:
例:
const int &c = fun(); // fun()是外文件函数
引用一个不可寻址的常量,此时就会产生一个临时量 , 这个临时量是个常量。
2、自定义类型产生的临时量是非常量:
例:
const int &d = 10;//产生一个临时量供引用
A &e = funa(); // A是自定义类型,funa()自定义类型函数。
引用一个临时量 临时量是非常量
2)、引用( & )和 const 对参数类型(函数重载)的影响
1、引用单独使用不参与类型
例:
bool compare(int &a, int &b);
2、const 单独使用不参与类型
例:
bool compare(const int a, const int b);
bool compare(int a, int b);
这两个函数的参数类型都是(int,int),所以不能构成重载
3、& 与 const 结合参与类型 ,可以形成重载
例:
bool compare(const int &a, const int &b)
4、const 修饰指针,如果修饰的内容里面没有*,则const不参与类型
例:
void compare(int *const p1, int *const p2);
3)、如何用c语言的编译规则编译c++程序?
先写一个c语言函数接收c++程序,然后转换成c语言编译规则。
extern "C"
{
void fun_creat() // c语言函数,生成符号: fun_creat_c
{
fun_plus_plus();// c++函数,生成符号:fun_plus_plus_cpp
}
};