cpp入门

来源:互联网 发布:淘宝网店开店步骤2016 编辑:程序博客网 时间:2024/05/16 12:40

===============================================================================================================================

cpp入门基础知识

命名空间

为什么需要将函数定义在命名空间中呢?这其实是为了避免变量或函数重命名的问题。试想,一个项目组内多个工程师进行开发,有可能会出现全局变量或函数重名的现象,而如果每个人都定义了自己的命名空间,就可以解决这个问题,即使重名,只要分属不同的命名空间就不会引起问题。 
这样大家应该明白了,命名空间就是将多个变量和函数等包含在内,使其不会与命名空间外的任何变量和函数等发生重命名的冲突。

using namespace *的意义

在上面的实例中,我们访问命名空间JiZhuoMi和Software中的字符串变量时,都需要在前面加上“命名空间::”,但cout定义在命名空间std中,前面却不需要加“std::”,这是因为上面这样一条语句“using namespace std;”。 
using namespace *;(这里的表示可以是任何命名空间)的作用是释放命名空间中的变量或函数等,使之在被访问时可以不必加“命名空间::”,访问方法与一般的变量或函数无异,就像上面的cout一样。 
using namespace *;会给我们书写程序带来方便,但也要慎用,如果释放了多个命名空间中的东西后,它们又可能会引起命名冲突。鸡啄米给大家演示下同时释放JiZhuoMi和Software命名空间的情况。

cpp基本的输入输出流

输入和输出是数据传送的过程,数据如流水一样从一处流向另一处。C++形象地将此过程称为流(stream)。C++的输入输出流是指由若干字节组成的字节序列,这些字节中的数据按顺序从一个对象传送到另一对象。流表示了信息从源到目的端的流动。在输入操作时,字节流从输入设备(如键盘、磁盘)流向内存,在输出操作时,字节流从内存流向输出设备(如屏幕、打印机、磁盘等)。流中的内容可以是ASCII字符、二进制形式的数据、图形图像、数字音频视频或其他形式的信息。

实际上,在内存中为每一个数据流开辟一个内存缓冲区,用来存放流中的数据。当用cout和插入运算符“<<”向显示器输出数据时,先将这些数据送到程序中的输出缓冲区保存,直到缓冲区满了或遇到endl,就将缓冲区中的全部数据送到显示器显示出来。在输入时,从键盘输入的数据先放在键盘缓冲区中,当按回车键时,键盘缓冲区中的数据输入到程序中的输入缓冲区,形成cin流,然后用提取运算符“>>”从输入缓冲区中提取数据送给程序中的有关变量。总之,流是与内存缓冲区相对应的,或者说,缓冲区中的数据就是流。

在C++中,输入输出流被定义为类。C++的I/0库中的类称为流类(streamclass)。用流类定义的对象称为流对象。

