C++ 系列 第三篇 C++程序的基本结构

 系列文章

C++ 系列 前篇 为什么学习C++ 及学习计划-CSDN博客

C++ 系列 第一篇 开发环境搭建(WSL 方向)-CSDN博客

C++ 系列 第二篇 你真的了解C++吗?本篇带你走进C++的世界-CSDN博客

本章概述

        从本章开始正式进入C++的学习, 就像要建造房屋,首先要打地基、搭框架一样,学习计算机语言时,应从程序的基本结构开始学起。只有这样,才能一步一步了解其具体细节。上一章我们从框架方面说明了C++是什么及主要特性(根据特性基本可以推断使用场景), 本章则会对 C++程序的基本结构进行概述,从头文件包含、main 函数、基本得输入输出 等方面进行入门学习。学完本章后的目标是,拿出一段C++代码,即使不知道在功能方面具体干了啥(代码可能引用了不同的名称空间,我们开始并不了解,也可能有不同的上下文),但是能从代码 结构上知道 每一段代码大概是要实现什么。

进入C++

        如下是C++ 书籍上的一个入门示例,该示例我们一眼看过去和C 代码的 结构结构一致,但是还是有一些不一样的地方,比如 1)引用的头文件没有用“.h” 结尾;2) main 函数中开头 有一句 “using namespace std” 我们并不知道是什么,但是可以看到 std 字样,可以联想到C 代码的 标准库; 3)有好几个 cout << "" 语句,我们并不认识,但是我们在C 里 "<<" 这个是左移符号, C++是C的超集, 理论是要兼容C 的,那这里是在移位吗,明细不是,更新是输出。

        我们带着这些疑问,来逐行的分析下这个代码。 

// myfirst.cpp--displays a message

