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

时间:2009-08-31 04:37:26

标签: c++ python syntax

我是编程的新手,虽然我已经教自己Python大约一年了,我不久前学过C#。

本月我在大学开设了C ++编程课程,我只想问; “为什么C ++代码如此复杂?”

写下“Hello world”。在Python中就像“打印'Hello world'一样简单。”但在C ++中它是:

# include <iostream>
using namespace std;

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

我知道这可能是一个很好的理由但是,为什么......

  • ...你必须包括&lt; iostream&gt;每次?你有需要吗?
  • ...标准库的相同问题,何时不需要std :: *?
  • ...是一个功能的“主要”部分?你有没有打电话给主要功能?为什么是整数?为什么C ++需要一个main函数但Python不需要?
  • ...你需要“std :: cout&lt;&lt;”吗?与Python相比,这不是那么长而复杂吗?
  • ......即使你永远不会使用它,你还需要返回0吗?

这可能是因为我正在学习这样的基本C ++,但到目前为止我所做的每个程序都是这样的,所以我必须一遍又一遍地重新输入相同的代码。这不是多余的吗?编译器本身无法输入此代码,因为它总是相同的(即afaik总是包含&lt; iostream&gt;,std,int main,return 0)

10 个答案:

答案 0 :(得分:78)

C ++是一种更低级的语言,无需解释器的上下文即可执行。因此,它有许多不同于Python的设计选择,因为C ++没有可依赖的环境来管理类型和内存等信息。 C ++可用于编写操作系统内核,除了程序本身之外,机器上没有代码运行,这意味着语言(某些库工具不适用于所谓的独立实现)必须是自包含的。这就是为什么C ++没有等同于Python的eval,也不是确定类的成员等的方法,也不是需要执行环境的其他特性(或者程序本身的大量开销而不是这样的环境) )

对于您的个人问题:

  • 您是否必须每次都包含<iostream>?你有没有需要它?

#include <iostream>是将<iostream>标头导入程序的指令。 <iostream>包含标准输入/输出对象 - 尤其是cout。如果您不使用标准I / O对象(例如,您只使用文件I / O,或者您的程序使用GUI库,或者正在编写操作系统内核),则不需要<iostream> < / p>

  • 标准库的相同问题,何时不需要std :: *?

std是包含所有标准库的命名空间。 using namespace std;有点像from std import *,而#include指令(在这方面)更像是准系统import std语句。 (实际上,机制相当不同,因为C ++不使用using namespace std;自动查找std中的对象; using-directive只将名称导入全局名称空间。)

我在这里要注意,using-directives(using namespace)经常在C ++代码中不受欢迎,因为它们会导入大量名称并导致名称冲突。尽可能使用using-declarations(using std::cout;),因为它限制了using指令的范围(例如,限制为一个函数或一个源文件)。没有充分理由,不要将using namespace放在标题中。

  • 是一个功能的“主要”部分?你有没有打电话给主要功能?为什么是整数?为什么C ++需要一个main函数但Python不需要?

main是程序的入口点 - 执行开始的地方。在Python中,__main__模块用于相同的目的。 C ++不像Python那样执行定义函数之外的代码,因此它的入口点是函数而不是模块。

  • 你需要“std :: cout&lt;&lt;”吗?与Python相比,这不是那么长而复杂吗?
