【C++】入门基础【上】
目录
- 一、C++的发展历史
- 二、C++学习书籍推荐
- 三、C++的第一个程序
- 1、命名空间`namespace`
- 2、命名空间的使用
- 3、头文件`<iostream>`是干什么的?
个人主页<—请点击
C++专栏<—请点击

一、C++的发展历史
C++的起源可以追溯到1979年,当时Bjarne Stroustrup(本贾尼·斯特劳斯特卢普)在贝尔实验室从事计算机科学和软件工程的研究工作。面对项目中复杂的软件开发任务,特别是模拟和操作系统的开发工作,他感受到了现有语言(如C语言)在表达能力、可维护性和可扩展性方面的不足。
1983年,Bjarne Stroustrup在C语言的基础上添加了面向对象编程的特性,设计出了C++语言的雏形,此时的C++已经有了类、封装、继承等核心概念,为后来的面向对象编程奠定了基础。这⼀年该语言被正式命名为C++。在随后的几年中,C++在学术界和工业界的应用逐渐增多。⼀些大学和研究所开始将C++作为教学和研究的首选语言,而⼀些公司也开始在产品开发中尝试使用C++。这⼀时期,C++的标准库和模板等特性也得到了进⼀步的完善和发展。
C++的标准化工作于1989年开始,并成立了⼀个ANSI和ISO(International Standards Organization)国际标准化组织的联合标准化委员会。1994年标准化委员会提出了第一个标准化草案。在该草案中,委员会在保持斯特劳斯特卢普最初定义的所有特征的同时,还增加了部分新特征。
在完成C++标准化的第⼀个草案后不久,STL(Standard Template Library)是惠普实验室开发的⼀系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。在通过了标准化第⼀个草案之后,联合标准化委员会投票并通过了将STL包含C++标准中的提议。STL对C++的扩展超出C++的最初定义范围。虽然在标准中增加STL是个很重要的决定,但也因此延缓了C++标准化的进程。
1997年11月14日,联合标准化委员会通过了该标准的最终草案。1998年,C++的ANSI/IS0标准被投入使用。
Bjarne Stroustrup:


上面这副图片是C++的版本更新情况,字体越大代表更新的力度越大,目前C++26预计在2026年公布。
二、C++学习书籍推荐

C++ Primer:主要讲解语法,经典的语法书籍,前后中期都可以看。STL源码剖析:主要从底层实现的角度结合STL源码,庖丁解牛式剖析STL的实现,是侯捷老师的经典之作。Effctive C++:本书也是侯捷老师翻译的,本书有⼀句评价:把C++程序员分为看过此书的和没看过此书的。
三、C++的第一个程序
在学习C语言的时候我们打印的第一个程序就是hello world!,所以我们C++的第一个程序也从它开始,C++兼容C语言绝大多数的语法,所以C语言实现的hello world!依旧可以运行,这里我们就不用C语言实现了,我们来看看C++怎么写,C++中需要把定义文件
代码后缀改为.cpp。
C++:
#include <iostream>
using namespace std;int main()
{cout << "hello world!" << endl;return 0;
}
这就是C++版本的hello world!了。
运行结果:

刚从C语言接触到C++,这里的大部分东西,我们都看不懂,没有关系,接下来我会一一讲解。
1、命名空间namespace
在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的。
C语言中的命名冲突:
我们知道在C语言中qsort是函数,假设我将它定义成int类型的全局变量,然后我不包含头文件<stdlib.h>,我们执行下面的代码:
#include <stdio.h>int qsort = 10;int main()
{printf("%d", qsort);return 0;
}
执行结果:

之后我再加上头文件<stdlib.h>,执行结果:

