为什么C++语法如此复杂?

34 投票
10 回答
18367 浏览
提问于 2025-04-15 13:58

我刚开始学编程,虽然自己学了大约一年Python,也学过一段时间的C#。

这个月我在大学开始上C++编程课,我真的想问一下:“为什么C++的代码这么复杂?”

在Python中写“Hello world.”就像这样简单:“print 'Hello world.'”,但在C++中却是:

# include <iostream>
using namespace std;

int main ()
{
    cout << "Hello world.";
    return 0;
}

我知道这背后可能有好的理由,但为什么...

  • ... 每次都要包含<iostream>?有没有可能不需要它的情况?
  • ... 对于标准库也是同样的问题,什么时候不需要std::*?
  • ... “main”部分是个函数吗?你会调用main函数吗?为什么它是个整数?为什么C++需要main函数,而Python却不需要?
  • ... 为什么需要“std::cout << ”?跟Python比起来,这不是显得冗长和复杂吗?
  • ... 即使你根本不会用到,为什么还需要返回0?

这可能是因为我学的C++还很基础,但到目前为止我写的每个程序都长得差不多,所以我不得不一遍又一遍地重新输入相同的代码。这不是多余吗?编译器难道不能自己输入这些代码吗?因为它总是一样的(也就是说,按我所知,你总是需要包含<iostream>、std、int main和return 0)。

10 个回答

8

... 你每次都需要包含这个吗?有没有不需要的时候?

如果你在这个模块里不打算使用 iostreams,那就不需要包含它。在较大的程序中,很多模块并不直接进行输入输出操作,所以实际上很少需要用到 iostreams

换个角度问:在 Python 中,大多数复杂程序都需要导入 sys 和/或 os。为什么呢?

... 关于标准库的同样问题,什么时候不需要 std::*

你可以选择使用 using 语句,或者使用 std:: 前缀。这和 Python 中的选择很相似,你可以选择 from sys import *,或者 import sys,然后在使用时加上 sys. 前缀。在 Python 中,你必须写 sys.stdout。那 std::cout 真的有什么不好吗?

... "main" 部分是个函数吗?你会调用 main 函数吗?为什么它是一个整数?为什么 C++ 需要有 main 函数而 Python 不需要?

是的,main 是一个函数。通常你不会自己去调用它。名字 "main" 是程序的入口点。它返回一个整数,因为这个返回值用作程序的状态码。如果你想返回一个非零的状态码,Python 中可以使用 sys.exit()

Python 不需要 main 函数,因为在 Python 中,你可以在模块里写一些不在任何函数中的代码。这些代码在加载模块时会被执行。不过,在 Python 中的常见约定是把你只想在模块作为程序运行时执行的代码放在一个类似于下面的块里:

if __name__ == '__main__':

通常这会用来调用一个 main 函数:

def main(argv):
  # program goes here

  return 0

if __name__ == '__main__':
  sys.exit(main(sys.argv))

此外,在 Python 中,当你运行模块时,你会告诉解释器哪个模块是 "main" 模块。例如:python foo.py。而在 C++ 中,像 C 一样,"main" 模块实际上就是那个包含 main 函数的模块。(如果有多个模块都有 main 函数,链接会失败。)

... 你需要 "std::cout << " 吗?这不是比 Python 更长更复杂吗?

在 Python 中,相应的写法是 sys.stdout.write(...)。Python 的 print 语句是一个特殊的简写,默认输出到 sys.stdout

不过,很多人确实觉得使用位移运算符进行输入输出的 iostreams 约定是个坏主意。

... 即使你根本不会用到,还是需要返回 0 吗?

你可能不会用到它,但你的程序会用到。正如之前提到的,你返回的值是程序的状态码。

顺便说一下,我确实觉得 C++ 有点复杂,但并不是因为你提到的这些点。一旦你开始写一些复杂的程序,涉及多个模块并且不仅仅是写入 stdout,这些差异就会消失(在 Python 中也需要同样的复杂性)。

14

针对你在帖子最后提出的问题,可以用C++的一个理念来总结:

你不需要为你不使用的东西付费。

你并不总是需要使用标准输入(stdin)或标准输出(stdout)(比如在Windows或图形界面应用中?),你也不一定总是会用到标准模板库(STL),而且你写的每一段代码也不一定都要使用标准的主函数(main)(比如winAPI)等等。正如之前的发帖者所说,C++比Python更底层。你会接触到更多的细节,这让你对自己正在做的事情有更多的控制权。

94

C++是一种更底层的编程语言,它的执行不依赖于解释器的环境。因此,它的设计选择和Python有很多不同,因为C++没有一个可以管理类型和内存等信息的环境。C++可以用来编写操作系统内核,在这种情况下,机器上除了程序本身没有其他代码运行,这就意味着这个语言必须是自给自足的(某些库功能在所谓的独立实现中不可用)。这就是为什么C++没有Python中的eval,也没有办法去判断一个类的成员等功能,因为这些功能需要一个执行环境(或者在程序本身中需要大量的开销,而不是依赖这样的环境)。

关于你的具体问题:

  • 每次都需要包含<iostream>吗?有没有不需要的时候?

#include <iostream>是一个指令,用来把<iostream>这个头文件引入到你的程序中。<iostream>包含了标准输入输出的对象,特别是cout。如果你不使用标准输入输出对象(比如,你只使用文件输入输出,或者你的程序使用图形用户界面库,或者你在编写操作系统内核),那么你就不需要<iostream>

  • 标准库的情况也是一样,什么时候不需要std::*

std是一个命名空间,里面包含了所有的标准库。using namespace std;有点像from std import *,而#include指令在这方面更像是一个简单的import std语句。(实际上,机制是相当不同的,因为C++并不使用using namespace std;来自动查找std中的对象;这个使用指令只是把名字引入到全局命名空间中。)

我在这里要提一下,使用指令(using namespace)在C++代码中通常不被推荐,因为它会引入很多名字,可能导致名字冲突。尽量使用使用声明(using std::cout;),或者限制使用指令的范围(比如,只在一个函数或一个源文件中)。没有充分理由的话,千万不要在头文件中放using namespace

  • “main”部分是一个函数吗?你会调用main函数吗?为什么它是一个整数?为什么C++需要有main函数而Python不需要?

main是程序的入口点——执行从这里开始。在Python中,__main__模块起着同样的作用。C++不允许在定义的函数外执行代码,而Python可以,所以它的入口点是一个函数,而不是一个模块。

  • 你需要“std::cout << ”吗?这不是比Python的写法复杂得多吗?

std::cout只有在你没有把cout这个名字引入到全局命名空间时才需要,方法是使用指令(using namespace std;)或者使用声明(using std::cout)。在这方面,它和Python中的import stdfrom std import *from std import cout之间的区别很相似。

<<是一个重载的操作符,用于标准流对象。cout << value调用cout的函数来输出value。Python不需要这样的额外代码,因为print是内置的;而对于C++来说,这种做法是合理的,因为它可能根本没有操作系统,更不用说输入输出库了。

  • 即使你根本不会用到,是否还需要返回0?

不需要。main(以及其他函数)在末尾有一个隐含的return 0;main的返回值(或者如果调用了exit函数,则是传给它的值)会作为退出代码返回给操作系统。0表示程序成功执行——没有遇到错误等。如果遇到错误,应该返回一个非零的值(或者传给exit)。

撰写回答