是C强类型?

时间:2009-01-09 23:54:48

标签: c strong-typing weakly-typed

引用Wikipedia

  

两种常用语言   支持多种隐含   转换是C和C ++,它是   有时声称这些是   弱类型语言。然而,   其他人认为这些语言   对如何设置足够的限制   不同类型的操作数可以   混合,这两个应该被视为   作为强类型语言。

是否有更确定的答案?

17 个答案:

答案 0 :(得分:138)

“强类型”和“弱类型”是没有广泛认可的技术含义的术语。具有明确定义的术语是

  • 动态类型表示类型在运行时附加到值,并且尝试混合不同类型的值可能会导致“运行时类型错误”。例如,如果在Scheme中尝试通过编写(+ 1 #t)将其添加为true,则会导致错误。只有在尝试执行有问题的代码时才会遇到错误。

  • 静态类型表示在编译时检查类型,编译器拒绝不具有静态类型的程序。例如,如果在ML中尝试通过编写1 + true将其添加为true,则程序将被拒绝(可能是神秘的)错误消息。即使代码可能永远不会被执行,您也总是会收到错误。

不同的人更喜欢不同的系统,部分原因在于他们对灵活性的重视程度以及他们对运行时错误的担忧程度。

有时“强类型”用于表示“静态类型”,而“弱类型”用于表示“动态类型”。更好地使用术语“强类型”是“你不能解决或破坏类型系统”,而“弱类型”意味着“类型系统中存在漏洞”。反过来说,大多数静态类型系统的语言存在漏洞,而动态类型系统的许多语言都没有漏洞。

这些术语均未以任何方式与语言中可用的隐式转换数相关联。

如果您想精确地谈论编程语言,最好避免使用“强类型”和“弱类型”这两个术语。我会说C是一种静态类型但有很多漏洞的语言。一个漏洞是你可以自由地将任何指针类型转换为任何其他指针类型。您还可以通过声明具有两个成员的C联合来创建您选择的任何两种类型之间的漏洞,每个成员对应一种类型。

我在why-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typing撰写了更多关于静态和动态类型的文章。

答案 1 :(得分:21)

很难将每种语言分为“弱”或“强”类型 - 它更像是一个连续统一体。但是,与其他语言相比,C的输入相当强。每个对象都有一个编译时类型,编译器会让你知道(大声)你是否正在使用其类型不允许你做的对象。例如,您不能使用错误类型的参数调用函数,访问不存在的struct / union成员等。

但是有一些弱点。一个主要的弱点是类型转换 - 他们基本上说你将会使用对象的类型,并且编译器应该是安静的(如果可以的话)。 void*也是另一个弱点 - 它是指向未知类型的通用指针,当你使用它们时,你必须格外小心,你正在做正确的事情。编译器无法静态检查void*的大多数用法。 void*也可以转换为指向任何类型的指针而不使用强制转换(仅在C中,而不是在C ++中),这是另一个弱点。

答案 2 :(得分:11)

C被认为是弱类型的,因为您可以通过强制转换将任何类型转换为任何其他类型,而不会出现编译器错误。您可以详细了解该问题here

答案 3 :(得分:9)

文献对此并不清楚。我认为强类型不是/不是,有不同程度的强类型。

编程语言具有如何执行程序的规范。有时不清楚如何执行某些程序。例如,尝试从数字中减去字符串的程序。或者除以零的程序。有几种方法可以处理这些情况。有些语言有处理这些错误的规则(例如,它们会抛出异常)。其他语言没有处理这些情况的规则。这些语言通常具有类型系统,以防止编译导致未指定行为的程序。并且还存在具有未指定行为的语言,并且没有类型系统来在编译时防止这些错误(如果编写的程序遇到未指定的行为,则可能会启动导弹)。

所以:

指定在每种情况下在运行时发生的事情的语言(如向字符串添加数字)都被称为动态类型。 在编译时阻止执行程序错误的语言是静态类型的。 没有指定发生的事情并且没有类型系统来防止错误的语言被称为弱类型。

Java静态类型化吗?是的,因为它的类型系统不允许从数字中减去字符串。不,因为它允许你除以零。您可以在编译时使用类型系统防止除零。例如,通过创建一个不能为零的数字类型(例如NonZeroInt),并且只允许除以具有此类型的数字。

C是强类型还是弱类型? C是强类型的,因为类型系统不允许某些类型错误。但是在其他情况下,如果未定义会发生什么(并且类型系统不能保护您),它会被弱类型化。

答案 4 :(得分:7)

C的输入强度大于Javascript,输入的强度低于Ada。

我会说它更多地落入连续体的强类型方面。但是其他人可能不同意(即使他们错了)。

如何确定?

答案 5 :(得分:4)

这里有很多好的答案。我想从Real World Haskell

提出一个重点
  

要注意许多语言社区都有自己的定义,这很有用   “强势型”。尽管如此,我们将简要地和广义地谈论类型系统中的强度概念。

(剪断)

  

类型系统周围的烟花源于普通的英语,人们将有价值的概念附加到“弱”和“强”的词语中:我们通常认为力量优于弱点。更多的程序员说普通英语而不是学术术语,而且学术界人士通常都会在任何不适合自己喜欢的类型系统中投掷砖块。结果往往是流行的互联网消遣,一场火焰战。

所以,看看关于C和C ++的答案,但要记住'强'和'弱'不会映射到'好'和'坏'。

答案 6 :(得分:4)

C被认为是静态类型的(您不能将变量从int更改为float)。一旦变量被声明,它就会被卡住。

但它被认为是弱类型的,因为类型可以被翻转。

什么是0? '\ 0',FALSE,0.0等。

在许多语言中你不能说IF(变量),因为条件只会从布尔表达式中获取布尔值。这些更强类型。这同样适用于字符和整数之间的转换。

基本上c有两个主要的简单数据类型,整数和浮点数(虽然各种精度)。其他所有布尔值,枚举(不简单但适合)等都是作为其中之一实现的。甚至字符基本上都是整数。

与其他存在字符串类型的语言相比,枚举类型只能分配给定义的值,布尔类型只能使用生成布尔值或true / false的表达式。

但你可以说,与Perl C相比,它是强类型的。所以这是其中一个着名的论点(vi vs emacs,linux vs windows等)。 C#比C更强类型。基本上你可以争论任何一种方式。你的答案可能会双管齐下:)另外一些教科书/网页会说C是弱类型的,有些人会说C是强类型的。如果你去维基百科,C条目说“部分弱打字”。我会说与Python C相比,它是弱类型的。所以Python / C#,C,Perl就是连续统一体。

答案 7 :(得分:2)

根据Dennis Ritchie(C 的创建者)和Brian Kernighan的说法,C不是强类型语言。以下几行来自本书 The C programming language 第3页第5段

  

C不是一种强类型语言,但随着它的发展,其类型检查得到了加强。

答案 8 :(得分:2)

在我看来,C / C ++是强类型的。由于C与机器的接近程度,允许转换类型的hack类型(void *)存在。换句话说,您可以从Pascal调用汇编程序命令并操作指针,而Pascal仍然被视为强类型语言。您可以通过JNI从Java调用汇编程序和C可执行文件,但它不会使Java键入弱。

C只是用原始指针等“嵌入”汇编程序。

答案 9 :(得分:2)

术语强类型没有商定的定义。因此,除非您通过“强类型”定义意思的内容,否则无法回答您的问题。

根据我的经验,巨魔使用“强类型”和“弱类型”这两个术语 ,因为它们缺乏定义,允许巨魔在争论中重新定义它们以适合他们的议程。除了启动火焰战之外,这些术语几乎没用。

您可能还想在StackOverflow上查看What are the key aspects of a strongly typed language?

答案 10 :(得分:1)

在“弱类型”和“强类型”之间存在多个平行途径的连续统一体,这两个术语甚至没有明确定义。

C是静态类型,因为编译器知道每个局部变量和结构成员的声明的类型是什么。

动态类型语言可能仍然是强类型的,如果每个对象都有特定的类型,但编译器无法知道该类型。

答案 11 :(得分:1)

c是弱类型,b是无类型。

答案 12 :(得分:0)

我想说C和你的编译器/平台所强加的类型一样强。例如,如果您在严格的平台上构建,则取消引用类型惩罚指针可能会破坏:

void m_free(void **p)
{
        if (*p != NULL) {
                free(*p);
                *p = NULL;
        }
}

....
char *str = strdup("foo");
m_free((void **) &foo);

现在,如果您告诉编译器跳过严格别名,那么这将是一个非问题,但不是非常便携。因此,从这个意义上说,推动语言的界限是可能的,但可能不是最好的主意。这比典型的铸造更进了一步,即铸造int很长时间,并且真正显示出一个可能的无效陷阱。

所以,我会说C基本上是严格打字的,但它的各种编译器都假定程序员最了解并允许一些灵活性。这实际上取决于编译器,有些人不会接受这种潜在的oops。所以从这个意义上讲,选择的编译器在回答问题时确实起了作用。什么是正确的通常不同于您的编译器将允许您逃脱。

答案 13 :(得分:0)

当没有“强类型”的具体定义时,很难提供具体的答案。我会说C是强类型的,因为每个变量和每个表达式都有一个类型但是弱类型,因为它允许你使用强制转换来改变类型,并将一种类型的表示重新解释为另一种。

答案 14 :(得分:0)

您查询的原因是什么?我问的原因是这是一个微小的差异,你对“强类型”的特殊用法可能需要或多或少的澄清。我肯定会说Java和其他语言对隐式类型会话有更严格的限制。

答案 15 :(得分:-1)

没有强烈输入。

考虑以下函数原型告诉您关于参数的数据类型的内容:

void func (int n, char ch, ...);

无。所以我建议强类型不适用于此。

答案 16 :(得分:-3)

我会说它是强类型的,因为每个表达式的类型都不是它的值的函数; E.I.它可以在运行时之前知道。

OTOH我不确定这是强类型的正确描述。我能看到语言产生原因的唯一更强有力的说法就是保证你不能在运行时通过重新解释类型转换,联合,调用其他语言,指针,汇编语言等来破坏类型系统。这样的语言存在但是如此瘫痪,以至于他们似乎对高保证和学术界以外的程序员不太感兴趣。正如某人所指出的那样,为了真正做到这一点,你需要开始使用类似nonZeroInt和诸如此类的东西。呸。