【c++】c++的基础知识

来源:互联网 发布:使命召唤4mac迅雷种子 编辑:程序博客网 时间:2024/05/29 14:50

命名空间
在c++中,变量、函数和类都是大量存在的,这些变量、函数和类的名称都将存在于全局命名空间中,会导致很多冲突,使用命空间的目的就是对标示符的名称本地化,以避免命名冲突或名字污染,namespace关键字就是针对这种问题的。
这种情况一般来说是不允许的,会导致编译错误,命名冲突。

void f(){    int a = 10;    int a = 20;}

命名空间的定义:

namespace Name1{    //内容}

命名空间使用方式:

namespace Name{    int test0;    int test1;    int test2;    void test()    {        test0 = 10;        test1 = 20;    }}

名称限制:
“::“是作用域限定符。前面是命名空间的名称。

void test(){    Name1::test = 0;    Name2::test = 1;}

c++基本输入输出流
在C语言中,用prinff和scanf进行输入输出,往往不能保证所输入输出的数据是可靠的、安全的。 C++编译系统提供了用于输人输出的 ostream类库。iostream这个单词是由3个部分组成的,即i-o-stream,意为输入输出流。在iostream类库中包含许多用于输入输出的类。
c++中输出/入:

cout << "hello world" << endl;//屏幕上显示hello worldcin >> a;

“<<”和“>>”本来在C++中是被定义为左位移运算符和右位移运算符的,由于在iosreeam头文件中对它们进行了重载,使它们能用作标准类型数据的输入和输出运算符。所以,在用它们的程序中必须用#include命令把ostream包含到程序中。
、cout流对象
cout是console output的缩写,意为在控制台(终端显示器)的输出。

1、cout不是C++预定义的关键字,它是ostream流类的对象,在iostream中定义。顾名思义,流是流动的数据,cout流是流向显示器的数据。cout流是容纳数据的载体,它并不是一个运算符。人们关心的是cout流中的内容,也就是向显示器输出什么。

2、用”cout<<”输出基本类型的数据时,可以不必考虑数据是什么类型,系统会判断数据的类型,并根据其类型选择调用与之匹配的运算符重载函数。
这个过程都是自动的,用户不必干预。如果在C语言中用prinf函数输出不同类型的数据,必须分别指定相应的输出格式符,十分麻烦,而且容易出错。C++的I/0机制对用户来说,显然是方便而安全的。
重载(c++为什么支持重载)

在c语言中,下面代码编译不通过;而在c++中时可以的。

void fun1(int a,int b){    //}void fun1(char a,char b){    //}

首先,我们需要了解的是,在c中,要求在同一个作用域中,函数名唯一。就是不允许函数同名。
而在C++中,要求同一个作用域中函数签名唯一。函数签名是函数名+参数列表。就是说允许函数名相同但参数列表不同的函数存在。可见,函数重载跟返回类型没什么关系。
代码段在被编译器编译的时候,会根据函数名生成函数的调用地址。
C编译器编译之后,函数名不变。而C++编译器编译之后,函数名就会发生命名置换。比如说代码中的函数是

int function(int a,int b,double c)      {          cout<<a<<b<<c<<endl;      }  

gcc编译,命名置换后,会变成_Z8functioniid。
其中_Z是gcc编译器的保留字,不同的编译器,生成的保留字也会不一样,8是函数名的字符数量,iid则是参数列表的缩写。
经过这样一个操作时候,即使是函数名相同,但只要参数列表不同,那么编译之后生成的函数名实际上是不同的。
c++缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个默认值。在调用该函数时,如果没有指定实参则采用该默认值,否则使用指定参数。

int test(int i = 0){    return i;}int main(){    cout << test() << endl;//输出结果是0    cout << test(5) << endl;//输出结果是5    getchar();    return 0;}

半缺省参数:

void FunTest(int i1,int i2 = 0){}void FunTest(int i1 = 0,int i2)//错误,i2也应该定义缺省值

一旦为函数的某个参数指定了缺省值,则必须为后续参数也定义缺省值,从右到左定义缺省参数。
全缺省参数:就是函数参数都带有缺省值
注意慎用缺省函数,否则会产生二义性

void Fun(){}void Fun(int a = 10){    cout<<a<<endl;}

假如使用不带实参的方式调用Fun()函数时。编译器将不知道调用哪一个,产生二义性。
【注意】:
1,带缺省值的参数必须放在参数表的最后面
2,缺省参数不能同时在函数的声明和函数定义中出现,二者只能选其一。
3,缺省值必须是常量或者全局变量。
4,缺省参数必须通过值参或者常参传递。

指针和引用
引用概念:引用不是新定义一个变量,而是给已存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它的引用共用同一块内存空间。
这里写图片描述

    int a = 10;    int& b = a;//b是a的引用

引用特性
1,引用在定义是必须初始化。
2,一个变量可以有多个引用。
3,引用一旦绑定了一个实体,就不能再改变为其他变量引用。
常引用

void test0(){    int inum0 = 0;    const int& inum1 = inum0;//inum1是inum0的常引用    //int& inum2 = inum1;//错误,inum1是常引用,所以inum2必须是常引用    //int& inum2 = inum0;    const int& inum2 = inum1;}
void test(){    //int &inum2 = 20;错误,    const int& inum3 = 30;//常引用可以对常量引用}
void test1(){    float fnum4 = 10.0f;    //int& inum5 = fnum4;不可以进行引用    const int& inum5 = fnum4;//fnum4是float型,inum5是int型,进行赋值时会生成一个临时变量,而临时变量具有常属性,所以要用const引用才可以}

引用做参数】:
作为函数参数时引用有两种原因:
1、在函数内部会对此参数进行修改
2、提高函数调用和运行效率

void Swap(int& a, int& b)//这里传引用做参数和穿指针做参数起到的作用是一样的而且跟指针一样可以提高效率{    int tmp;    tmp = a;    a = b;    b = tmp;}

引用作返回值】:
说明:
(1)以引用返回函数值,定义函数时需要在函数名前加&
(2)用引用返回一个函数值的最大好处是,在内存中不产生被返回值的副本。

//值返回int Addi(int l,int r)//{    return l+r;}//引用返回int& Add(int l,int r){    int ret = l+r;    return ret;}

引用作为返回值,必须遵守以下规则:
(1)不能返回局部变量的引用。主要原因是局部变量会在函数返回后被销毁,因此被返回的引用就成为了”无所指”的引用,程序会进入未知状态。
(2)不能返回函数内部new分配的内存的引用。虽然不存在局部变量的被动销毁问题,可对于这种情况(返回函数内部new分配内存的引用),又面临其它尴尬局面。例如,被函数返回的引用只是作为一 个临时变量出现,而没有被赋予一个实际的变量,那么这个引用所指向的空间(由new分配)就无法释放,造成memory leak。
(3)可以返回类成员的引用,但最好是const。主要原因是当对象的属性是与某种业务规则(business rule)相关联的时候,其赋值常常与某些其它属性或者对象的状态有关,因此有必要将赋值操作封装在一个业务规则当中。如果其它对象可以获得该属性的非常 量引用(或指针),那么对该属性的单纯赋值就会破坏业务规则的完整性。

指针和引用的区别
相同点:
底层实现方式相同,都是按照指针的方式实现的。
不同点:
1,引用定义是必须初始化,指针可以不用,一般情况下初始化为NULL
2,引用一旦定义就不能再改变,指针可以。
3,在sizeof中含义不同:引用结果为引用类型的大小,但是指针始终是地址空间所占字节数,32为平台下是4个字节.
4,引用自加改变变量的内容,指针自加改变了指针的指向
5,有多级引用,没有多级指针。
6,引用比指针使用起来相对安全。

原创粉丝点击