一、前言
开发环境搭建属于非常基础的内容,同时由于其它文章我也已经讲过了,所以这里不再赘述,不会的可以参考本站另外一篇文章:初识C++
一个最简单的C++程序如下:
#include<iostream> //预处理器指令
using namespace std; //使定义可见
int main() //函数头
{ //函数体的开始
cout << "hello world"; //打印数据
cout << endl; //换行
cout << "C++ www.kucoding.com"; //再次打印数据
return 0; //结束main函数
} //函数体的结束
将上面的代码运行后,就会输出下面这样的内容:
上面的代码虽然简单,但却包含了很多基本的元素:
- 注释:以
//
作为标识 - 预处理器指令:
#include
- 函数头:
int main()
- 编译指令:
using namespace
- 函数体:用
{}
括起来 - 使用C++的cout工具显示消息的语句
- 结束
main
函数的return
语句。
二、main函数
上面的代码很简洁,但还并不是最简洁的:
int main() //函数头
{ //函数体的开始
return 0; //结束main函数
} //函数体的结束
上面这简单的几行表明了有一个名为main
的函数,并描述了该函数的行为。
其主要构成了一个函数定义,函数定义由两部分组成,其中int main()
叫做函数头,花括号 {} 中的内容叫做 函数体 。
- 函数头:总结了该函数与程序其它部分的接口
- 函数体:指出这个函数应该做什么的计算机指令,每条完整的指令都称为语句,所有语句都以英文分号结束
而放在最后的那条语句叫做返回语句,它用于结束该函数,并且很多时候也并不需要写在所有语句的最后,只要函数执行到它,就会立刻结束。
语句是要执行的操作,编译器需要知道每条语句什么时候结束,C/C++中采用的就是英文分号(;
)作为语句的结束,这取决于语言本身的定义,比如python
用的是换行作为语句的结束。
而main
函数则比较特殊,即使你不写return
这个返回语句它也不会报错,这是编译器做出的妥协,你不写并不代表没有,只是编译器会自动给我们补上而已。
上面的作为接口的函数头可能会让人感到疑惑。
如果仅从入门而言,现在你只需要记住一点:C++语法要求main
函数的定义以int main()
开始,后面的文章也会继续探讨函数的相关内容。
但这里也可以稍微预览一下。
一般来说,C++函数会被其它函数调用,而函数头就描述了这个函数与调用它的函数之间的接口。
位于函数名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
单词中的io
为input
与output
的缩写,即输入输出的意思,而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_time
、get_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
这个名称空间中,std
为Standard
的缩写,即为标准的意思。
想要使用这里面的东西,一般有三种办法。
第一种最直接的方式就是将其全部引入:using namespace std;
一旦使用了这条语句,那么std
内的东西都可以直接用了,比如cout
也是它里面的东西。
但这样做其实只适用于学习阶段,比如如果用到多个名称空间,这样写就完全发挥不出名称空间应用的作用了:将所有名称空间内的东西都暴露出来,仍就有可能导致命名冲突。
另一种更好的方式是用哪个,就引入哪个:using std::cout;
。
这种写法可以让你后续直接使用cout
,但其它的想要用也得分别这样就行引入。
而最后、可能最麻烦,但也最稳妥的方式是,带着名称空间一起使用:
std::cout<<"hello world";
这样写稍显麻烦,但却能精确的表达我需要用哪个名称空间内的哪个东西,符号::
你可以直接理解为的,也就是std
的cout
。
七、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++本身是以;
作为语句的结束,所以这代表它的写法是可以非常随意的:
这种随意的代价就是,让我们很难理解这段代码是干嘛的。
所以为了保持代码的简洁好看,一旦都是采用的每行一条语句:
如果一条语句太长,也可以分行写:
九、简单练习
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;
}