#include                            // a PREPROCESSOR directive
int main()                                    // function header
{                                             // start of function body
    using namespace std;                      // make definitions visible
    cout << "Come up and C++ me some time.";  // message
    cout << endl;                             // start a new line
    cout << "You won't regret it!" << endl;   // more output
// If the output window closes before you can read it,
// add the following code:
    // cout << "Press any key to continue." <

示例代码逐行分析

part 1: 注释

// myfirst.cpp--displays a message 

        这一行及后续每行 “//” 打头部分, 都代表注释,C++注释以双斜杠(//)打头,到行尾结束,注释可以位于单独的一行上,也可以和代码位于同一行。注释是程序员为读者提供的说明,通常标识程序的一部分或解释代码的某个方面,编译器会忽略注释。

        程序越复杂,注释的价值越大。注释不仅有助于他人理解这些代码,也有助于程序员自己理解代码,特别是隔了一段时间没有接触该程序的情况下。

        当然也不用死板教条,不是说说每个函数,每句代码都需要写注释,以个人观点来说,如果代码的能自注释是最好的,比如在一个求矩形面积的函数中,矩形边长用变量a表示, 别人不知道这代表什么,但是如果命名为rect_length,即使没有注释,我们也知道这个是要表达矩形的边长。

        有一种情况下是必须要加注释的,即函数的逻辑具有一定得复杂性,那这种情况下,需要给函数添加注释,说明函数的目的及输入输出,如果能说明函数的主要逻辑点就更好了。

        有一点说明,C++也能识别C注释 “/* */”, 即C 及 C++ 都支持 “//”  和 “/* */” 两种风格的注释。

part 2:include 编译指令

#include

        C++和 C 一样,也使用预处理器,程序在进行编译之前会对源文件进行预处理(有些 C++实现使用翻译器程序将C++程序转换为 C 程序。虽然翻译器也是一种预处理器,但这里讨论的不是这种预处理器,而是以#开头的编译指令所指示的预处理器)。不必执行任何特殊的操作来调用该预处理器,它会在编译程序时自动运行。  

       #include编译指令导致iostream 文件的内容随源代码文件的内容一起被发送给编译器。实际上,iostream 文件的内容将取代程序中的代码行#include 。原始文件没有被修改,而是将源代码文件和 iostream 组合成一个复合文件,编译的下一阶段将使用该文件。

        为什么要将 iostream 文件的内容添加到程序中呢?答案涉及程序与外部世界之间的通信。iostream 中的io 指的是输入(进入程序的信息)和输出(从程序中发送出去的信息)。C++的输入/输出方案涉及iostream 文件中的多个定义(例如我们下边要介绍到的cout),我们要输出信息,那就需要iostream中定义的功能。

        使用 cin 和cout 进行输入和输出的程序必须包含文件iostream。那我们联想一下,如果我们想使用C++的其他库函数,必然要在我们的源代码文件中包含对应的头文件,那我们平常看代码,看源代码文件引用的头文件也可以大概推断,代码中做哪一些类型的操作。

 为什么没有“.h”

         是否还记得我们上边的疑问,示例代码中的 头文件为什么没有“.h” 结尾?

        C 语言的传统是,头文件使用扩展名 h,将其作为一种通过名称标识文件类型的简单方式。例如,头文件math.h支持各种C语言数学函数,但C++的用法变了。现在,对老式C的头文件保留了扩展名h(C++程序仍可以使用这种文件),而C++头文件则没有扩展名。有些C头文件被转换为C++头文件,这些文件被重新命名,去掉了扩展名 h(使之成为 C++风格的名称),并在文件名称前面加上前缀c(表明来自C语言)。例如,C++版本的 math.h 为 cmath。有时 C 头文件的 C 版本和C++版本相同,而有时候新版本做了一些修改。对于纯粹的 C++头文件(如iostream)来说,去掉 h不只是形式上的变化,没有 h 的头文件也可以包含名称空间。(稍后讲到什么是名称空间,我们在开头也捎带提了下)。以下是头文件引用的不同说明。

C++ 系列 第三篇 C++程序的基本结构_第1张图片

名称空间 

        如果使用 iostream,而不是iostream.h,则应使用“using namespace std;” 名称空间编译指令来使iostream 中的定义对程序可用,这叫做 using 编译指令。

        名称空间支持是一项C++特性,旨在编写大型程序以及将多个厂商现有的代码组合起来的程序时更容易。一个潜在的问题是,可能使用两个已封装好的产品,而它们都包含一个名为wanda()的函数。这样,使用wanda()函数时,编译器将不知道指的是哪个版本。名称空间让厂商能够将其产品封装在一个叫做名称空间的单元中,这样就可以用名称空间的名称来指出想使用哪个厂商的产品。因此,Microflop Industries 可以将其定义放到一个名为Microflop 的名称空间中。这样,其 wanda()函数的全称为Microflop::wanda() ;  同样,Piscine 公司的wanda()版本可以表示为Piscine::wanda()。这样,程序就可以使用名称空间来区分不同的版本了。

        之前没学C++的时候,clickhouse 挂了,看堆栈一堆  XX::bb(), 现在知道是啥了,(^-^)V

        按照Microflop::wanda() 这种方式,类、函数和变量便是C++编译器的标准组件,它们现在都被放置在对应的名称空间中, 我们示例代码中 的count 便是 std 名称空间的一个函数组件,仅当头文件没有扩展名h 时,情况才是如此,这意味着在iostream中定义的用于输出的cout 实际上是std::cout, endl 实际上是std::endl,因此也可以省略编译指令using, 以“std::cout << "come up" ”这种方式进行编码。

        using编译指令有两种用法,一是直接向示例代码 一样,using namespace std; 使得std名称空间中的所有名称都可用。这是一种偷懒的做法,在大型项目中是一个潜在的风险。二是只使所需的名称可用,如 using std::cout 。

part  3 :使用cout进程C++输出

cout << "Come up and C++ me some time."; 

cout << endl; 

cin.get(); 

        line 2 的讲解,如果看明白了的话, 这里的输出就好理解了。

        双引号括起的部分是要打印的字符串消息。“<<” 符号表示该语句将把这个字符串发送给 cout。“<<” 符号指出了信息流动的路径。cout我们上边说过了,是std名称空间里的一个对象,它知道如何显示字符串、数字和单个字符等。

        还记得我们开始提的第三个疑问吗,C++兼容C,那这里的“<<” 为什么是插入运算符 而不是 左移运算符呢?这其实是一个运算符重载的例子,通过重载,同一个运算符将有不同的含义。编译器通过上下文来确定运算符的含义。C 本身也有一些运算符重载的情况。例如,&符号既表示地址运算符,又表示按位 AND 运算符; *既表示乘法,又表示对指针取值。这里重要的不是这些运算符的具体功能,而是同一个符号可以有多种含义,而编译器可以根据上下文来确定其含义。C++扩展了运算符重载的概念,允许为用户定义的类型(类)重新定义运算符的含义,这个后续学到了再说。

       示例代码中还有两个比较特殊的, endl 和 cin.get, 我们分别说下含义:

       endl 是一个特殊的C++符号,表示一个重要的概念:重起一行。在输出流中插入 endl 将导致屏幕光标移到下一行开头。诸如endl 等对于cout 来说有特殊含义的特殊符号被称为控制符(manipulator)。和 cout一样,endl 也是在头文件 iostream 中定义的,且位于名称空间 std 中。打印字符串时,cout 不会自动移到下一行,因此想要换行重启输出其它字符串需要中间插入一个endl。当然,C++还提供了另一种在输出中指示换行的旧式方法:C 语言符号\n,可以这样写 "cout <<"What's next?\n"; ,同样能起到换行的效果。显示用引号括起的字符串时,通常使用换行符\n,在其他情况下则使用控制符 endl。

        cin.get 则是对于有些程序,要让窗口一直打开,直到按任何键,就必须添加这个,像示例代码中一样    cout << "Press any key to continue." <

part 4 :程序其他部分

int main() 
{
    return 0;
}

        这部分没什么可说的,和C语言一样,定义了一个函数,有函数名, 输出及对应的返回,及{}包含的函数体部分,同时语句和c代码一样 以分号结尾, 关键字 和 常量 或者 类型和 名称之前用空格或者tab 分割。

总结

        到这里应该对c++代码的基本结构有所了解了,标准库该怎么引用,库中的函数该怎么使用,函数该怎么定义 这些都有了基本得概念了,后续再学习示例代码 或者直接看开源代码 也应该有一些指导方针了。

你可能感兴趣的:(C++,c++,开发语言,c语言)