入“坑”C++系列之(二)从Hello World开始说起

前言

本文通过一个“简单”且经典的例程,对C++的一些基本语法进行简单的介绍,希望能够让大家对C++有一个初步的认识。当然,由于C++和C语言之间的特殊关系,本文也会涉及到一些C语言的知识,不过还是希望大家能够从C++的角度进行理解,毕竟我们正在入坑C++嘛。由于本人能力有限,本文难免有疏漏或错误之处,仍然希望读者不吝指正,谢谢!

程序源码

本文使用的程序源码如下:
程序1:

#include <iostream>
using namespace std;
int main()
{
  cout << "Hello World!" << endl;
  return 0;
}

程序结构分析

对于上述程序,对于学习过C语言的童鞋应该相当眼熟吧。程序开头的预编译指令#include ,目的是在程序的编译阶段,将iostream头文件中的内容载入程序,从而代替这行的头文件包含;接下来的编译指令using namespace std;,涉及到命名空间的知识,细节将在后面的文章中进行讲解;然后便是main函数了,也是程序中的主体部分,其中包含了许多细节性的知识,我们在下面的内容进行详细的说明。

预编译指令

预编译指令是C语言和C++共有的一种特性,通常以#开头,比如此处的#include 头文件包含指令,以后会使用到的#define 宏定义指令,以及#if…#elif…#endif 条件编译指令等,都属于预编译指令,他们都是在程序的编译阶段运行的。而此处使用头文件包含指令iostream头文件包含进程序中,而iostream的中文名是输入输出流,由此可以看出,该头文件与输入输出函数是密切相关的,如果想要使用后面的cin和cout,那么便必须包含该头文件。

命名空间

本文对命名空间的知识进行一个简单的介绍,详细的内容将会在后面的专题文章中进行单独的介绍,读者此时只需要了解该语句的作用即可。
这里做个简单的比喻,我们试想一下。如果同一个学校1班和2班都有一个叫小明的同学,当老师组织1班和2班的同学一起开班会时,老师需要小明同学回答一个问题,那么怎样才能准确的让老师想提问的小明进行回答呢?最简单的方法便是直接使用1班的小明或者2班的小明进行提问,这样便不会出现两个小明同时站起来的情况了。而命名空间的作用与此类似,也是为了避免同名的对象或者函数等产生冲突。
此处,如果我们不使用命名空间,那么程序会出错,报出如下错误:
在这里插入图片描述
当然,在C++中,我们也可以不使用上面的方法进行区分。除了上面的方法之外,我们还可以直接使用std::cinstd::cout使用来代替cin和cout指令,如下所示:
程序2

#include <iostream>
int main()
{
  std::cout << "Hello World!" << std::endl;
  return 0;
}

命名空间的不同表示形式

在实际应用中,命名空间的位置以及形式并非固定的,我们可以根据需要,在不同的地方使用不同格式的命名空间。此处,我将命名空间变量进行类比,提出命名空间的作用域这一概念(个人见解)。从而类比于变量的全局变量局部变量。而命名空间的使用位置主要有下面四种情况
1、如上述程序1所示,放在所有的函数定义之前,我们可以认为是一个全局性的命名空间,即当前文件中的所有函数均能使用命名空间std中的所有元素;
2、将命名空间放在特定的函数中,相当于其作用域是局部的,仅该函数能够使用命名空间中的内容,如下所示:
程序3:

#include <iostream>
void TestFunc()
{
  using namespace std;
  cout << "Hello Word!" << endl;
}
int main()
{
  TestFunc();//函数调用
  //cout << "cout test" << endl;//出错
  return 0;
}

我们仅在TestFunc函数中使用命名空间,那么main函数中便不能直接使用cout或者cin进行输入输出了。
3、使用使用using std::coutusing std::cin的形式代替using namespace std,同样可以使用coutcin进行输入和输出。
4、不使用using namespace std的形式,而直接使用std::coutstd::cin,以及std::endl进行输入输出。

使用建议

一般而言,建议使用上述的第3和第4种方法使用命名空间。

main函数

main函数的结构

在C++和C语言中,所有的函数结构几乎都是一样的。主要由以下几部分构成

函数返回值的类型 函数名(函数形参1,,函数形参2...)

基于此,我们可以知道此处的main函数的返回值类型int整型函数名main没有函数形参。并且,函数一般分为被调函数调用函数,即被调函数被其他函数进行调用,而main函数的不同之处在于,main函数是被操作系统的启动代码调用的,而不能被程序中的其他函数调用,且main函数是必须且唯一的。

main函数的返回值

按照标准规定,对于main函数的返回值。如果返回为零值,那么意味着程序正常运行,如果返回非零值,那么意味着程序中可能存在某些错误。在实际应用中,可以结合脚本对main函数的不同返回值进行不同的处理,从而实现不同的需求。

