3. C++初学者指南:从简单程序到语法解析

一、前言

开发环境搭建属于非常基础的内容,同时由于其它文章我也已经讲过了,所以这里不再赘述,不会的可以参考本站另外一篇文章:初识C++

一个最简单的C++程序如下:

#include<iostream>					//预处理器指令
using namespace std;				//使定义可见
int main()							//函数头
{									//函数体的开始    
	cout << "hello world";			//打印数据
	cout << endl;					//换行
	cout << "C++ www.kucoding.com"; //再次打印数据 
	return 0;						//结束main函数
}									//函数体的结束

将上面的代码运行后,就会输出下面这样的内容:

image-20231113055718823

上面的代码虽然简单,但却包含了很多基本的元素:

  1. 注释:以//作为标识
  2. 预处理器指令:#include
  3. 函数头:int main()
  4. 编译指令:using namespace
  5. 函数体:用{}括起来
  6. 使用C++的cout工具显示消息的语句
  7. 结束main函数的return语句。

二、main函数

上面的代码很简洁,但还并不是最简洁的:

int main()							//函数头
{									//函数体的开始    
	return 0;						//结束main函数
}									//函数体的结束

上面这简单的几行表明了有一个名为main的函数,并描述了该函数的行为。

其主要构成了一个函数定义,函数定义由两部分组成,其中int main()叫做函数头,花括号 {} 中的内容叫做 函数体

  1. 函数头:总结了该函数与程序其它部分的接口
  2. 函数体:指出这个函数应该做什么的计算机指令,每条完整的指令都称为语句,所有语句都以英文分号结束

而放在最后的那条语句叫做返回语句,它用于结束该函数,并且很多时候也并不需要写在所有语句的最后,只要函数执行到它,就会立刻结束。

语句是要执行的操作,编译器需要知道每条语句什么时候结束,C/C++中采用的就是英文分号(;)作为语句的结束,这取决于语言本身的定义,比如python用的是换行作为语句的结束。

main函数则比较特殊,即使你不写return这个返回语句它也不会报错,这是编译器做出的妥协,你不写并不代表没有,只是编译器会自动给我们补上而已。

上面的作为接口的函数头可能会让人感到疑惑。

如果仅从入门而言,现在你只需要记住一点:C++语法要求main函数的定义以int main()开始,后面的文章也会继续探讨函数的相关内容。

但这里也可以稍微预览一下。

一般来说,C++函数会被其它函数调用,而函数头就描述了这个函数与调用它的函数之间的接口。

image.png

位于函数名main前面的部分叫做函数返回类型,也就是这里的int,它描述的是函数返回给调用者的信息,比如int就代表着将要返回一个整数。

而函数名后面小括号中的部分叫做形参列表或者参数列表,它描述了调用函数传递给被调用函数的信息,这不过这里main函数内暂时没有写,也就是它不接受任何参数。

虽然我们没有主动去调用这里的main函数,但它会被启动代码自动调用,而启动代码是由编译器自动添加到程序中的,它是程序和操作系统之间的桥梁,正常情况下我们是无需理会的。

三、注释

C/C++中注释是以//打头的,注释对于程序本身来说是可有可无的存在,它存在的唯一目的是为程序员提供说明的。

比如一段代码有什么用,一般就会添加一个注释信息,如果其它程序员以后需要使用这段代码,也能很容易的从注释信息中明白这段代码是干嘛的。

而对于编译器而来,它会直接忽略掉注释,前面添加了注释的代码在编译器眼中就像下面这样:

int main()
{    
	return 0;
}			

对于越复杂的程序,注释的价值就会越发重要,因为它有利于其他人理解这些代码。

同时用//写注释信息主要用于简单说明的情况下,如果你需要写大量的注释,比如需要用到多行,那可以使用另一种注释方案:/*注释内容*/

它也是注释写法的一种,优点就是可以换行:

/*
注释信息
注释信息
注释信息
*/

四、预处理器

如果程序想要使用C++输入、输出功能,那就得要写上这两行代码:

#include<iostream>
using namespace std; //可用其它语句替换

C++和C一样,也使用预处理器,其作用是在编译前对源代码进行处理,比如去除掉注释信息之类的。

而这里的#include被称为编译指令,它的作用就是调用预处理器,会在编译程序的时候自动执行。

这里的#include<iostream>的作用就是,将iostream这个文件中的内容,也就是代码,替换到这个位置。

那么为什么要将这个文件中的内容替换到这里呢?

因为我们想要在程序中输入输出就得使用一些工具,而这些工具就被定义在了iostream这个文件中,比如前面使用过的cout,就在这个文件中。

iostream单词中的ioinputoutput的缩写,即输入输出的意思,而stream则是流的意思,这个涉及到了C++的设计理念,这里先不提了。

总结来说就是,#include<iostream>这句指令完成了这样一个目的:将iostream文件中的内容拿过来取代#include<iostream>,然后将我们写的源代码文件和iostream文件组合成一个复合文件,一起参与后续的编译过程。

五、头文件

iostream这样的文件有很多,它们是在我们下载安装C++编译器后自动下载下来的,属于官方写好的代码。

