C++ 入门知识
2017-06-18 16:44
211 查看
知识点:
1.命名空间
2.C++基本的输入输出流(简单介绍一下就行)
3.重载(C++为什么支持重载?)
4.C++缺省参数
5.指针和引用(概念、使用方法、做参数、做返回值的作用,指针和引用的区别)
1.命名空间 : namespacenamespace,即“命名空间”,也称“名字空间”。VS.NET中的各种语言使用的一种代码组织的形式通过名称空间来分类,区别不同的代码功能。同时也是VS.NET中所有类的完全名称的一部分。
首先,来看它是如何使用的(::是作用域运算分解符):
(1) 引用 using namespace std;
#include <iostream> using namespace std; namespace A1 { int a = 10; } namespace A2 { int a = 20; } int a = 30; int main() { cout<<A1::a<<endl; //使用A1空间 a=10 cout<<A2::a<<endl; //使用A2空间 a=20 cout<<::a<<endl; //使用全局域空间 cout<<a<<endl; return 0; }
(2) 输出时还可以 采用 std::count<<......<<std::endl的方式;
此外,
命名空间可以是全局的,也可以位于另一个命名空间之中,但是不能位于类和代码块中。所以,在命名空间中声明的名称(标识符),默认具有外部链接特性(除非它引用了常量)。
在所有命名空间之外,还存在一个全局命名空间,它对应于文件级的声明域。因此,在命名空间机制中,原来的全局变量,现在被认为位于全局命名空间中。
标准C++库(不包括标准C库)中所包含的所有内容(包括常量、变量、结构、类和函数等)都被定义在命名空间std(standard标准)中了。
2.C++的基本输入输出流
(1)标准输入流(cin):
cin是iostream类的对象,它从标准输入设备(键盘)获取数据,程序中的变量通过流提取符“>>”从流中提取数据。流提取符“>>”从流中提取数据时通常跳过输入流中的空格、tab键、换行符等空白字符。
(2)标准输出流(cout):
cont是console output的缩写,意为在控制台(终端显示器)的输出。
①cout不是C++预定义的关键字,它是ostream流类的对象,在iostream中定义。 顾名思义,流是流动的数据,cout流是流向显示器的数据。cout流中的数据是用流插入运算符“<<”顺序加入的。如果有:
cout<<"I "<<"study C++ "<<"very hard.";
按顺序将字符串"I ", "study C++ ", "very hard."插人到cout流中,cout就将它们送到显示器,在显示器上输出字符串"I study C++ very hard."。cout流是容纳数据的载体,它并不是一个运算符。人们关心的是cout流中的内容,也就是向显示器输出什么。
②cout流在内存中对应开辟了一个缓冲区,用来存放流中的数据,当向cout流插 人一个endl时,不论缓冲区是否已满,都立即输出流中所有数据,然后插入一个换行符, 并刷新流(清空缓冲区)。注意如果插人一个换行符”\n“(如cout<<a<<"\n"),则只输出和换行,而不刷新cout流(但并不是所有编译系统都体现出这一区别)。
(3)标准错误流(cerr,clog):
①cerr流对象是标准错误流,cerr流已被指定为与显示器关联。
②7clog流对象也是标准错误流,它是console log的缩写。它的作用和cerr相同,都是在终端显示器上显示出错信息。区别:cerr是不经过缓冲区,直接向显示器上输出有关信息,而clog中的信息存放在缓冲区中,缓冲区满后或遇endl时向显示器输出。
下面演示一个标准输入输出流的简单程序:
int main()
{
int a = 0;
cout<<"请输入一个整数"<<endl;
cin>>a;
cout<<oct<<a<<endl; //8进制输出
cout<<dec<<a<<endl; //10进制输出,不写类型默认输出十进制
cout<<hex<<a<<endl; //16进制输出
cout<<"请输入一个布尔值0或者1"<<endl;
bool b = 1; //定义布尔类型
cin>>b;
cout<<boolalpha<<b<<endl; //以布尔类型输出
return 0;
}
3.重载(C++为什么支持重载)
重载:在同一个作用域中,函数名相同,参数不同(类型不同,个数不同)。
func(int a, int b); | func(int a); | func(double a, double b); //函数重载
①首先,我们需要了解的是,在c中,要求在同一个作用域中,函数名唯一。就是不允许函数同名。
而在C++中,要求同一个作用域中函数签名唯一。函数签名是函数名+参数列表。就是说允许函数名相同但参数列表不同的函数存在。可见,函数重载跟返回类型没什么关系。
②那么为什么C++允许函数签名唯一呢?
代码段在被编译器编译的时候,会根据函数名生成函数的调用地址。
C编译器编译之后,函数名不变。
而C++编译器编译之后,函数名就会发生命名置换。比如说代码中的函数是
int function(int a,int b,double c)
{
cout<<a<<b<<c<<endl;
}
gcc 编译,命名置换后,会变成_Z8functioniid。
其中_Z是 gcc 编译器的保留字,不同的编译器,生成的保留字也会不一样,8是函数名的字符数量,iid则是参数列表的缩写。
经过这样一个操作时候,即使是函数名相同,但只要参数列表不同,那么编译之后生成的函数名实际上是不同的。
4.C++缺省参数
在C++中参数可以设置缺省值,设置了缺省值之后,这个参数在调用时可以省略。
注意:设置缺省值的参数只能是最后的几个参数。也就是说某一个参数一旦设置了缺省值,其后而的参数也必须设置缺省值。例如:f()函数有3个参数,如果只设置第2个有缺省值,这就错了。因为调用时只输入2个参数时,系统不知道究竟是第2个参数还是第3个参数。
例如:
int sum(int x=0, int y=100, int z=0) { return x+y+z; } int sum(int x, int y=100, int z=0) { ... } //这是正确的 int sum(int x, int y, int z=0) { ... } //这是正确的 int plus(int x, int y=100, in 4000 t z) { ... } //这是错误的
缺省参数使用主要规则:调用时你只能从最后一个参数开始进行省略,换句话说,如果你要省略一个参数,你必须省略它后面所有的参数,即:带缺省值的参数必须放在参数表的最后面。 缺省值必须是常量。显然,这限制了缺省参数的数据类型,例如动态数组和界面类型的缺省参数值只能是 nil;至于记录类型,则根本不能用作缺省参数。 缺省参数必须通过值参或常参传递。
5.指针和引用(概念、使用方法、做参数、做返回值的作用,指针和引用的区别)
首先,对两者进行简单的对比:
指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形式参数作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形式参数的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。(这里是在说实参指针本身的地址值不会变)
引用传递过程中,被调函数的形式参数虽然也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址(int &a的形式)。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。正因为如此,被调函数对形参做的任何操作都影响了主调函数中的实参变量。
①从传递角度:
引用传递和指针传递是不同的,虽然它们都是在被调函数栈空间上的一个局部变量,但是任何对于引用参数的处理都会通过一个间接寻址的方式操作到主调函数中的相关变量。而对于指针传递的参数,如果改变被调函数中的指针地址,它将影响不到主调函数的相关变量。如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。
②从编译角度:
程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。
下面再具体谈一下 引用:
引用的规则:
(1)引用被创建的同时必须被初始化(指针则可以在任何时候被初始化)。
(2)不能有NULL引用,引用必须与合法的存储单元关联(指针则可以是NULL)。
(3)一旦引用被初始化,就不能改变引用的关系(指针则可以随时改变所指的对象)。
一、引用的概念
引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*。例如:
Point pt1(10,10);
Point &pt2=pt1;
定义了pt2为pt1的引用。通过这样的定义,pt1和pt2表示同一对象。需要特别强调的是引用并不产生对象的副本,仅仅是对象的同义词。因此,当下面的语句执行后:
pt1.offset(2,2);
pt1和pt2都具有(12,12)的值。引用必须在定义时马上被初始化,因为它必须是某个东西的同义词。你不能先定义一个引用后才初始化它。例如下面语句是非法的:
Point &pt3;
pt3=pt1;
引用的两个主要用途:作为函数参数以及从函数中返回左值。
二、引用参数
1、传递可变参数
传统的c中,函数在调用时参数是通过值来传递的,这就是说函数的参数不具备返回值的能力。所以在传统的c中,如果需要函数的参数具有返回值的能力,往往是通过指针来实现的。比如,实现两整数变量值交换的c程序如下:
void swapint(int *a,int *b)
{
int temp;
temp=*a;
a=*b;
*b=temp;
}
使用引用机制后,以上程序的c++版本为:
void swapint(int &a,int &b)
{
int temp;
temp=a;
a=b;
b=temp;
}
调用该函数的c++方法为:swapint(x,y); c++自动把x,y的地址作为参数传递给swapint函数。
2、给函数传递大型对象
当大型对象被传递给函数时,使用引用参数可使参数传递效率得到提高,因为引用并不产生对象的副本,也就是参数传递时,对象无须复制。
三、引用返回值
如果一个函数返回了引用,那么该函数的调用也可以被赋值。
引用返回值的概念与引用参数相似,下面通过几个例子说明容易出错的地方。
(1)int &max(int i, int j) //错误的用法,i和j都是局部变量
{
return i>j?i:j;
}
(2)int m;
int &max(int i, int j) //正确
{
m = i>j?i:j;
return m;
}
(3)int &max(int &i, int &j) //正确
{
return i>j?i:j;
}