重头戏一之cout

cout是ostream类的一个对象,而ostream被称为输出流
cout在iostream头文件中进行定义,位于std命名空间中。按照上面的程序,就是Hello Word!通过输出流流向cout对象,从而实现了在屏幕上的显示。
这里我们只需要知道,cout的作用就是打印输出信息,作用和C语言中的printf函数一样。至于类和对象的概念,将会在后续的文章中进行深入讲解,相信大家也会慢慢的有所理解。

重头戏二之<<运算符重载

在C语言中,我们知道**<<表示的是左移运算符**,那为什么在这里就成了插入运算符了呢?是因为**<<运算符使用了C++的一个重要特性,即运算符重载**,通过运算符重载,我们便可以使用同一个运算符,完成不同的功能。
插入运算符的作用便是将其右侧的内容插入输出流中,在流向上面的cout对象,实现信息的输出。
而在C语言中,也存在运算符重载,比如:&既可以作为取地址的运算符,也可以作为按位与的运算符。

重头戏三之endl

C++中的endl和C语言中的**\n类似,我们都可以简单将其人为认为是换行的作用。不同的是,endl被称为控制符**,而**\n被称为换行符**,是一种转义序列。当然,他们之间的区别远非名字不同。
与cout一样,endl也是在iostream头文件中定义的,且位于std命名空间中。并且,endl除了换行的作用之外,还会将缓冲区中的内容进行刷新,从而可以确保将需要打印的信息立即输出到屏幕上,实际上使用endl时,系统会自动调用fflush()函数,清空缓冲区。
而\n的作用则仅仅是换行,在C语言的IO编程章节,会涉及到缓冲IO无缓冲IO两个概念。对于有缓冲的IO函数,可能只有当缓冲区被占满的时候,才会将数据进行输出(即使此处使用了\n换行符),而对于无缓冲的IO函数,只要遇到**\n**,便会将数据进行输出。

重头戏四之cin

cin是instream类的一个对象,而istream被称为输入流。同样,cin也在iostream头文件中进行定义,位于std命名空间中。
虽然上面的程序中并没有使用到cin,但是我们通过对cout的理解,可以想象出cin的语法大概是下面的亚子:

cin >> inputData;

没错,上面的程序,就是为了通过输入设备(此处指键盘),向变量 inputData 流入一个数据,从而将输入的值保存在变量inputData所对应的内存空间中。由此可知,C++中的cin对象的作用与C语言中的scanf函数是一样的。只是相比而言,更加简单。

重头戏五之>>运算符重载

与**<<插入运算符类似,此处的>>被称为抽取运算符**,即从输入流中抽取数据,载入指定的内存地址中。
**>>**同样使用了运算符重载的特性。

补充:处理实际输入与希望输入的数据类型不符的情况

问题现象

在平时的编程过程中,当我们利用cin获取键盘的输入时,需要提前声明一个数据类型,从而将键盘的输入保存至这个变量中,如下:

int inputData = 0;
cin >> inputData;
cout << "输入的数字为:" << inputData << endl;

但是,如果当我们输入的数据并非int类型时,编译器会如何处理呢?实际上,当发生类型不匹配的情况时,编译器会进行如下处理:
1、inputData的值保持不变,即仍然为初始值0;
2、不匹配的输入将被遗留在输入队列中;
3、设置cin对象的一个错误标志;
4、对cin方法的调用将返回false。

解决方法

当发生了上述的错误之后,我们可以按照下面的步骤,对其进行处理:
1、重置cin,从而接收新的输入;
2、删除错误输入;
3、提示用户再次输入正确的数据。
那么,我们如何在代码中实现呢?
首先,利用cin.clear()方法,可以重置输入。其次,利用cin.get()方法,重复读取输入队列中的数据,知道读取到换行符\n,此时则意味着已经读取到上次输入数据的结尾了,此时便实现了清除输入队列的目的。最后,再次提醒用户输入新的数据即可。代码示例如下:

while(1)//重复输入,直到正确输入数字
{
	int testData = 0;
	cout << "请输入一个数字:" << endl;
	if(!(cin >> testData))//如果输入的数据不是数字,则表示类型不匹配.cin方法将返回false
	{
		cin.clear();//重置cin
		while('\n' != cin.get());//将上次的错误输入全部读取出来,达到清空输入队列的目的
		cout << "请输入一个数字:" << endl;
		continue;//继续输入
		
	}
	else //输入的数据正确
	{
		cout << "输入的数据是:" << testData << endl;
		break;//跳出循环
	}
}

总结

本文通过一个简单的例子,对涉及到的一些C++基本特性,进行了介绍。但是,并没有对类、对象以及重载进行深入的描述,这部分内容将在后续的学习笔记中进行描述。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值