C++(基础)———— c和c++的区别(二)

四、const

  1. c语言中const的用法:
    1)、const就是定义一个常变量 const int a = 10;
    2)、数据类型对于const是透明的(const int 等同于int const);
    3)、const直接修的内容不能做左值;(左值:放在=符号左边,用写权限;右值:只可读不可写)
    4)、const在权限传递时,只能同等或者缩小传递,不能放大传递;

因为在之前文章中有具体介绍c语言中const的具体用法,所以在此就不过多赘述。

  1. 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
	}
};

猜你喜欢

转载自blog.csdn.net/djh971102/article/details/83722814
今日推荐