浅谈C到C++的扩展
2017-09-16 11:18
127 查看
1、如果一个函数没有参数,C++会认为这是一个无参函数,不能给它传参;C语言中一个无参函数定义是用void进行填充
C++函数必须要有类型。
2、C++中三目运算符可以作为左值实用,三目运算符返回的是变量本身,但是返回的表达式中不能有常量。
3、C++中用const来定义常量,C++中常量会放在一个常量表中,当编译器检测到要const常量进行取地址操作时,会为其分配内存,但这个内存并不会被使用。C语言中的const变量是只读变量,有自己的存储空间。C++中的const常量类似于宏定义 const int c = 5; ≈ #define c 5;C++中的const常量与宏定义不同const常量是由编译器处理的,提供类型检查和作用域检查,宏定义由预处理器处理,单纯的文本替换。
4、引用在C++中的内部实现是一个常指针
Type& name <==> Type* const name
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏
函数返回值是引用,不能返回栈上的引用,可以反悔静态变量和全局变量的引用:
a.函数返回值是引用,如果用引用去接,接回来的是一个 引用;
b.函数返回值是引用,可以用普通变量去接,接回来的是一个值;
c.函数返回值是引用,可以作为左值来使用。
5、内联函数代替宏函数:在普通函数前加上关键字inline将函数变为内联函数(inline必须要和函数定义放在一起,若和函数声明放在一起会被忽略),如果内联成功,编译完后代码是没有这一段函数的。
注意点:内联函数函数体不能过长,最好不要超过5行;不能有循环语句,复杂的if语句;
不能对内联函数进行取地址操作。
6、函数的默认参数
C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的值,编译器会自动用默认值代替
注意点:只有参数列表后面的参数可以提供默认参数值,一但在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默认参数。
占位参数只有参数类型声明,而没有参数名声明,一般情况下,在函数体内部无法使用占位参数。
7、函数重载
用同一个函数名定义不同的函数,当函数名和不同的参数搭配是函数的含义不同。
函数重载至少满足下面的条件之一:
a.参数个数不同
b.参数类型不同
c.参数顺序不同
注意函数返回值不是函数重载的判断标准
这里需要注意了,函数重载遇上函数默认参数可能导致二义性的问题,这里归纳一下
将所有同名函数作为候选者尝试寻找可行的候选函数:
1 )精确匹配实参
2) 通过默认参数能够匹配实参
3) 通过默认类型转换匹配实参
匹配失败:
1) 最终寻找到的可行候选函数不唯一,则出现二义性,编译失败。
2) 无法匹配所有候选者,函数未定义,编译失败。
void func(void) //等价于func() { }
C++函数必须要有类型。
2、C++中三目运算符可以作为左值实用,三目运算符返回的是变量本身,但是返回的表达式中不能有常量。
int a = 10; int b = 20; (a > b ? a : b) = 100; // *(a > b ? &a : &b) = 100; printf("a = %d, b = %d\n", a, b); //输出结果是a = 10,b = 100 //(a > b ? a : 10) = 100 <==> *(a > b ? &a : &10) = 100;显然是不对的
3、C++中用const来定义常量,C++中常量会放在一个常量表中,当编译器检测到要const常量进行取地址操作时,会为其分配内存,但这个内存并不会被使用。C语言中的const变量是只读变量,有自己的存储空间。C++中的const常量类似于宏定义 const int c = 5; ≈ #define c 5;C++中的const常量与宏定义不同const常量是由编译器处理的,提供类型检查和作用域检查,宏定义由预处理器处理,单纯的文本替换。
4、引用在C++中的内部实现是一个常指针
Type& name <==> Type* const name
C++编译器在编译过程中使用常指针作为引用的内部实现,因此引用所占用的空间大小与指针相同。
从使用的角度,引用会让人误会其只是一个别名,没有自己的存储空间。这是C++为了实用性而做出的细节隐藏
#include <stdio.h> int main() { int a = 10; int &b = a; // int * const b = &a; // *b = 20; b = 20; // printf ("%p, %p\n", &a, &(*b)); printf ("%p, %p\n", &a, &b); //输出结果是一样的 return 0; }
函数返回值是引用,不能返回栈上的引用,可以反悔静态变量和全局变量的引用:
a.函数返回值是引用,如果用引用去接,接回来的是一个 引用;
b.函数返回值是引用,可以用普通变量去接,接回来的是一个值;
c.函数返回值是引用,可以作为左值来使用。
5、内联函数代替宏函数:在普通函数前加上关键字inline将函数变为内联函数(inline必须要和函数定义放在一起,若和函数声明放在一起会被忽略),如果内联成功,编译完后代码是没有这一段函数的。
注意点:内联函数函数体不能过长,最好不要超过5行;不能有循环语句,复杂的if语句;
不能对内联函数进行取地址操作。
//宏函数定义的缺点: #define MAX(a, b) f((a) > (b) ? (a) : (b)) void f (int max) { printf ("max = %d\n", max); } int main() { int a = 10; int b = 20; MAX(a, b++); printf ("b = %d\n", b); return 0; } //输出结果是22,用define只是在预编译的时候替换处理,即把MAX(a, b++)替换成 f((a) > (b++) ? (a) : (b++))
//inline的优点 inline int max(int a, int b) { return (a>b ? a : b); } int main() { int a = 10; int b = 20; f(10); f (max(a, b++)); printf ("b = %d\n", b); //输出结果是21. return 0; }
6、函数的默认参数
C++中可以在函数声明时为参数提供一个默认值,当函数调用时没有指定这个参数的值,编译器会自动用默认值代替
#include <stdio.h> // 声明时指定默认参数值 int mul(int a = 10); int main() { printf ("%d\n", mul(2)); printf ("%d\n", mul(-3)); printf ("%d\n", mul()); // 没有写参数,则默认参数 return 0; } // 定义时不再指定 int mul(int a) { return a * a; }
注意点:只有参数列表后面的参数可以提供默认参数值,一但在一个函数调用中开始使用默认参数值,那么这个参数后的所有参数都必须使用默认参数。
int add(int a, int b = 0, int c = 0) { return a+b+c; } int main() { printf ("%d\n", add(2)); printf ("%d\n", add(1,2)); printf ("%d\n", add(1,2,3)); return 0; }
占位参数只有参数类型声明,而没有参数名声明,一般情况下,在函数体内部无法使用占位参数。
int func(int a, int b, int ) { return a + b; } int main() { // func(1, 2);是不可以的 printf("func(1, 2, 3) = %d\n", func(1, 2, 3)); getchar(); return 0; }
7、函数重载
用同一个函数名定义不同的函数,当函数名和不同的参数搭配是函数的含义不同。
函数重载至少满足下面的条件之一:
a.参数个数不同
b.参数类型不同
c.参数顺序不同
注意函数返回值不是函数重载的判断标准
int func(int x) { return x; } int func(int a, int b) { return a + b; } int func(const char* s) { return strlen(s); } int main() { int c = 0; c = func(1) ab17 ; printf("c = %d\n", c); c = func(1, 2); printf("c = %d\n", c); c = func("12345"); printf("c = %d\n", c); return 0; }
这里需要注意了,函数重载遇上函数默认参数可能导致二义性的问题,这里归纳一下
将所有同名函数作为候选者尝试寻找可行的候选函数:
1 )精确匹配实参
2) 通过默认参数能够匹配实参
3) 通过默认类型转换匹配实参
匹配失败:
1) 最终寻找到的可行候选函数不唯一,则出现二义性,编译失败。
2) 无法匹配所有候选者,函数未定义,编译失败。
相关文章推荐
- 浅谈C到C++的扩展
- C++下扩展卡尔曼类(EKF)的实现
- C++ /CX在语法上的一些扩展
- wchar_t是C/C++的字符类型,是一种扩展的存储方式
- c++扩展PHP编译错误
- php C++ 扩展
- SWIG and Python(用SWIG将C/C++封装为Python扩展模块)
- C++到底是恐怖还是优秀,浅谈C C++的本质区别
- 浅谈Log4j的扩展 (二)
- Winx基本类使用指南之C++标准扩展(AutoFreeAlloc)
- c++对内存的浅谈以及内存泄漏问题的探讨之九
- 介绍LuaPlus: 好用的Lua For C++扩展(修订) (转帖)
- 浅谈C++中内存泄漏的检测
- 浅谈c++的编译和运行
- 浅谈C++编译原理
- 使用c/c++扩展python
- C++对C语言的扩展
- C/C++联合(Union)浅谈
- 浅谈C++容器(六) .
- SystemC——一套将C++扩展为硬件描述语言的Class Library (初学SystemC有感)