除了用官方写好的,当然我们也可以自己写,只是会比较麻烦而已。

这样的文件叫做包含文件,因为它们通常被包含到其它文件中使用,同时也被称为头文件,因为它们常被包含到文件起始位置。

C语言的传统是在头文件名字后添加后缀名.h,但C++的用法变了,不再需要添加后缀名,只要文件名即可。

比如C语言中的math.h等等,在C++中被去除了后缀名.h,同时前面添加了c,也就是cmath

主要有以下几种:

头文件类型 约定 示例 说明
C++旧式风格 以.h结尾 iostream.h C++程序可以使用
C旧式风格 以.h结尾 math.h C、C++程序可以使用
C++新式风格 没有扩展名 iostream C++程序可以使用
转换后的C 加上前缀C,没有扩展名 cmath C++程序可以使用

六、名称空间

如果使用iostream而不是iostream.h,那就需要使用名称空间编译指令来使得iostream中的定义对程序可用:

using namespace std;

这叫做using编译指令,最简单的方式就是这里先记住它,以后再慢慢理解,不然可能会让你感到困惑。

使用它的目的在于尽量避免命名冲突,比如一个用于操作时间的代码,里面写有几个相应的函数,而常用的函数名其实就那么几个:get_timeget_local_time之类的。

那么此时一旦程序变大、参与的人变多,就很容易出现问题,比如两个人用了同一个函数名,这会导致编译器不知道你应该调用哪个函数而出错。

graph TD
	A[程序员A]--写了函数名get_time-->C[代码合并]
	B[程序员B]--写了函数名get_time-->C
	C-.函数名冲突无法链接.->D[链接]

名称空间的作用就在于此,它可以让你将其包含在一个局部空间内。

graph TD
	A[程序员A]--在命令空间A中写了函数名get_time-->C[代码合并]
	B[程序员B]--在命令空间B中写了函数名get_time-->C
	C--此时两个get_time函数分别在空间A与空间B中,不冲突-->D[链接]

具体写法以后再详细介绍,这里我们只需要知道所有的官方内容,都被添加到了std这个名称空间中,stdStandard的缩写,即为标准的意思。

想要使用这里面的东西,一般有三种办法。

第一种最直接的方式就是将其全部引入:using namespace std;

一旦使用了这条语句,那么std内的东西都可以直接用了,比如cout也是它里面的东西。

但这样做其实只适用于学习阶段,比如如果用到多个名称空间,这样写就完全发挥不出名称空间应用的作用了:将所有名称空间内的东西都暴露出来,仍就有可能导致命名冲突。

另一种更好的方式是用哪个,就引入哪个:using std::cout;

这种写法可以让你后续直接使用cout,但其它的想要用也得分别这样就行引入。

而最后、可能最麻烦,但也最稳妥的方式是,带着名称空间一起使用:

std::cout<<"hello world";

这样写稍显麻烦,但却能精确的表达我需要用哪个名称空间内的哪个东西,符号::你可以直接理解为,也就是stdcout

七、cout输出

一句简单的打印指令为:

cout<<"hello world,www.kucoding.com";

后面用英文双引号""括起来的就是要打印的消息。

在C++中,双引号括起来的一系列字符叫做字符串,因为它是由若干字符组成的。

而符号<<你可以将其直接理解为发送的意思,也就是将这个字符串发送给cout,这涉及到了C++中的思想,也就是iostream文件名中的stream,意为输入输出流。

因为它可以让你像流水一样,不断的在其后面追加:

cout<<"hello world"<<"www.kucoding,com";

并会从左到右依次将其打印到控制台上,将其抽象一下,看起来是不是就是流水一样?

而前面使用的endl以及上图字符串中的\n的作用都是换行,也就是另起一行打印字符串。

这种对cout来说有特殊含义的符号被称为控制符endl同样处于std中,至于\n,则是C遗留下来并一直沿用的换行方式。

\n这个整体被视为了一个字符,名为换行符,这样的符号被统称为转义序列,后面会提到。

两者唯一的区别就是,endl换行会立即将前面进入cout中的内容打印到控制台上,而\n没有这样的保证。

八、代码格式

由于C++本身是以;作为语句的结束,所以这代表它的写法是可以非常随意的:

image.png

这种随意的代价就是,让我们很难理解这段代码是干嘛的。

所以为了保持代码的简洁好看,一旦都是采用的每行一条语句:

image.png

如果一条语句太长,也可以分行写:

image.png

九、简单练习

1.阅读下面程序,在运行它的情况下猜测其实现的功能,然后将其复制到vs中运行试一试?

#include <iostream>  
  
int main()  
{  
    int x = 8;  
    int y = 6;   
    std::cout << x - y << " " << x * y << " " << x + y << std::endl;  
    return 0;  
}

2.下面程序存在什么样的错误?复制到vs中看能不能将其修复?

include <iostream>  
  
int main()  
{  
    std::cout << "Hello Buggy World\n";  
    return 0;  
}
作者:余识
全部文章:0
会员文章:0
总阅读量:0
c/c++pythonrustJavaScriptwindowslinux