C++基础
1.概述
C++是由来自贝尔实验室(对,就是上次说的写了Unix的贝尔实验室)的本贾尼-斯特劳斯特卢普(Bjarne Stroustrup)在C语言的基础上发明的一款新的编程语言。
C++在C语言的基础上扩充了面向对象的概念,所谓面向对象,即通过面向对象的方式,将现实世界的事物抽象成对象,现实世界中的关系抽象成类、继承,帮助人们实现对现实世界的抽象与数字建模。(面向对象编程,有人称作面向女朋友编程)
2.基础入门
命名空间
命名空间是标识符的一个可见范围或者有范围,令在不同的命名空间定义的相同名称的变量在使用时不会产生冲突。
1.定义命名空间
使用namespace关键字可以定义命名空间,namespace后面跟上命名空间的名字。
namespace N{
int a;//定义变量
int func (int b,int c){//定义函数
return b+c;
}
}
namespace N{//相同名字的命名空间最后会由编译器合成一个
int* p;
}
2.使用命名空间
一共有三种使用命名空间的方法:
using namespace N;//全局生效
using N::a;//离得最近的生效;
//::是作用域限定符
printf("%d\n",N::a);
3.输出&输入
#include <iostream>//注意没有.h
using namespace std;//使用std命名空间,这样在使用std::cout等函数时就不需要加作用域限定符了
//但是有说法认为不应该习惯使用using namespace std;我的观点是只在cpp里用就好
int main (){
int a;
int b,c;
cin>>a;
cin>>b>>c;
cout<<a<<endl;
cout<<b<<" hello "<<c<<endl;
return 0;
}
参数缺省
定义函数时,可以给函数设置一个缺省参数,在使用函数时,如果没有传递参数,就用缺省值直接代替该参数。
void function (int a = 0){
if(a = 0){
cout<<"hello ";
}else {
cout<<"kishere"<<endl;
}
int main (){
function();
function(1);
上面的例子中,第一个函数没有传参,第二个函数传递了参数。输出的结果为:hello kishere
。
参数可以全部设置缺省值,称为全缺省函数。也可以只设置一部分缺省值,称为半缺省函数。但是要注意的是:
- 半缺省函数中必须将有缺省值的变量放在右边,没有缺省值的变量放在左边。
- 缺省参数不能再函数声明和定义中同时出现。
- C语言中不支持缺省参数。
函数重载
1.定义
函数重载即在一个作用域中,声明多个同名函数,这些函数的参数列表不同。在调用时,根据传递的参数来决定调用哪个函数。
2.形成重载的条件
- 在同一作用域内。
- 参数列表不同(参数类型不同或参数个数不同)。
int add(int a, int b){
return a+b;
}
char add(char a, char b){
return a;
}
int add(int a){
return a;
}
//特殊的例子
short add(short left,short right){
return left + right;
}
int add(short left ,short right){
return left +right;
}//这两个函数无法形成重载,参数列表相同
void testfunc(){
}
void testfunc(int a = 1){
}//这两个函数形成了重载,但是如果不传递参数,就会报错
引用
引用就是给变量起了一个“外号”。编译器不会给引用变量开辟内存空间。但是使用引用变量时可以得到引用实体。
1.引用类型的定义
int a = 10;
int&ra = a;//定义引用类型
int a = 10;
int& ra = a;
int* p = &a;
cout << &a << endl;
cout << &ra << endl;
cout << p << endl;//三个输出相同
const int a = 10;
int& ra = a;//这条代码在不能通过编译
const int& ra = a; //常引用
int a[10];
int(&ra)[10]=a;//数组引用
2.引用类型的特性
- 引用类型在定义时必须要初始化。
- 一个变量可以有多个引用。
- 引用类型定义后,不能再次引用其他实体。
- 引用类型必须和实体是相同类型的。
3. 引用的用途
void func1(int& left, int& right){//引用做函数参数
int temp = left;
left = right;
right = temp;
}//引用的一个作用是可以在作为函数形参,来改变实参的值
int& func2(int& a){//引用做返回值,注意不能返回栈上的空间
a+=2;
return a;
}
函数在使用值来作为返回值或者参数时,代码运行效率比较低,代码运行时间较长。而用引用作为参数或者返回值时,代码运行效率比较高,代码运行的时间比较短。
4.引用与指针
在语法上来说,引用是没有独立空间的。引用和他的引用实体公用一块空间。但是在底层实现时,我们会发现指针的汇编代码和引用的汇编代码是相同的。在底层实现时,引用是用自己的空间的,空间中存放的是引用实体的地址。
引用和指针有以下不同点:
- 引用在定义是必须初始化,指针不需要。
- 引用在初始化时引用一个实体后,就不能引用其他实体,而指针可以在任何时候指向任何一个同类型实体。
- 没有NULL引用,但是有NULL指针。
- 引用在调用sizeof()函数时结果为引用类型的大小,指针始终是4个字节(32平台下)。
- 引用增时引用实体增加1,指针自增时向后移动一个类型大小。
- 有多级指针,但没有多级引用。
- 访问实体的方式不同,指针需要解引用,引用不需要。
- 引用比指针使用起来更安全。(因为指针需要判空)
内联函数
在函数前增加inline关键字将其变为内联函数,在编译期间编译器会用函数体替换函数的调用。
inline add(int a,int b){
return a+b;
}
int main (){
int ret;
ret = add(10,20);//这行代码将变为ret = 10 + 20
return 0;
}
在visual studio中,编译器默认只在release模式下对inline修饰的函数进行替换。在dubug模式下默认不进行替换。这样的替换省区了调用函数的开销。但在函数过于复杂的情况下,并不适合使用内联函数。同时对于编译器来说,如果inline修饰的函数内含有循环、递归等算法时,编译器优化时会忽略内联。
在C++中inline修饰的函数常用来代替宏,同时也可以运用const修饰变量代替宏。
auto关键字
我们在声明变量时,都要指定变量的类型,比如int、double等等。而C++中的auto关键字可以用来自动获取变量类型:
int a;
auto b = a;
auto c = "kishere";
auto d = func();
注意:
- auto不能作为函数参数
- auto不能直接声明数组
- auto同时声明多个变量时,变量类型要一致。(反面例子:
auto c = 10,d = 10.0;
)