文章

【信奥业余科普】C++ 的奇妙之旅 | 09:信奥赛场的核心语言——C++ 的前世今生

在上一篇文章中,我们为第一部分【计算机历史】画上了句号。从本篇开始,我们将开启第二部分——【C++ 的奇妙之旅】。在此部分中,我们将开始学习 C++ 这门核心编程语言。今天,我们将由浅入深地介绍 C++ 的发展历史、设计理念,以及它为何能成为当今信奥赛场上的主要编程语言。

写在前面的话:这是一系列专为对信奥(信息学奥赛)感兴趣的中小学生及家长朋友们准备的科普文章。笔者受自身学识所限,文中若存在不严谨之处,还望各位读者指正。

推出本系列的初衷主要有三点:

  1. 拓宽视野:在动手写代码之前,了解计算机软硬件的发展脉络。
  2. 激发兴趣:通过通俗地讲述技术与历史,激发中小学生对计算机科学的兴趣。
  3. 课余读物:作为休闲阅读,让大家在轻松的氛围中收获知识。

第一部分【计算机历史】系列文章往期回顾:


要想了解一门编程语言的设计初衷,最好的办法是结合它诞生时的历史背景。我们先来聊聊编程语言的发展过程。

一、 编程语言的发展与 C 语言的诞生

在之前的文章中我们提到,早期的程序员使用打孔纸带或汇编语言这些复杂的指令与计算机硬件进行交互。

到了 1970 年代初,两位计算机科学家——丹尼斯·里奇(Dennis Ritchie)肯·汤普森(Ken Thompson) 正在贝尔实验室开发 Unix 操作系统。为了让操作系统的代码编写更高效、更具可读性,同时保持对底层硬件和内存的控制,丹尼斯·里奇发明了 C 语言

C 语言具有两个显著的优势:

  • 拥有高级语言的逻辑结构(如 ifwhile 等控制语句,易于阅读);
  • 保留了底层硬件操作能力(能够直接操控内存地址)。

因此,C 语言被广泛应用于系统级软件的开发。但是,随着软件工业的发展,新的编程挑战也随之而来。

二、 软件规模的扩大与 C++ 的诞生

时间来到 1980 年代。随着计算机性能的提升,软件的规模也越来越庞大。

在过去,编写一两千行代码的小型程序时,C 语言非常适用。然而,当需要开发包含十数万行代码的大型系统(如具有复杂图形界面或大型数据库的系统)时,C 语言传统的“面向过程”编程方式显得难以维护。代码之间的依赖变复杂,修改某一处功能可能会影响到整个程序的稳定性。

在这个背景下,计算机科学家 本贾尼·斯特劳斯特卢普(Bjarne Stroustrup) 提出了新的解决方案。

本贾尼当时在研究复杂的系统模拟,他发现 C 语言运行速度快,但在组织大型程序时比较困难;而另一门名为 Simula 的语言拥有很好的“分类”思维,适合组织大型项目,但运行速度较慢。

于是,他尝试将 Simula 的这种结构化思维与 C 语言的执行效率结合起来。他为 C 语言引入了“类(Class)”和“对象(Object)”的概念,也就是如今常见的——面向对象编程(Object-Oriented Programming, OOP)

起初,这门新语言被称为 “带类的 C(C with Classes)”。后来,为了体现它是对 C 语言的演进,借用了 C 语言中的自增运算符 ++,将其正式命名为 C++,寓意“C 语言的增强版”。

三、 究竟什么是“面向对象”?

那么,“类(Class)和对象(Object)”具体是指什么呢?它们是如何解决大型项目开发难题的?

我们可以通过在游戏中开发“英雄打怪物”的例子,来对比这两种逻辑的差异:

1. 面向过程(以 C 语言为代表): 在这种思维下,程序里的 “数据(变量)”“动作(函数)” 是完全分开存放的。

假如系统里散落着一堆数据(英雄的血量、英雄的攻击力、怪物的血量等),同时还有一个负责算账的公共处理函数叫 计算伤害()。 如果想让英雄去砍怪物一刀,代码写出来的逻辑像这样: 计算伤害(英雄的攻击力, 怪物的血量) 在这里,程序员就像个劳碌的保姆,每次都要亲自去仓库查出是谁砍的、攻击力是多少、被砍的是谁,然后把这堆数据整理好塞进 计算伤害() 里面去算。 一旦游戏里由于新增怪物而增加了海量的零散数据,稍有不慎,程序员就会把“怪物的攻击力”算在“英雄”的头上,导致整个游戏乱套。