前面曾多次说明,cout和cin并不是C++语言中提供的语句,它们是iostream类的对象,在未学习类和对象时,在不致引起误解的前提下,为叙述方便,把它们称为cout语句和cin语句。正如C++并未提供赋值语句,只提供赋值表达式,在赋值表达式后面加分号就成了C++的语句,为方便起见,我们习惯称之为赋值语句。又如,在C语言中常用printf和scanf进行输出和输入,printf和scanf是C语言库函数中的输入输出函数,一般也习惯地将由printf和scanf函数构成的语句称为printf语句和scanf语句。在使用它们时,对其本来的概念要有准确的理解。

  • 1.iostream类库中有关的类 
    C++编译系统提供了用于输人输出的iostream类库。iostream这个单词是由3个部分组成的,即i-o-stream,意为输入输出流。在iostream类库中包含许多用于输入输出的类。

    ios是抽象基类,由它派生出istream类和ostream类,两个类名中第1个字母i和o。分 别代表输入(mput)和输出(output)。istream类支持输入操作,ostream类支持输出操作, iostream类支持输入输出操作。iostream类是从istream类和ostream类通过多重继承而派生的类。

    C++对文件的输人输出需要用ifstream和ofstream类,两个类名中第1个字母i和o分别代表输入和输出,第2个字母f代表文件(file)。ifstream支持对文件的输入操作,ofstream支持对文件的输出操作。类ifstream继承了类istream,类ofstream继承了类ostream,类fstream继承了类iostream。

    由抽象基类ios直接派生出4个派生类,即istream,ostream,fstreambase和strstreambase。其中fstreambase是文件流类基类,由它再派生出ifstream,ofstream和fstream。strstreambase是字符串流类基类,由它再派生出lstrstream,ostrsCeam和swsWeam类。 
    I/0类库中还有其他一些类,但是对于一般用户来说,以上这些已能满足需要了。如果想深入了解类库的内容和使用,可参阅所用的C++系统的类库手册。在本章将陆续介绍有关的类。

  • 2、与iostream类库有关的头文件 
    iostream类库中不同的类的声明被放在不同的头文件中,用户在自己的程序中用 #include命令包含了有关的头文件就相当于在本程序中声明了所需要用到的类。可以换一种说法:头文件是程序与类库的接口,iostream类库的接口分别由不同的头文件来实现。常用的有 
    1,iostream 包含了对(标准)输入输出流进行操作所需的基本信息。 
    2,fstream 用于用户管理的文件的I/0操作。 
    3,sbsbeam 用于字符串流I/0。 
    4,stdiostream 用于混合使用C和C++的I/0机制时,例如想将C程序转变为C++程序。 
    5,iomamp 在使用格式化I/0时应包含此头文件。

  • 3、在iostream头文件中定义的流对象 
    在iostream头文件中定义的类有:ios,istream,ostream,iostream,istream_withassign,stream_withassign,iostream_withassign等。 
    iostream包含了对输入输出流进行操作所需的基本信息。因此大多数C++程序都包括iostream。在iostream头文件中不仅定义了有关的类,还定义了4种流对象,

    cin是istream的派生类istream_withassign的对象,它是从标准输入设备(键盘)输入到内存的数据流,称为cin流或标准输入流。cout是ostream的派生类ostream_withassign的对象,它是从内存输入到标准输出设备(显示器)的数据流,称为cout流或标准输出流。cerr和clog作用相似,均为向输出设备(显示器)输出出错信息。因此用键盘输入时用cin流,向显示器输出时用cout流。向显示器输出出错信息时用cerr和clog流。

cpp为什么支持重载?

C++支持函数重载而C语言不支持函数重载。 
而所谓的函数重载就是指: 
在同一作用域类,一组函数的函数名相同,参数列表不同(个数不同或类型不同),返回值可同可不同。 
那么问题来了,为什么C++支持函数重载,而C语言不支持呢? 
从代码的编译到运行,在VC6.0或VS这种编译器下,它是系统直接完成了翻译与链接,直接生成了运行结果。 
编译器内部完成了翻译部分: 
1.预处理 
1)头文件展开 
2)宏的替换 
3)去注释 
4)条件编译 
2.编译过程:将高级语言转为汇编语言 
3.汇编过程:汇编语言转为二进制程序 
链接部分:所引用的数据链接进来 
比如一个函数的声明如下: 
void function(int x,int y); 
在c语言中,编译器在编译后在库中的名字为_function 
在c++中,编译器在编译后在库中的名字为_Z8functionii 
还有一个函数的声明如下: 
void function(float x,float y); 
在c语言中,编译器在编译后在库中的名字为_function 
在c++中,编译器在编译后在库中的名字为_function_float_float 
在链接时,都是找名字进行链接的,就比如以上两个函数, 
在C语言中两个的名字一样,就会在链接中报错。 
C++中它们的名字不一样,所以就不会报错。

cpp缺省参数

所谓缺省参数,顾名思义,就是在声明函数的某个参数的时候为之指定一个默认值,在调用该函数的时候如果采用该默认值,你就无须指定该参数。缺省参数使用主要规则:调用时你只能从最后一个参数开始进行省略,换句话说,如果你要省略一个参数,你必须省略它后面所有的参数,即:带缺省值的参数必须放在参数表的最后面。 缺省值必须是常量。显然,这限制了缺省参数的数据类型,例如动态数组和界面类型的缺省参数值只能是 nil;至于记录类型,则根本不能用作缺省参数。 缺省参数必须通过值参或常参传递。

  1. 如果函数已经带有缺省参数的函数原型声明,则在该函数的定义中不允许出现缺省值。
  2. 一旦为函数的某个参数指定了缺省值,则必须为后续参数也定义缺省值,从右到左定义缺省参数。 
    void showmessage(char *text,int length=1,int color ) ; //错color也应定义缺省值。
  3. 调用函数时,如果略去一个参数传递,则略去后续所有参数传递,调用时将参数从左至右,逐一传递给行参。 
    showmessage(“hello”); 
    showmessage(“hello”,5); 
    showmessage(“hello”,5,8); 
    showmessage(“hello”, ,8); // 错误

指针和引用

指针保存一个对象的地址,通过该地址访问对象;引用是对象的别名。二者在概念及使用上需要分清楚。

