经典问题解析(1)---const和引用、指针与引用、函数重载、C方式编译
2017-02-21 21:41
330 查看
const和引用
#include <stdio.h> int main() { const int x = 1;//定义的一个const常量 const int& rx = x;//当const常量取地址时,编译器会为其分配一个空间 //在下面的程序中,x仍为符号表中的常量,rx则为新分配空间中的数值 int& nrx = const_cast<int&>(rx);//类型转换将const属性去掉,变为普通引用 nrx = 5; printf("x = %d\n", x);//打印 1 printf("rx = %d\n", rx);//打印 5 printf("nrx = %d\n", nrx);//打印 5 printf("x = %p\n", &x);//打印的是分配空间的地址 printf("rx = %p\n", &rx);//三个地址相同 printf("nrx = %p\n", &nrx); volatile const int y = 2; //由于volatile,y不是一个真正的常量,只是只读变量 int* p = NULL; p = const_cast<int*>(&y);//y的地址给p *p = 6; printf("y = %d\n", y);//两个的输出结果都为6 printf("*p = %d\n", *p); const int z = y;//使用其它变量初始化的const常量仍然是只读变量 p = const_cast<int*>(&z); *p = 7; printf("z = %d\n", z);//两个的输出结果都为7 printf("*p = %d\n", *p); char c = 'c'; char& rc = c; const int& trc = c; //const引用的类型与初始化变量的类型不同, //生成一个新的只读变量,其初始值与初始化变量相同 rc = 'a'; printf("c = %c\n", c);//输出结果为a,a,c printf("rc = %c\n", rc); printf("trc = %c\n", trc); return 0; }
符号表:
符号表是编译器在编译过程中产生的关于源程序中语法符号的数据结构,如常量表、变量名表、数组名表、函数名表等等。
符号表是编译器自用的内部数据结构,符号表不会进入最终产生的可执行程序中。
指针与引用
#include <stdio.h> struct SV { int x; int y; int z; }; struct SR { int& x; int& y; int& z; }; int main() { SV sv = {1, 2, 3}; SR sr = {sv.x, sv.y, sv.z}; printf("&sv = %p\n", &sv);// &sv = &sv.x printf("&sv.x = %p\n", &sv.x);//依次增加4 printf("&sv.y = %p\n", &sv.y); printf("&sv.z = %p\n", &sv.z); printf("&sr = %p\n", &sr);//打印出的是另外的地址 printf("&sr.x = %p\n", &sr.x);//&sr.x = &sv.x printf("&sr.y = %p\n", &sr.y);//&sr.y = &sv.y printf("&sr.z = %p\n", &sr.z);//&sr.z = &sv.z //操作引用就等于操作变量 SV& rsv = sv; rsv.x = 4; rsv.y = 5; rsv.z = 6; printf("sv.x = %d\n", sv.x);//打印结果为4,5,6 printf("sv.y = %d\n", sv.y); printf("sv.z = %d\n", sv.z); //操作引用就等于操作变量 return 0; }
指针与引用的区别:
指针是一个变量,其值为一个内存地址,通过指针可以访问对应内存地址中的值。
引用不是变量只是一个变量的新名字,所有对引用的操作(赋值,取地址等)都会传递到其引用的变量上。
指针可以被const修饰成为常量或者只读变量。
const引用使其引用的变量具有只读属性。
指针就是变量,不需要初始化,也可以指向不同的地址。
引用天生就必须在定义时初始化,之后无法在引用其它变量。
从使用C++语言的角度来看:
引用与指针常量没有任何的关系。
引用是变量的新名字,操作引用就是操作对应的变量。
从C++编译器的角度来看:
为了支持新概念“引用”必须要一个有效的解决方案,在编译器内部,使用指针常量来实现“引用”。
因此“引用”在定义时必须初始化。
重载的相关问题
#include <stdio.h> void func(int a, int b)//重载1号函数 { printf("void func(int a, int b)1\n"); } void func(int a, char b)//重载2号函数 { printf("void func(int a, char b)2\n"); } void func(char a, int b)//重载3号函数 { printf("void func(char a, int b)3\n"); } void func(char a, char b)//重载4号函数 { printf("void func(char a, char b)4\n"); } int main() { int a = 1; char b = '2'; func(a, a);//调用重载1号函数 func(a, b);//调用重载2号函数 func(b, a);//调用重载3号函数 func(b, b);//调用重载4号函数 //当采用字面量如1,2来调用重载函数时,要看编译器的字面量的默认类型是什么,可能不能调用 func(1, 2); //调用重载1号函数 func(1, '2'); //调用重载2号函数 func('1', 2); //调用重载3号函数 func('1', '2'); //调用重载4号函数 return 0; }
C++编译器对字面量的处理方式:
整数型字面量的默认类型为int,占用4个字节
浮点型字面量的默认类型为double,占用8个字节
字符型字面量的默认类型为char,占用1个字节
字符串型字面量的默认类型为const char*,占用4个字节
当使用字面量对变量进行初始化或赋值时:
无溢出产生:编译器对字面量进行默认类型转换。
产生溢出:编译器会做截断操作,并产生警告。
深入理解重载三规则:
精确匹配实参
通过默认类型转换匹配实参
通过默认参数匹配实参
函数重载的判断标准有:
函数名称、参数类型、参数个数、const
如果同时在类中,对于函数名相同的const函数和非const函数能够构成重载。
如果定义的对象是常对象,则调用的是const成员函数;如果定义的对象是非常对象,则调用重载的非const成员函数。
三条规则会同时对已存在的重载函数进行挑选
当实参为变量并能够精确匹配形参时,不再进行默认类型转换的尝试。
当实参为字面量时,编译器会同时进行精确匹配和默认类型转换的尝试。
不同的编译器可能有不同的处理结果。
C方式编译
#include <stdio.h> extern "C" { void func(int x) { const int i = 1; int& ri = const_cast<int&>(i); ri = 5; printf("i = %d\n", i);//输出1 printf("ri = %d\n", ri);//输出5 } } void func(const char* s) { printf("%s\n", s); } int func(int a, int b) { return a + b; } int main() { func(1); func("Delphi Tang"); func(1, 2); return 0; }
上面程序输出的结果为 i = 1, ri = 5, Delphi Tang,
说明extern “C”中的代码仍然按照C++的方式进行编译的。
C方式的编译主要指按照C语言的规则对函数名进行编译。而函数中的函数体的代码仍然会按照C++的方式进行编译。
相关文章推荐
- 函数返回const引用形参的指针问题
- C++笔记(一)const与define,指针,引用,函数,类成员
- 函数参数的单指针参数和双指针参数的问题和解析
- 实例解析使用指针作为函数参数传递需要注意的问题
- C/C++中函数的传值调用、指针调用、引用调用问题
- 关于“无法解析的外部符号”和“该符号在函数_wmain 中被引用”的问题
- C++,常量,const,constant,引用,指针,形参,实参,函数,返回值
- Const 重载解析(const参数重载 和 const成员函数重载)
- 函数参数用指针或引用传递时发现的一个小问题
- C++基础学习笔记----第六课(const和引用的扩展、重载函数和C方式编译的深入)
- C++中形参与const形参的函数重载问题。
- C++函数参数和返回值三种传递方式:值传递、指针传递和引用传递(着重理解)
- C++关于参数为const引用类型的函数调用参数成员函数的一个问题
- 解决android使用gson解析json字符串,并使用混淆编译方式打包apk遇到的问题
- const成员函数和非const成员函数返回引用的问题
- 问题:向函数中传递指针和传递指针的引用的区别
- SDL项目常见问题( error LNK2019: 无法解析的外部符号 _main ,该符号在函数 _mainCRTStartup 中被引用)
- 用委托改写一个经典函数指针问题
- 函数的传参方式有值传递和地址传递,地址传递又分为指针传递和引用传递。
- 关于“无法解析的外部符号”和“该符号在函数_wmain 中被引用”的问题