仅当您未通过using-directive(std::cout)或using-declaration({{coutusing namespace std;名称导入全局命名空间时,才需要

using std::cout {1}})。在这方面,它再次非常类似于Python的import stdfrom std import *from std import cout之间的区别。

<<是标准流对象的重载运算符。 cout << value调用cout的函数输出value。 Python不需要这样的额外代码,因为print内置于语言中;这对于C ++来说没有意义,因为C ++甚至可能没有操作系统,更不用说I / O库了。

  • 即使你永远不会使用它,你还需要返回0吗?

没有。 main(并且没有其他函数)最后有一个隐式return 0;main的返回值(或者,如果调用exit函数,则传递给它的值)作为退出代码传递回操作系统。 0表示程序已成功执行 - 它没有遇到错误等。如果遇到错误,应返回非零值(或传递给exit)。

答案 1 :(得分:11)

在帖子结束时回答你的问题,可以用C ++的哲学来概括:

你不支付你不使用的东西。

您并不总是需要使用stdin或stdout(Windows / GUI应用程序?),也不会一直使用STL,您编写的所有内容也不一定使用标准main(winAPI)等。作为之前的海报说,C ++比Python低。您将接触到更多详细信息,可让您更好地控制自己正在做的事情。

答案 2 :(得分:7)

  

...你必须包括    每次?你有没有   需要吗?

如果您不打算在该模块中使用iostream,则不需要它。在较大的程序中,很少有模块直接执行任何实际IO,因此实际上很少需要使用iostream。

转过来的问题:在python中你需要在大多数非平凡的程序中导入sys和/或os。为什么呢?

  

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

您可以使用使用行,也可以使用std ::前缀。这非常类似于python的选择,你可以说“来自sys import *”或“import sys”,然后不得不用“sys。”作为前缀。在python中你必须说“sys.stdout”。 “std :: cout”真的更糟吗?

  

...是一个功能的“主要”部分?做   你有没有打电话给主要功能?为什么   它是整数吗?为什么C ++需要   有一个主要功能,但Python   不?

是的,main是一个功能。通常你不会自己打电话给主。名称“main”保留用于程序的入口点。它返回一个整数,因为返回的值用作程序的状态代码。在Python中,如果要返回非零状态代码,可以使用sys.exit。

Python没有相同的约定,因为使用Python,您可以在不在函数中的模块中使用代码。加载模块时执行此代码。有趣的是,许多人认为将代码放在模块的顶层并且通过执行以下操作来创建主要功能是不好的方式:

def main(argv):
  # program goes here

  return 0

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

此外,在Python中,您告诉具有模块的解释器在运行时是“主”模块。例如:“python foo.py”。在C中,“main”模块(有效地)是具有称为main的函数的模块。 (如果有多个带有main函数的模块,那就是链接器错误。)

  

...你需要“std :: cout&lt;&lt;”吗?是不是   那不必要的漫长而复杂   与Python相比?

Python中的等价物实际上是“sys.stdout.write(...)”。 Python的print语句是一个特殊情况的简写。

尽管如此,许多人确实认为使用IO的位移操作符的iostreams惯例是一个坏主意。具有讽刺意味的是,Python似乎受到了这种语法的“启发”。如果你想使用print写入stdout以外的地方你可以说:

print >>file, "Hello"
  

...即使在什么时候你也需要返回0   你永远不会用它吗?

你不会使用它,但你的程序会。如前所述,您返回的值是程序的状态代码。

除此之外:我确实觉得C ++过于复杂,但并不是因为你提到的任何一点。一旦你开始编写具有多个模块的非平凡程序并且不仅仅是写入stdout,那么你提到的所有差异都会消失(在某种意义上,你需要在Python中具有同样多的复杂性)。

答案 3 :(得分:6)

如果要将内容输出到控制台,请包括<iostream>。由于打印“Hello world”涉及控制台输出,因此您需要iostream

操作系统基本上调用main函数。它通过传递给程序的命令行参数调用。它返回一个整数,因为程序必须向操作系统返回一个错误代码(这是确定最后一个命令是否成功的标准方法)。

如果你想要采用C风格,你可以随时使用printf("hello world");代替std::cout << "hello world";。写入速度要快一些,并允许您进行格式化输出。

来自return 0的{​​{1}}表示程序已成功执行。

编译器不会自动包含所有标准库并使用命名空间main,因为有时您的代码和库代码之间可能会发生名称冲突,而这些代码和库代码根本不需要。您并不总是需要所有库。同样,有时您使用的是不同的主程序(Windows开发时会想到它自己的,不同的std启动函数)。编译器也不会自动WinMain,因为有时程序需要指示它未成功完成。

答案 4 :(得分:6)

所有这些事情都有很好的理由。 C ++是一种非常广泛的语言,用于从小型嵌入式系统到由100多名程序员构建的巨型应用程序。构建一个小程序的人在桌面上运行的用例绝不是唯一的。所以有时你正在构建库组件。在那种情况下没有main()。有时您正在使用没有标准库的小型系统。在那种情况下没有标准。有时您希望构建一个与其他Unix文本工具一起使用的Unix工具,并使用从main()返回的int来表示其完成状态。

换句话说,你抱怨的事情是你的样板。但它们是重要的细节,与该语言的其他用户不同。

答案 5 :(得分:5)

这让我想起了The Evolution of a Programmer。现在展示的一些语言和技术有点陈旧,但你应该得到一般的想法。 :)