引用不可以为空,指针可以为空。定义一个引用的时候,必须初始化;声明指针是可以不指向任何对象,即空指针。因此如果一个变量是用于指向另一个对象,它可能为空,这时你应该使用指针;如果变量总是指向一个对象,且不允许变量为空,这时你应该使用引用。由于指针可能为空,使用指针之前必须做判空操作,而引用就不必。

引用不可以改变指向;指针可以改变指向。虽然引用不可以改变指向,但是可以改变初始化对象的内容。例如就++操作而言,对引用的操作直接反应到所指向的对象,而不是改变指向;而对指针的操作,会使指针指向下一个对象,而不是改变所指对象的内容。要通过指针修改对象内容需要先获取对象。

引用的大小是所指向的变量的大小,因为引用只是一个别名而已;指针是指针本身的大小,4个字节。

引用比指针更安全。由于不存在空引用,并且引用一旦被初始化为指向一个对象,它就不能被改变为另一个对象的引用,因此引用很安全。对于指针来说,它可以随时指向别的对象,并且可以不被初始化,或为NULL,所以不安全。const指针虽然不能改变指向,但仍然存在空指针,并且有可能产生野指针(即多个指针指向一块内存,free掉一个指针之后,别的指针就成了野指针)。

const对指针和引用的限定是有差别的:

常量指针:指向常量的指针,在指针定义语句的类型前加const,表示指向的对象是常量。

常量引用:指向常量的引用,在引用定义语句的类型前加const,表示指向的对象是常量。也跟指针一样不能利用引用对指向的变量进行重新赋值操作。

指针常量:在指针定义语句的指针名前加const,表示指针本身是常量。在定义指针常量时必须初始化!而这是引用天生具来的属性,不用再引用定义语句的引用名前加const。

常量指针常量:指向常量的指针常量,可以定义一个指向常量的指针常量,它必须在定义时初始化。常量指针常量定义”const int* const pointer=&c”告诉编译器,pointer和*pointer都是常量,他们都不能作为左值进行操作。

而就不存在所谓的”常量引用常量”,因为跟上面讲的一样引用变量就是引用常量。C++不区分变量的const引用和const变量的引用。程序决不能给引用本身重新赋值,使他指向另一个变量,因此引用总是const的。如果对引用应用关键字const,起作用就是使其目标成为const变量。即没有:const double const& a=1;只有const double& a=1;

引用占不占空间?

有人说占用,有人说不占用,看怎么理解。作为变量,肯定是有内存要存的,汇编层面上和指针一样。但是从语义上讲,引用就是一个别名,不会分配一个对象空间。编译器也有可能提前优化处理。C++标准并未规定引用的实现方式,一般使用指针。

指针传递和引用传递

指针传递参数本质上是值传递的方式,它所传递的是一个地址值。值传递过程中,被调函数的形参作为被调函数的局部变量处理,即在栈中开辟了内存空间以存放由主调函数放进来的实参的值,从而成为了实参的一个副本。值传递的特点是被调函数对形参的任何操作都是作为局部变量进行,不会影响主调函数的实参变量的值。

引用传递过程中,被调函数的形参也作为局部变量在栈中开辟了内存空间,但是这时存放的是由主调函数放进来的实参变量的地址。被调函数对形参的任何操作都被处理成间接寻址,即通过栈中存放的地址访问主调函数中的实参变量。被调函数对形参做的任何操作都影响了主调函数中的实参变量。

如果想通过指针参数传递来改变主调函数中的相关变量,那就得使用指向指针的指针,或者指针引用。

引用并不产生对象的副本,仅仅是对象的同义词,当大型对象被传递给函数时,使用引用参数可使参数传递效率得到提高,因为引用并不产生对象的副本,也就是参数传递时,对象无须复制。

指针从本质上讲就是存放变量地址的一个变量,在逻辑上是独立的,它可以被改变,包括其所指向的地址的改变和其指向的地址中所存放的数据的改变。

而引用是一个别名,它在逻辑上不是独立的,它的存在具有依附性,所以引用必须在一开始就被初始化,而且其引用的对象在其整个生命周期中是不能被改变的(自始至终只能依附于同一个变量)。

从编译的角度讲:程序在编译时分别将指针和引用添加到符号表上,符号表上记录的是变量名及变量所对应地址。指针变量在符号表上对应的地址值为指针变量的地址值,而引用在符号表上对应的地址值为引用对象的地址值。符号表生成后就不会再改,因此指针可以改变其指向的对象(指针变量中的值可以改),而引用对象则不能修改。

引用是类型安全的,而指针不是,引用比指针多了类型检查。

原创粉丝点击