赞
踩
C++是一种计算机高级程序设计语言,由C语言扩展升级而来。
C++既可以进行C语言的过程化程序设计,又可以进行以抽象数据类型为特点的基于对象的程序设计,还可以进行以继承和多态为特点的面向对象的程序设计。即C++擅长面向对象程序设计的同时,还可以进行基于过程的程序设计。
C++拥有计算机运行的实用性特征,同时还致力于提高大规模程序的编程质量与程序设计语言的描述问题
-----百度百科
C++相比较与C语言,增加了将近一倍数量关键字,C++总计有63个关键字。如图:
3.1、问题提出
在C语言中,当我们定义变量名时,变量名与库中的函数重名,就会报错。如图:
变量名rand与库中的rand函数重名时,就会报重定义错误。
同样的,当我们在工程中,两个程序员在各自写代码的过程中使用了同名的变量名,就会出现错误,C++为了解决这一问题引入了命名空间。
3.2、命名空间定义
定义命名空间需要使用namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。
注意:一个命名空间就定义了一个新的作用域,命名空间中所有内容都局限于该命名空间中
3.3 命名空间的使用
- 加命名空间名称及作用域限定符(::)
namespace cpp { int n = 0; int m = n + 1; } int main() { int k = cpp::n; //使用作用域限定符(::) std::cout << cpp::n << std::endl; return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 使用using将命名空间中某个成员引入
namespace cpp { int n = 0; int m = n + 1; } using cpp::n; //将命名空间中的n释放 int main() { int k = n; return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 使用 " using namespace 命名空间 "引入
namespace cpp { int n = 0; int m = n + 1; } using namespace cpp; //将命名空间中的全部成员释放 int main() { int k = n; std::cout << m << std::endl; return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
C++标准库的命名空间为std,在使用std命名空间中,并不推荐上述的第三种方法,而是上面的一二种方法。
using namespace std 展开,标准库就全部暴露出来了,如果我们定义和库重名的类型/对象/函数,就又会存在冲突问题。
所以在平常的练习中,为了方便可以直接展开,但是在项目中并不推荐这种方法。
4.1 缺省参数概念
缺省参数是声明或者定义函数时为函数的参数指定一个缺省(默认)值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
void Func(int a = 0) { std::cout << a << std::endl; } int main() { Func(); // 没有传参是时默认使用缺省值,即 a = 0 Func(10); //传参时使用参数,即 a = 10 }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
4.2 缺省参数分类
- 全缺省参数(全部参数都设置缺省值)
- 半缺省参数( 部分参数设置缺省值)
注意:
1、半缺省参数必须从右往左依次来给,不能间隔给
2、缺省参数不能在函数声明和定义时同时给(声明和定义都给缺省值时,编译器无法识别该使用哪个缺省值,所以一般在声明时给缺省值即可)
3、缺省值必须为常量或者全局变量
4、C语言不支持
5.1函数重载概念:
函数重载是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数,参数类型,参数类型顺序)不同,常用来处理实现功能类似但数据类型不同的问题。
5.2 参数列表不同
- 类型不同
void Add(int a, int b) { std::cout << "Add(int a, int b)" << std::endl; } void Add(double a, double b) { std::cout << "Add(int a, int b)" << std::endl; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 参数的个数不同
void Add() { std::std::cout << "Add()" << std::endl; } void Add(int a, int b) { std::cout << "Add(int a, int b)" << std::endl; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 参数的顺序不同
void Func(int a, char b) { std::cout << "Func(int a ,char b)" << std::endl; } void Func(char a , int b) { std::cout << "Add(char a, int b)" << std::endl; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
5.3 函数重载原理 ---- 名字修饰(name mangling)
C++代码在编译时会根据参数列表对函数进行重命名(即将参数列表也加入到函数名修饰规则中),这样就方便识别每个同名却不同参的函数。
所以函数重载仅仅是语法层面的,本质上它们还是不同的函数,占用不同的内存,入口地址也不同。
例如在Linux下修饰:
int f(char a,int b ); //修饰为 _Z1fci int f(int a,char b); //修饰为 _Z1fic
- 1
- 2
注意:
返回值不同不构成重载并不是因为函数名修饰规则中无法加入返回值这一判断条件,而是在调用函数时具有二义性,无法区别调用的是哪个函数,因为调用时不指定返回值类型。
void func(int a,int b) { std::cout << "func(int a,int )" << std::endl; } int func(int a, int b) { std::cout << "func(int a,int )" << std::endl; return a +b; } int main() { func(1,1); //在调用的时候,无法通过返回值来选择。 func(2,2); //先调用,再有返回值 return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
在C/C++编程习惯中,声明一个变量时最好给变量一个合适的初始值,否则可能会出现不可预料的错误。尤其是当我们声明指针时,最好要对指针初始化为NULL
NULL是一个宏,在传统的C头文件(stddef.h)中将NULL定义为0或者((void*)0)
void f(int a) { std::cout << "f(int a)" << std::endl; } void f(int* ptr) { std::cout << "f(int* ptr)" << std::endl; } int main() { f(0); f(NULL); return 0; }
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
当我们执行上述代码时,会发现无论传NULL还是0,所调用的都是第一个函数。
程序本意是想通过f(NULL)调用指针版本的f(int *)函数,但是由于NULL被定义为0,因此与程序的初衷相悖。
所以C++在C++11中引入了nullptr作为关键字来表示指针空值
7.1 概念
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
7.2 特性
- inline只是向编译器建议次函数可以展开,具体是否展开取决于编译器。
- inline对于编译器而言只是一个请求,编译器可以选择忽略这个请求。一般建议将规模较小,不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽视inline的特性。
- inline修饰的函数不能声明和定义分离,分离会导致链接错误。
联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
7.2 特性
- inline只是向编译器建议次函数可以展开,具体是否展开取决于编译器。
- inline对于编译器而言只是一个请求,编译器可以选择忽略这个请求。一般建议将规模较小,不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽视inline的特性。
- inline修饰的函数不能声明和定义分离,分离会导致链接错误。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。