2. 面向对象(以 C++ 为代表): 为了解决代码过多带来的混乱,C++ 引入了面向对象(OOP)思维。它的重点是把“相关的特征和动作”强行打包在一起。这只需理解两个最通俗的概念:

  • 类(Class):就像是一张“通用图纸”。比如我们画出一张“游戏角色图纸”,规定所有角色对象都必须拥有“血量”、“攻击力”(数据),并且都会带有“攻击”这个行为手段(函数)。
  • 对象(Object):就是照着图纸实际造出来的具体事物。比如,基于图纸我们造出了“具体的英雄”和“具体的怪物”这两个独立存在的对象。

在面向对象的设计下,“英雄”作为一个对象,他不仅自带了血量和攻击力,而且“打人”这个动作是长在他自己身上的! 这时候让他去攻击怪物,代码就会变得极其直观,就像日常下达命令一样: 英雄.攻击(怪物) 此时,英雄自己心里清楚自己的属性是多少,也知道如何执行攻击的动作,完全不需要程序员再去到处翻找本子拼凑数据了。

两者的核心差异: 如果用一句话来通俗总结:

  • 面向过程是“数据、动作分开保管”。程序员就像个保姆,凡事都要亲自拿着散落的数据去函数里计算。
  • 面向对象是“数据、动作自身打包”。程序员就像个统帅,只要直接对着一个个会干活的“对象”下达命令就行了。

通过这种“分类打包”的机制,C++ 将一个庞大无序的复杂系统,切分成了无数个相对独立、自己管理自己的小模块。这不仅极其符合人类日常的认知习惯,也让系统极难崩溃且极其方便后续的扩展。

四、 为什么信奥赛场主要使用 C++?

现在有许多热门的编程语言,比如易于上手的 Python,或者用于网页开发的 JavaScript。为什么信息学奥赛(CSP/NOIP/NOI 等)主要将 C++ 作为首选甚至唯一指定语言呢?

这主要归功于 C++ 的两个核心优势:

1. 卓越的执行效率与底层控制

信息学奥林匹克竞赛主要考察算法的效率。在处理数十万甚至成百上千万规模的数据时,程序的运行时间限制通常在毫秒级别。 虽然 Python 等高级语言易学,但由于在底层进行了较多的自动管理与转换,其执行速度低于 C++。C++ 赋予了程序员直接管理内存等硬件资源的权限,只要代码编写得当,就可以最大化地发挥计算机的性能。

2. 强大的标准模板库(STL)

C++ 提供了一个非常完善的标准模板库(Standard Template Library,简称 STL)。STL 中内置了大量常用的数据结构和算法:如动态数组(vector)、队列(queue),以及高效率的排序算法(sort 等)。 在比赛有限的时间内,选手可以直接调用这些经过高度优化的工具函数,将精力集中在核心的算法设计上,而无需从零开始编写基础的数据结构代码。

正是因为这兼具了“运行效率高”和“内置工具强大”的特点,C++ 成为了信息学奥林匹克竞赛的首选语言。


结语与下期预告

C++ 是一门自由度极高但也具有一定挑战性的语言。它赋予了开发者底层的控制权,同时要求开发者承担相应的内存管理等责任。

在这篇文章中,我们梳理了 C++ 的发展历史,以及它在信奥竞赛中的优势。【C++ 的奇妙之旅】才刚刚开始。

在下一篇文章中,我们将正式动手:建立 C++ 的代码编写和运行环境,并编写第一段经典的入门代码——Hello, World!

我们下篇见!

所有代码已上传至Github:https://github.com/lihongzheshuai/yummy-code

GESP 学习专题站:GESP WIKI

"luogu-"系列题目可在洛谷题库进行在线评测。

"bcqm-"系列题目可在编程启蒙题库进行在线评测。

欢迎加入Java、C++、Python技术交流QQ群(982860385),大佬免费带队,有问必答

欢迎加入C++ GESP/CSP认证学习QQ频道,考试资源总结汇总

欢迎加入C++ GESP/CSP学习交流QQ群(688906745),考试认证学员交流,互帮互助

GESP/CSP 认证学习微信公众号
GESP/CSP 认证学习微信公众号
本文由作者按照 CC BY-NC-SA 4.0 进行授权