学科分类
目录
C++基础

第一个C++程序

通过前面小节的学习,我们对C++这种面向对象的编程语言有了一定认识,接下来就要学习一下如何编写出第一个C++程序。本书同系列教材《C语言程序设计教程》使用Visual Studio2013来开发C程序,同样的在本书中仍然使用Visual Studio2013作为C++的开发环境,关于Visual Studio2013的安装与使用,请参考《C语言程序设计教程》一书(传智播客高教产品研发部 著),本书就不再重复讲解了。

用Visual Studio2013来编写一个最简单的C++程序,首先要创建一个C++源程序hello.cpp,其具体实现步骤和创建C语言源文件一样,具体创建步骤本书不再重复,注意C++源文件的扩展名是“.cpp”。

在创建的源文件中编写C++程序,具体代码如例1所示。

例1

 1  #include <iostream>
 2  using namespace std;
 3  int main()
 4  {
 5    cout << "hello C++" << endl;
 6    system("pause");
 7     return 0;
 8  }

运行结果如图1所示。

图1 例1-1运行结果

例1就是一个完整的C++语言程序,接下来针对该程序中的主要语法进行详细讲解,具体如下:

1、iostream文件

例1-1中第1行代码包含了输入输出头文件 iostream,它是标准的C++头文件,在旧的标准C++中,使用的是iostream.h,实际上这两个文件是不同的,在编译器include文件夹里它是两个文件,并且内容不同。在C++标准明确提出不支持后缀为.h的头文件,早期在C++中调用.h头文件其实相当于调用的C标准库,为了和C语言区分开,C++标准规定不使用后缀.h的头文件,例如C语言中的string.h头文件,C++用string,C语言中的math头文件,C++使用cmath头文件。这不只是形式上的改变,其实现也有所不同。

2、命名空间

第二行代码是引用全局命名空间,在讲解全局命名空间之前,先来学习一下什么是命名空间。命名空间实际上是由程序设计者命名的内存区域,程序设计者可以根据需要指定一些有名字的空间区域,把一些自己定义的变量、函数等标识符存放在这个空间中,从而与其他实体定义分隔开来。其定义格式如下所示:

namespace 空间名{……}

namespace是定义命名空间的关键字,空间名可以用任意合法的标识符,在{}内声明空间成员,例如定义一个命名空间A1,代码如下所示:

namespace A1
{
  int a = 10;
}

则变量a只在A1空间内({}作用域)有效,命名空间的作用就是建立一些互相分隔的作用域,把一些实体定义分隔开来,就像三个名字相同的同学,如果分在一个班级里,则点名时就会出现不确定性,如果将他们分在不同的班级则再点名时就没有歧义了。

当命名空间外的作用域要使用空间内定义的标识符时,有三种方法可以使用:

(1)用空间名加上作用域标识符“::”来标识要引用的实体,例如要引用上述A1空间中的变量a。

cout<<A1::a;

在引用处指明变量所属的空间,就可以对变量进行操作了。

(2)使用using关键字,在要引用空间实体的上面,使用using关键字引入要使用的空间变量。

using A1::a;
cout<<a;

这种情况下,只能使用using引入的标识符,如果A1空间里还有标识符b,则这个地方只引入了a, 则b不能被使用,但可以使用A1::b的形式。

(3)使用using关键字直接引入要使用的变量所属的空间,例如:

using namespace A1;

这样引入A1空间后,则A1中定义的所有实体都可以被引用了。但这种情况如果引用多个命名空间

往往容易出错,例如,定义了两个命名空间,两个空间都定义了变量a,示例代码如下所示:

namespace A1
{
   int a = 10;
}
namespace A2
{
   int a = 20;
}
using namespace A1; //引入A1命名空间
using namespace A2; //引入A2命名空间
cout<<a; //引起编译错误

这样在输出a时就会出错,因为A1与A2空间都定义了a变量,引用不明确,编译出错。因此只有在使用命名空间数量很少,以及确保这些命名空间中没有同名成员时才用using namespace语句。

在编写C++程序时,由于C++标准库中的所有标识符都被定义于一个名为std的namespace中,所以std又叫作标准命名空间,要使用其中定义的标识符就要引入std空间。早期的实现将标准库功能定义在全局空间,声明在带iostream.h头文件里,包含iostream.h头文件就可以使用全局命名空间中的标识符。而现在的iostream头文件没有定义全局命名空间,如果要使用命名空间中的标识符,就要单独引入std空间。

对于命名空间的三种引用,显而易见,第三种选择更为方便。在编写大型项目时,往往是很多程序员编写很多源文件,函数名、变量名等难免会重复,如想使用一个变量num时,系统中存在两个num变量,这时就可以将它们归属到不同的命名空间space1、space2中,在使用时就可以用不同的命名空间来区分它们,如:space1::num,space2::num。

多学一招:匿名命名空间

命名空间还可以定义成匿名的,也就是在申请的时候不写名字,由系统自动分配。例如下面的匿名命名空间:

namespace
{
  int a;
}

编译时,编译器在内部会为这个命名空间生成一个唯一的名字,而且还会为这个匿名的命名空间生成一条using指令。所以上面的代码在编译后等效于下面的代码:

namespace _UNIQUE_NAME
{
  int a;
}
using namespace __UNIQUE_NAME_;

这个匿名的空间具有一个很有用的特性,那就是对于不同的编译单元(cpp文件),“同一个”匿名空间中的对象,会被当作不同的实体。而这个特性和全局的static修饰是一致的,即相当于在这个源程序中定义了一个static int a;也就是只能在当前文件中引用a,而外部是不可见的。

由于static不能修饰类型定义,如class,而且static用在不同的地方有不同的含义,很容易造成混淆,所以相对于static,C++更倾向于使用匿名空间。

3、cin与cout

当例1-1中的第5行代码在屏幕上输出“hello C++”时,读者或许会吃惊,为什么不是printf()。其实printf()函数也可以,但它是C语言的标准输出函数。在C++中输入输出都是以“流”的形式实现的, C++定义了iostream流类库,它包含两个基础类istream和ostream来表示输入流和输出流它们分别定义了标准输入流对象cin来处理输入,标准输出流对象cout来处理输出。

cin与提取运算符“>>”结合使用,用于读入用户输入,以空白(包括空格、回车、TAB)为分隔符。

cout与插入运算符“<<”结合使用,用于打印消息。通常它还会与操纵符endl使用,endl的效果是结束当前行,并将与设备关联的缓冲区(buffer)中的数据刷新到设备中,保证程序所产生的所有输出都写入输出流中,而不是仅停留在内存中。

为了让读者了解cin、cout的使用,接下来由用户输入两个数实现两个数相加,如例2所示。

例2

 1    #include <iostream>
 2    using namespace std;
 3    int main()
 4    {
 5        int num1, num2;
 6        cin >> num1 >> num2;
 7        cout << num1 << "+" << num2 << "=" << num1 + num2 << endl;
 8        system("pause");
 9        return 0;
 10    }

运行结果如图2所示。

图2 例1-2运行结果

在例2中,用cin连续输入两个整数,cout输出两值相加结果的表达式,关于cin与cout的用法很简单,关于它的定义将在后面I/O流中讲解,这里读者只需能够使用即可。

点击此处
隐藏目录