1

我正在学习 C 并且我有点知道如何在 Mathematica 上编程。

在 Mathematica 上,我可以简单地通过编写来声明一个变量:

a=9
a="b"
a=9.5

似乎 Mathematica 通过简单地阅读并在其上找到某种模式就可以自然地理解这是什么类型的变量。(整数、字符、浮点数)。我猜 Python 也有同样的功能。

在 C 上,我必须先说它是什么:

int num;
char ch;
float f;

num=9;
ch='b';
f=9.5;

我知道这延伸到其他语言。所以我的问题是:为什么编程语言需要这种变量声明?

关于该主题的参考资料将非常有用。

4

6 回答 6

6

Mathematica、Python 和其他“动态类型”语言的变量由值和类型组成,而“静态类型”语言(如 C)则具有仅由值组成的变量。这不仅意味着存储变量需要更少的内存,而且动态类型语言必须在运行时设置和检查变量类型以了解变量包含的值类型,而静态类型语言则需要类型,因此需要进行哪些操作可以/需要对其执行,在编译时是已知的。因此,静态类型语言的速度要快得多。

此外,现代静态类型语言(如 C# 和 C++11)具有类型推断,这通常使得无需提及类型。在一些非常先进的静态类型语言(如 Haskell)中,可以在不指定类型的情况下编写大型程序,从而提供静态类型语言的效率和动态类型语言的简洁性和便利性。

于 2012-08-30T04:59:37.800 回答
3

声明对于将 C 编译成有效的二进制文件是必要的。基本上,这是 C 比 Mathematica 快得多的重要原因。

于 2012-08-30T04:47:13.293 回答
3

与大多数其他答案似乎暗示的相反,这与类型无关,很容易推断(更不用说效率了)。这完全是关于作用域的明确语义。

在允许语言结构的非平凡嵌套的语言中,对变量所属的位置以及哪些标识符引用同一个变量有明确的规则很重要。为此,每个变量都需要一个明确的范围来定义它的可见位置。如果没有显式声明变量(无论有无类型注释),这在一般情况下是不可能的。

考虑一个简单的函数(您可以使用其他形式的嵌套范围构造类似的示例):

function f() {
  i = 0
  while (i < 10) {
    doSomething()
    i = i + 1
  }
}

function g() {
  i = 0
  while (i < 20) {
    f()
    i = i + 1
  }
}

怎么了?要告诉您,您需要知道i将在哪里绑定:在全局范围内还是在本地函数范围内?后者意味着两个函数中的变量是完全独立的,而前者将使它们共享——并且这个特定的示例永远循环(尽管全局范围可能是其他示例中的意图)。

对比上面的

function f() {
  var i = 0
  while (i < 10) {
    doSomething()
    i = i + 1
  }
}

function g() {
  var i = 0
  while (i < 20) {
    f()
    i = i + 1
  }
}

对比

var i

function f() {
  i = 0
  while (i < 10) {
    doSomething()
    i = i + 1
  }
}

function g() {
  i = 0
  while (i < 20) {
    f()
    i = i + 1
  }
}

这使得不同的可能含义非常清楚。

一般来说,没有好的规则能够(1)猜测程序员的真正意思,(2)在程序扩展或重构下足够稳定。程序越大、越复杂,情况就越糟糕。

避免多义性和令人惊讶的错误的唯一方法是要求变量的显式声明——这是所有合理的语言所做的。(这是语言设计 101,已经有 50 年了,不幸的是,这并不能阻止新一代的语言“设计者”一遍又一遍地重复同样的老错误,尤其是在所谓的脚本语言中。直到他们学会以艰难的方式吸取教训并纠正错误,例如 ES6 中的 JavaScript。)

于 2012-09-01T14:25:04.500 回答
2

编译器需要变量类型才能验证是否为变量分配了正确的值类型。潜在需求因语言而异。

于 2012-08-30T05:00:28.687 回答
2

这与类型没有任何关系。考虑 JavaScript,它有没有类型的变量声明:

var x = 8; y = 8;

原因是 JavaScript 需要知道您是在引用旧名称还是创建新名称。上面的代码将保留任何现有的 s 不变,但会破坏周围范围内x现有的旧内容。y

有关更广泛的示例,请参阅此答案

于 2012-08-31T01:01:29.387 回答
1

从根本上说,您正在比较两种类型的语言,一种由高级虚拟机或解释器(python、Mathematica ...)解释,另一种被编译为正在执行的本机二进制文件(C、C++ ...)一台物理机,很明显,如果您可以定义自己的虚拟机,那么您可以非常灵活地了解您的语言的动态性和强大程度,而物理机则非常有限,结构和基本指令集的数量非常有限等等.. ..

虽然确实某些编译为虚拟机或解释的语言仍然需要声明类型(java,C#),但这只是为了提高性能,想象一下必须在运行时推断类型或必须使用基类型每种可能的类型,这将消耗相当多的资源,更不用说很难实现将在本机运行某些东西的 JIT(即时编译器)。

于 2012-08-30T04:58:59.050 回答