答案 6 :(得分:5)

C ++相当复杂的原因之一是因为它旨在解决大型程序中出现的问题。在C ++创建为AT&amp; T时,他们最大的C程序大约有1000万行代码。在那种规模上,C不能很好地发挥作用。 C ++解决了使用这种程序时遇到的许多问题。

话虽如此,也可以回答原来的问题:

  • 你会include <iostream>在哪里需要它。如果你有10.000个C ++文件,那么通常少于1000个,有时少于100个会产生用户可见的输出。
  • print "Hello, world"这样的语句假定存在默认输出,但很难一概而论。 cout << "Hello, world"表单会明确显示输出的位置,但同一表单也允许cerr << "Goodbye, world"MyTmpFile << "Starting phase #" << i
  • 标准库位于std::命名空间中。我的10.000个文件将在另外25个名称空间中。
  • main在许多方面都是一个奇怪的东西,作为启动功能。

答案 7 :(得分:3)

博德:

您并不总是需要<iostream>。您唯一需要的是:

  1. main函数(或WinMain,如果您正在编写Win32应用程序)。
  2. 变量,函数,运算符,语言结构(ifwhile等。)。
  3. 能够将库中的功能包含到您的程序中。
  4. 其他所有内容都是特定于应用程序的。

    正如其他海报所说,main函数的返回值是错误代码 1 。如果main返回0,请高兴:一切正常!

    1 当您编写与其他程序“通信”的程序时,这非常有用。程序可以“告诉”另一个程序是否正确执行的最简单方法是使用错误代码。

答案 8 :(得分:2)

正如人们所说,简单的答案是他们的语言不同,目标不同。回答你的具体问题...

  

...你每次都必须加入<iostream>吗?你有没有需要它?

<iostream>是iostreams的头文件之一,它是负责输入/输出的C ++标准库的一部分;在这种情况下,您需要它才能访问std::cout。如果您没有在源文件中执行I / O操作,则不需要包含它 - 例如,大多数包含类定义的文件可能不需要<iostream>

  

...标准库的相同问题,何时不需要std :: *?

std是包含标准库中类的命名空间的名称;它是为了避免名称冲突。 Python有包和模块来做到这一点。

您可以使用using语句将来自其他命名空间的项目带入当前范围,请参阅this FAQ entry以获取示例(并解释为什么盲目地带来所有{{1}的错误进入范围!)。

  

...为什么“主要”部分是一个功能?你有没有打电话给主要功能?为什么是整数?为什么C ++需要一个main函数但Python不需要?

C ++中的可执行语句必须包含在函数中,std函数定义为执行开始的位置。在Python中,可执行语句可以放在文件的顶层,执行定义为。

如果你愿意,你可以打电话给main - 毕竟这只是一个功能 - 但是通常没有理由这样做。在幕后,大多数C ++实现会在运行时库完成一些启动内务管理后为您调用main()

main()的返回值将返回给操作系统。这源于C和UNIX,其中应用程序需要提供1字节的退出状态代码,并从main()返回该值是一种明确的表达方式。

  

...为什么你需要“std :: cout&lt;&lt;”?与Python相比,这不是那么长而复杂吗?

这只是设计上的差异。 iostreams是一个相当复杂的野兽,具有许多功能,其中一个副作用是语法对于简单的任务有时有点难看。

  

...即使您永远不会使用它,为什么还需要返回0?

你确实使用它;这是作为程序退出状态返回给操作系统的值。

答案 9 :(得分:0)

Python是高级语言。 C ++是中级语言。