程序就会出现这样的报错,因为函数在全局变量中发现了两个这样的变量名称,这就导致了命名冲突问题,而我们今天要讲的命名空间就是专门解决这个问题的。
注:只有将qsort定义成全局变量时,才会出现这样的错误,因为当它为局部变量时,打印的时候,程序会首先在局部域寻找变量,当它在局部域中找到后,就不会前往全局域寻找,就不会引发命名冲突了。
命名空间解决该问题的思路呢也很简单,举个生活中常见的例子,假设你家的大黄和邻居家的大黄一摸一样,而且都叫大黄,总是分不清谁是谁,解决这个问题只需要在狗的身上做个标记,比如让它戴个牌子就可以分清楚了,命名空间解决命名冲突的问题和这个类似,就是定义一个空间然后把冲突的变量,放进这个空间就可以了。
#include <stdio.h>
#include <stdlib.h>namespace qs
{int qsort = 10;
}int main()
{printf("%d",qs::qsort);return 0;
}
测试结果:

这里由于我们定义了一个命名空间,而访问这个空间需要一些小的操作,即用命名空间::成员名的方式访问指定命名空间中的成员。::是作用域解析运算符。
当::变量名这样使用时表示全局作用域,即可以访问全局变量。

如上图,当我放开时,它就会访问全局变量中的qsort函数。
注意:
- 定义命名空间,需要使用到
namespace关键字,后面跟命名空间的名字,然后接⼀对{}即可,{}中即为命名空间的成员。命名空间中可以定义变量/函数/类型等 namespace本质是定义出⼀个域,这个域跟全局域各自独立,不同的域可以定义同名变量,所以qsort不再冲突了namespace只能定义在全局,当然它还可以嵌套定义。- 项目工程中多文件中定义的同名
namespace会认为是⼀个namespace,不会冲突。 C++标准库都放在⼀个叫std(standard)的命名空间中。(也就是我们打印程序中用到的std)。
2、命名空间的使用
编译查找⼀个变量的声明/定义时,默认只会在局部或者全局查找,不会到命名空间里面去查找。
例如:
#include <stdio.h>namespace test
{int a = 100;int b = 200;
}int main()
{printf("%d", a);return 0;
}
以上代码会出现一下错误:

- 解决方案1:指定命名空间访问
#include <stdio.h>namespace test
{int a = 100;int b = 200;
}int main()
{printf("%d", test::a);return 0;
}

- 解决方案2:
using将命名空间中某个成员展开,项目中经常访问的不存在冲突的成员推荐这种方式
#include <stdio.h>namespace test
{int a = 100;int b = 200;
}using test::a;
int main()
{printf("%d",a);return 0;
}

- 解决方案3:展开命名空间中全部成员,项目不推荐,冲突风险很大,日常小练习程序为了方便推荐使用。
#include <stdio.h>namespace test
{int a = 100;int b = 200;
}using namespace test;
int main()
{printf("%d",a);return 0;
}

我们的打印程序就是使用的方案3,将C++标准库全部展开了,即using namespace std;。
3、头文件<iostream>是干什么的?
在C++编程语言中,<iostream>是一个标准库头文件,它的主要作用是实现基本的输入输出功能,包含了输入输出流相关的定义和声明。
其中定义了std::cin(标准输入流对象)相当于C语言中的scanf,定义了std::cout(标准输出流对象)相当于C语言中的printf等等。
std::cin是istream类的对象,它主要面向窄字符(narrow characters (of type char))的标准输入流。std::cout是ostream类的对象,它主要面向窄字符的标准输出流。std::endl是⼀个函数,流插入输出时,相当于插入⼀个换行字符加刷新缓冲区。
我们在实现第一个程序的时候发现其中有<<符号,这个操作符是流插入运算符,被用于向输出流中去插入数据,相对的>>是流提取运算符,被用于从输入流中提取数据。
我们还从程序中发现C++中打印时没有使用%d、%f这些符号,这是因为cout在输出时会自动识别数据类型,进行相应的转换和输出,不容易出现因格式化字符串与实际数据类型不匹配而导致的错误。而C语言使用%d时,如果不小心将其他类型的数据以 %d 格式输出,可能会导致错误的结果或程序崩溃。
总结:
以上就是本期博客分享的全部内容啦!如果觉得文章还不错的话可以三连支持一下,你的支持就是我前进最大的动力!
技术的探索永无止境! 道阻且长,行则将至!后续我会给大家带来更多优质博客内容,欢迎关注我的CSDN账号,我们一同成长!
(~ ̄▽ ̄)~
