第2部分 与C++第一次亲密接触ios
在浏览了C++“三分天下”的世界版图以后,便对C++有了基本的了解,算是一只脚跨入了C++世界的大门。那么,怎样将咱们的另一只脚也跨入C++世界的大门呢?是该即刻开始编写C++程序?仍是……程序员
正在咱们犹豫的时候,便看到前面有一我的被一群满头问号的C++初学者围在当中。咱们赶忙挤进去一看,噢,原来是一个C++程序正作自我介绍呢。算法
“你们好,欢迎来到奇妙的C++世界。我是C++世界的迎宾——一个最简单最普通的C++程序,个人名字叫“HelloWorld.exe”。我虽然简单而普通,但却几乎是这个世界上最著名的C++程序。每一个来到C++世界的初学者与C++的第一次亲密接触都是经过我来完成的。你们在听我介绍以前,必定会以为C++程序很是神秘,好比,C++程序是如何建立的?一个完整的C++程序由哪几部分构成?传说中的源文件究竟是什么文件?C++程序是如何执行的?其实,咱们C++程序一点都不神秘,跟你们同样,咱们有本身的老爸老妈,有本身的五官四肢,也有本身的生命过程。什么?你们以为难以想象?别着急,下面且听我一一道来……”框架
你们进入C++世界最感兴趣的第一件事,就是亲自动手建立一个C++程序。大多数C++程序都是经过一种叫作集成开发环境(Integrated Development Environment,IDE)的软件建立的,能够说,它是建立C++程序的工厂。虽然能够用于建立C++程序的集成开发环境有不少,可是咱们首选的仍是由微软公司开发的Visual Studio。做为一款通过二十多年不断发展而来的集成开发环境,Visual Studio拥有多种功能各异的版本:有适用于大规模团队开发的旗舰版,也有适用于我的开发的专业版,还有免费的快速版。若是咱们只是想利用Visual Studio进行C++的学习,咱们可使用其中的Visual C++ Express版本。它不只功能齐备,并且小巧。更重要的是,它是免费的,咱们能够从微软的网站免费下载安装。Visual Studio是Windows平台上最经常使用的开发环境,至于其它的开发工具以及Linux平台上的开发工具,请你们参考后文的2.3小节。函数
如今,请你们在个人引导下,一步一步地使用Visual Studio建立咱们的第一个C++程序。第0步,新建项目。从开始菜单找到已经安装好的Visual Studio并点击启动。当第一次启动Visual Studio时,它会要求咱们选择界面布局设置,这里咱们选择适用于Visual C++的布局设置,而后通过片刻的等待就能够看到Visual Studio华丽丽的起始页了。在Visual Studio中,咱们全部的开发工做都是在某个项目中进行的,因此咱们利用Visual Studio编写程序的第一步就是建立用于管理程序文件的项目:单击起始页左侧的“新建项目”,在弹出的“新建项目”对话框中,选中左侧树状图中的“Visual C++”节点,而后在右侧的项目类型列表中选中“空项目”这个项目模板,接着在对话框下方输入项目名称“HelloWorld”并选择项目存放的位置,最后点击“肯定”按钮,就完成了新项目的建立。工具
图2-1 新建项目布局
第1步,添加源文件。新项目的建立,只是搭起了一个空的框架,还等着咱们向其中添加一些实质的内容。在左侧的“解决方案资源管理器”中,找到“HelloWorld”项目下的“源文件”分支,而后右键单击“源文件”分支,在弹出的菜单中依次选择“添加->新建项”,就能够获得“添加新项”对话框。在“添加新项”对话框中,选中左侧树状图中的“Visual C++”分支,而后在右侧文件类型列表中选中“C++文件”,接着在对话框下方将文件名称修改成“HelloWorld.cpp”,最后点击“肯定”按钮,Visual Studio就会为咱们新建一个HelloWorld.cpp源文件并添加到项目中。学习
图2-2 添加源文件开发工具
第2步,编辑代码。有了空白的源文件,就至关于画家支好了画板,做家摆好了稿纸,就等着咱们开始编写代码了。在已经被打开的HelloWorld.cpp文件中,咱们编辑以下的代码(这里值的特别提醒的是,其中的标点都应该是英文的):网站
#include <iostream> using namespace std; int main() { // 在屏幕输出“Hello World!”字符串 cout<<"Hello World!"<<endl; return 0; }
图2-3 编辑代码
第3步,编译执行程序。代码编辑完成以后,咱们就能够编译并执行这个程序向C++世界打个招呼了。这一步能够经过菜单命令“调试->开始执行(不调试)”来完成,但更多时候,咱们经过Ctrl+F5快捷键来完成。当咱们按下快捷键以后,Visual Studio会编译项目当中的源文件,若是源文件中没有错误,它就会生成相应的HelloWorld.exe可执行文件,随后会启动执行这个程序,从而在DOS窗口打印出一个“Hello World!”字符串向C++世界打招呼。
图2-4 Hello World!
最佳实践:等一下,等一下,我还没看清输出结果呢!
当咱们在Visual Studio中执行某个程序时,若是这个程序在执行过程当中不须要与用户进行交互,那么它执行时打开的DOS窗口会在其执行完毕后当即关闭。若是这个程序有结果输出,咱们甚至来不及看清程序的输出结果。一个程序执行完了,连输出结果都来不及看清这怎么行呢?
为了解决这个问题,咱们能够在程序的主函数返回以前加上一条“system("pause");”语句。例如:
int main() { // … // 让程序在结束以前暂停 system("pause"); return 0; }
加上这条语句后,程序会在执行完毕以前暂停,这样,咱们就有足够的时间看清程序的输出结果了。天然,这条语句也还能够用在程序执行过程当中那些须要暂停的地方,以此来提升程序的可交互性。
另一种查看程序输出结果的方法,就是先启动DOS窗口,而后DOS窗口中手动地执行咱们的应用程序。在这种方式下,DOS窗口并不会在程序执行完毕后关闭,因此咱们也有时间查看程序的输出结果。
通过这样四个简单的步骤,咱们就轻松编写了咱们的第一个C++程序,完成了与C++的第一次亲密接触。除了借助Visual Studio建立C++程序以外,咱们甚至还能够采起纯粹手工的方式建立C++程序。但不管何种方式,它们的基本流程都是同样的。若是使用Visual Studio方式,由于有开发工具的帮助,上手容易开发效率也会比较高。而若是是使用手工方方式,则能够对整个开发过程进行灵活定制,从而知足咱们一些个性化的需求。对于初学者而言,手工方式稍显复杂。最佳的学习路线应该是,先以Visual Studio方式入门,等到有了必定的基础,须要对程序的编写过程有更精细控制的时候,再改用手工方式。这样才不至于在入门阶段就被复杂的手工方式困住了脚步,而在进阶后又受到开发工具的限制。
麻雀虽小,五脏俱全。你们别看我个头小,只有短短的几行代码,实现的功能也很简单,可是我一样拥有C++程序的“五官和四肢”:预编译指令、程序代码和注释,如图2-5所示。大多数状况下,这三个基本组成部分都被放在一个扩展名为“cpp”的文本文件中,这个文件被称为C++ 源文件。源文件记录了个人“五官和四肢”,规划了个人人生。源文件的编写者就是个人设计师了。经过修改源文件,能够改变个人面貌、个人人生轨迹,让我完成各类任务,实现各类功能。
图2-5 C++程序=预编译指令+程序代码+注释
下面,你们一块儿来看看个人源文件,从中认识个人“五官和四肢”。
在源文件中,以“#”开始的内容就是预编译指令。它的做用是告诉编译器,让它在真正进行编译以前对源文件进行一些插入文件、替换字符串等预处理,以获得最终参与编译的源文件。例如,在个人源文件HelloWorld.cpp中,第一行就是一个插入文件的预编译指令:
#include <iostream>
其中,“#include”指令用于将指定的文件插入该指令所在的位置,做为整个源文件的一部分。由于这样的文件老是在一个源文件的头部被插入,因此咱们一般将这样的文件称为头文件(header file)。在这里,咱们插入了“iostream”这个头文件,这是由于咱们在程序中须要用到其中定义的cout和endl来完成输出(关于C++的输入输出,能够参考后文2.2小节的介绍)。须要注意的是,“#include”指令后的文件名有两种表示方式:若是使用双引号""来包围一个文件名,则预处理器在处理这个指令的时候,将首先在当前目录(也就是这个源文件所在的目录)下搜索这个文件,若是不存在,则继续在项目的包含目录(包括项目的默认头文件目录,也就是Visual Studio安装目录下的“\VC\include”文件夹,以及在项目属性中设置的项目附加头文件目录)下搜索这个文件;而若是使用尖括号<>来包围一个文件名,预处理器则会直接在项目的包含目录下搜索这个文件。因此,一般咱们使用""来插入当前项目目录下的头文件(好比咱们本身建立的头文件),而使用<>来插入各类项目包含目录下的库头文件(好比这里的iostream)。这里值得再次提醒的是,代码中使用的全部标点符号(这里使用的尖括号,也包括后面代码中用到的双引号、逗号、分号等)必须是英文的。某些中英文符号很是类似,很容易被初学者搞混淆而引发编译错误,这一点尤为值得初学者注意。
程序代码主体由若干C++语句(一般以分号结束的一行代码就是一条语句)构成,能够说语句是构成程序的基本单位。在个人源文件中,第一条C++语句是:
using namespace std;
这条语句表示我所使用的名字空间是std。所谓名字空间,就是程序中各类标识符(好比这里的cout和endl,咱们经过这些符号来访问程序中的各类元素,实际上也能够说是这些元素的名字,因此这些符号也被称为标识符)所在的范围,更具体的能够参考7.3.2小节关于名字空间的介绍。在C++中,任何标识符都被定义在某个名字空间中,而同一个标识符也能够在多个名字空间中同时定义。这就像张家村有一我的叫陈良乔,而李家村也有一我的叫陈良乔同样,你们在称呼“陈良乔”这我的的时候,为了表达清楚,咱们必须在名字前加上一个前缀,称之为“张家村的陈良乔”或是“李家村的陈良乔”。C++中的名字空间就至关于这里的“张家村”、“李家村”。在这里,咱们在后面代码中使用的cout、endl都是来自std这个村的,因此咱们用这条语句告诉编译器,若是遇到没有加前缀的标识符(好比,这里的cout),能够到std村去找找看,若是能找到,那就是它了(结果,在std村里找到了std::cout)。C++的大多数内容都定义在std这个名字空间中,因此,不少时候咱们都须要在代码中使用这条语句引入std名字空间。固然,若是不使用这条语句,咱们也能够在标识符的前面直接加上名字空间的前缀,明确地表示这是来自于某个名字空间的标识符(在代码中,使用 std::cout代替 cout,用std::endl代替endl)。
接下来的一条语句是:
int main()
这条语句连同它后面大括号内的内容,共同构成了main()函数,也称为主函数。所谓函数,是C++程序中最基本的一个组织单元,它把若干条语句组织到一块儿共同实现某个功能。若是说一条语句至关于人体的一个细胞的话,那么函数就至关于由若干细胞构成的拥有必定功能的器官。而这里的主函数就是一个程序中最重要的“器官”。一个C++程序必须有一个主函数,且只能有一个主函数。当C++程序开始执行的时候,将首先进入主函数,而后逐条地执行其中的语句,直到其中的语句执行完毕退出主函数,程序执行也就宣告结束。能够说,主函数定义了一个C++程序的一辈子。
知道更多:为何一个C++程序必须有且只能有一个main函数?
当咱们双击执行程序后,执行程序的进程会首先建立主线程,主线程而后调用约定启动运行时库,由启动运行时库调用约定好的main函数,自此开始执行用户的代码。main函数是主线程的执行入口,因此一个C++程序必须有一个main函数。
同时,一个线程不可能拥有多个执行入口。并且在C++中,全局符号(变量、函数) 只能有一个定义。main函数做为一个全局函数,天然也就只能有一个。
接下来的就是主函数中的一条语句:
cout<<"Hello World!"<<endl;
cout是定义在头文件“iostream”中的一个输出流对象,它是C++标准库预约义的对象,一般用于将文字或数字输出到屏幕。前面使用“#include”预编译指令包含“iostream”头文件就是为了在代码中使用这个对象。关于输入/输出流,会在之后的章节中作更详细的介绍,这里只要知道这条语句能够将“Hello World!”这串文字输出到屏幕上便可。值得再次提醒的是,这里的双引号也必须是英文的。
个人最后一条语句是:
return 0;
它表示程序成功执行完毕并返回(return)。一般,咱们返回一个0值表示程序成功执行(若是在程序的执行过程当中出现错误,也能够返回表示错误信息的其余数值。程序的执行者能够接受这个返回值以判断程序是否成功执行)。到这里,主函数中的语句执行完毕,而个人一辈子也到此终结。
注释是源代码的编写者为了帮助代码的阅读者(代码后期维护人员,也包括编写者本身)更好地理解代码,而在代码中写下的关于某一行或某一段代码的一些解释性文字。虽然源代码中的注释并不会参与最终的编译,不会对程序的功能产生影响,但它会提升代码的可读性,为后期的维护带来极大的便利。例如这里的:
// 在屏幕输出“Hello World!”字符串
就是一条注释,它解释了接下来的一条语句的做用,从而可让咱们对代码有更好的理解。
在形式上,C++中的注释能够分为单行注释和块注释两种。“//”是单行注释符,“//”以后直到换行的全部内容都属于注释。由于内容只有一行,因此它经常用来对代码做简短的解释。例如上面的注释就是一个典型的单行注释。
C++中的块注释咱们用一对“/*”和“*/”表示,凡是出如今这对符号之间的全部内容都属于注释。由于它能够包含多行内容,当咱们须要对代码作详细解释的时候,可使用块注释。例如:
/* 这是一段注释 */
在功能上,注释通常分为序言性注释和解释性注释。序言性注释多位于程序源文件的开始,用来讲明程序的文件名、用途、编写时间、维护历史等。在上面的例子中,咱们能够在源文件的第一行加上一个序言性注释来解释这个源文件的功能:
// HelloWorld.cpp:在屏幕输出“Hello World!”字符串
序言性注释被普遍用于大型的项目中。一般,每一个项目都有本身定义的序言性注释格式,用来向代码的阅读者说明一些必要的信息。下面是从一个实际的项目中摘录的一段序言性注释,它说明了源文件的名字、做用、文件的修改历史等信息,帮助阅读者更好地理解代码。你们能够以此为模板,编写适合于本身的序言性注释。
/////////////////////////////////////////////////////////////////////// // AppDataView.cpp : implementation file // //CAppDataView // This view is designed to display the App Data // // Version: 2.1 // Date: September 2001 // Author: Chen Liangqiao // Email: chenlq@live.com // Copyright (c) 2002. All Rights Reserved. // // History: /* 27.09.2001 Chen Liangqiao Added OnCreate(), OnUpdate(): Added usage of mesh tracer layers Added bugfix for Graphics zoom error 30.10.2001 Chen Liangqiao Changed order of MPR View only in _TORCHTONAV 08.11.2001 Zeng Me Added EUpdateReason, used for UpdateAllView(), Added voxel trafo Changed the control panel due to new CTestCtrl */ ///////////////////////////////////////////////////////////////////////
与序言性注释多位于源文件开始部分不一样,解释性注释多分散于源代码的各个部分,用来向代码阅读者解释代码的含义,说明一些必要的问题等。例如,上面例子中的注释:
//在屏幕上输出“Hello World!”字符串 cout<<"Hello World!"<<endl;
这句解释性注释就是用来向代码阅读者说明其下代码的功能是输出字符串“Hello World!”。
最佳实践:什么是好的注释
虽然程序的注释并不影响程序功能的实现,编译器也不会去阅读咱们的注释,可是好的注释却能够增长程序代码的可读性,使程序更易于维护。谁都不肯意维护一份没有注释的代码,那无异于阅读天书。那么,什么样的注释才算是好注释呢?
首先,该注释的地方必定要注释。
注释是对代码的“提示和说明”,是为了帮助代码的阅读者更好地理解代码而存在的。当咱们认为代码不能被“一眼看穿”而须要加以解释,或者是代码须要特别说明的时候,就应该添加注释,加以额外的解释和说明,帮助阅读者理解代码。例如:
// 判断某个浮点数是否近似整数 bool is_int(double d) { // 用浮点数d减去其整数部分(int)d,得到其小数部分 double s = d - (int)d; // 判断小数部分是否在偏差范围内 if(s > 0.000001) return false; else return true; }
这里的注释,恰当地对比较难以理解的代码进行了解释(若是没有注释,很难一会儿就理解“double s = d - (int)d;”这行代码的含义究竟是什么),提升了代码的可读性。
其次,不应注释的地方最好不要注释。
注释仅仅是对代码的“提示和说明”而已,若是代码自己已经可以很好地作到“望文生义”,也就没有必要“多此一举”地加以注释了。另外须要注意的是,注释只是简短的说明性文字,不是详尽的文档。程序的注释不可喧宾夺主,注释过多会让人眼花缭乱,反而下降了代码的可读性。例如,下面代码中的注释就不太合适:
// 判断某个浮点数是否近似整数 // 其参数是表示输入的浮点数d // 其返回值是一个表示是否近似的bool值 bool is_int(double d) { // 用浮点数减去其整数部分,得到其小数部分 // 其中,d表示浮点数,(int)d表示浮点数的整数部分 double s = d - (int)d; // 判断小数部分是否在偏差范围内 if(s > 0.000001) return false; // 小数部分大于偏差范围,则表示浮点数不近似整数,返回false else return true; // 小数部分小于偏差范围,则表示浮点数近似整数,返回true }
这段代码中的注释,对一些含义很是浅显易懂的代码也进行了详尽的解释,注释的内容远超过了代码的内容,这样不但没有增长代码的可读性,反却是让代码淹没在了复杂的注释中,反而下降了代码的可读性。这样的注释实属“多此一举”画蛇添足。
另外,应该养成良好的代码注释习惯。编写代码时添加必要的注释,修改代码时修改相应的注释,删除无用的注释,保证注释与代码的一致性。
注释应当准确、易懂,避免二义性。错误的注释不但无益反而有害。
注释的位置应与被描述的代码相邻,能够放在代码的上方或右方,不可放在下方。例如:
// 在屏幕输出“Hello World!”字符串 // 对下方的代码进行注释 cout<<"Hello World!"<<endl; int n = 1024; // 循环次数,对左侧代码进行注释
若是代码比较长,特别是有多重嵌套时,应当在某些段落的结束处加以注释,以便于查看嵌套结构的起始和结束位置。例如,一个多重循环的代码及其注释以下:
for ( int i = 0; i < 100; ++i ) { for ( int j = 0; j < 100; ++j ) { // 算法处理... } // j循环结束 } // i循环结束
程序代码不只仅是写给编译器看的,它更是写给程序员本身或者他人看的。对于编译器来讲,代码中有没有注释无所谓,然而对于阅读代码的程序员来讲,合适的注释能够很大程度上提升代码的可读性,让代码更易于维护。于是,注释是C++程序代码中必不可少的一部分,而程序代码中是否包含合适的注释,也成为衡量一个程序员是否优秀的标准。
预编译指令、程序代码与注释共同构成了个人“五官与四肢”,但这时候我还只是一个后缀为cpp的文本文件,而要获得最后的可执行的exe文件,还得靠个人父亲母亲:编译器和连接器。