引用维基百科:
支持多种隐式转换的两种常用语言是 C 和 C++,有时声称它们是弱类型语言。然而,其他人认为这些语言对如何混合不同类型的操作数施加了足够的限制,因此这两种语言应该被视为强类型语言。
有没有更确定的答案?
引用维基百科:
支持多种隐式转换的两种常用语言是 C 和 C++,有时声称它们是弱类型语言。然而,其他人认为这些语言对如何混合不同类型的操作数施加了足够的限制,因此这两种语言应该被视为强类型语言。
有没有更确定的答案?
“强类型”和“弱类型”是没有广泛认可的技术含义的术语。具有明确含义的术语是
动态类型意味着类型在运行时附加到值,尝试混合不同类型的值可能会导致“运行时类型错误”。例如,如果在 Scheme 中您尝试通过编写(+ 1 #t)
this 来为 true 加一,则会导致错误。仅当您尝试执行有问题的代码时才会遇到错误。
静态类型意味着在编译时检查类型,没有静态类型的程序会被编译器拒绝。例如,如果在 ML 中您尝试通过编写 来将 1 添加到 true 1 + true
,则程序将被拒绝并显示(可能是神秘的)错误消息。即使代码可能永远不会执行,您也总是会收到错误消息。
不同的人喜欢不同的系统,部分取决于他们对灵活性的重视程度以及对运行时错误的担忧程度。
有时“强类型”被松散地用来表示“静态类型”,而“弱类型”被错误地用来表示“动态类型”。术语“强类型”更好的用法是“你不能解决或颠覆类型系统”,而“弱类型”意味着“类型系统中存在漏洞”。相反,大多数具有静态类型系统的语言都有漏洞,而许多具有动态类型系统的语言则没有漏洞。
这些术语都没有以任何方式与语言中可用的隐式转换的数量相关联。
如果你想准确地谈论编程语言,最好避免使用“强类型”和“弱类型”这两个术语。我会说 C 是一种静态类型的语言,但它有很多漏洞。一个漏洞是您可以自由地将任何指针类型转换为任何其他指针类型。您还可以通过声明一个具有两个成员的 C 联合,在您选择的任何两种类型之间创建一个漏洞,每个成员对应一个所讨论的类型。
我在why-interpreted-langs-are-mostly-ducktyped-while-compiled-have-strong-typing上写了更多关于静态和动态类型的文章。
很难将每种语言分类为“弱”或“强”类型——它更像是一个连续体。但是,与其他语言相比,C 是相当强类型的。每个对象都有一个编译时类型,编译器会(大声地)让你知道,如果你正在对一个对象做一些它的类型不允许你做的事情。例如,您不能使用错误类型的参数调用函数、访问不存在的结构/联合成员等。
但也有一些弱点。一个主要的弱点是类型转换——它们本质上是说你会胡乱处理对象的类型,编译器应该保持安静(如果可以的话)。 void*
这也是另一个弱点——它是一个指向未知类型的通用指针,当你使用它们时,你必须格外小心,以确保你在做正确的事情。编译器无法静态检查void*
. void*
也可以在没有强制转换的情况下转换为指向任何类型的指针(仅在 C 中,而不在 C++ 中),这是另一个弱点。
C 被认为是弱类型,因为您可以通过强制转换将任何类型转换为任何其他类型,而不会出现编译器错误。您可以在此处阅读有关该问题的更多信息。
文献对此并不清楚。我认为强类型不是是/否,强类型有不同程度。
编程语言有一个关于它如何执行程序的规范。有时不清楚如何使用某些程序执行。例如,尝试从数字中减去字符串的程序。或除以零的程序。有几种方法可以处理这些情况。有些语言有处理这些错误的规则(例如它们抛出异常)。其他语言只是没有规则来处理这些情况。这些语言通常具有类型系统,以防止编译导致未指定行为的程序。并且还有一些语言具有未指定的行为并且没有类型系统来在编译时防止这些错误(如果您编写的程序遇到未指定的行为,它可能会发射导弹)。
所以:
指定每种情况下运行时发生的情况的语言(例如向字符串添加数字)称为动态类型。防止在编译时执行错误程序的语言是静态类型的。没有指定会发生什么并且没有类型系统来防止错误的语言称为弱类型。
那么Java是静态类型的吗?是的,因为它的类型系统不允许从数字中减去字符串。不,因为它允许您除以零。您可以使用类型系统在编译时防止除以零。例如,通过创建一个不能为零的数字类型(例如 NonZeroInt),并且只允许除以具有这种类型的数字。
那么C是强类型还是弱类型?C 是强类型的,因为类型系统不允许某些类型错误。但是在其他情况下,当它未定义会发生什么(并且类型系统不能保护您)时,它的类型很弱。
C 的类型比 Javascript 强,比 Ada 的类型弱。
我想说它更多地属于连续体的强类型方面。但其他人可能不同意(即使他们错了)。
怎么确定的?
C 被认为是静态类型的(您不能将变量从 int 更改为 float)。一旦声明了一个变量,它就会被卡住。
但它被认为是弱类型,因为类型可以翻转。
什么是0?'\0'、FALSE、0.0 等。
在许多语言中,您不能说 IF(变量),因为条件只会从布尔表达式中获取布尔值。这些是更强类型的。这同样适用于字符和整数之间的转换。
基本上 c 有两种主要的简单数据类型,整数和浮点数(尽管精度不同)。其他所有布尔值、枚举(不简单但很合适)等都作为其中之一实现。甚至字符基本上都是整数。
与存在字符串类型的其他语言相比,枚举类型只能分配给定义的值,布尔类型只能使用生成布尔值或真/假的表达式。
但是你可以争辩说,与 Perl C 相比,C 是强类型的。所以它是那些著名的论点之一(vi vs emacs,linux vs windows,等等)。C# 的类型比 C 强。基本上你可以争论任何一种方式。你的答案可能会是双向的 :) 还有一些教科书/网页会说 C 是弱类型的,有些人会说 C 是强类型的。如果你去维基百科,C 条目会说“部分弱类型”。我想说与 Python C 相比,C 是弱类型的。所以 Python/C#、C、Perl 在连续统一体上。
根据 Dennis Ritchie(C 的创建者)和 Brian Kernighan 的说法,C 不是强类型语言。以下几行来自《C 编程语言第 3 页第 5 段》一书
C 不是一种强类型语言,但随着它的发展,它的类型检查得到了加强。
这里有很多很好的答案。我想从Real World Haskell中提出一个重要的观点:
了解许多语言社区对“强类型”有自己的定义是很有用的。尽管如此,我们还是会简要而广泛地讨论类型系统中强度的概念。
(剪断)
类型系统周围的烟花起源于普通英语,人们对“弱”和“强”这两个词赋予价值观念:我们通常认为强胜于弱。更多的程序员说简单的英语而不是学术术语,而且很多时候,学者们真的在向任何不适合他们喜欢的类型系统扔砖头。结果往往是那种流行的网络消遣,一场火焰大战。
因此,请查看有关 C 和 C++ 的答案,但请记住,“强”和“弱”并不对应于“好”和“坏”。
在我看来,C/C++ 是强类型的。允许类型转换(void *)的黑客类型存在,因为 C 与机器的接近。换句话说,您可以从 Pascal 调用汇编程序命令并操作指针,并且 Pascal 仍然被认为是一种强类型语言。您可以通过 JNI 从 Java 调用汇编程序和 C 可执行文件,但它不会使 Java 成为弱类型。
C 只是在其中“嵌入”了带有原始指针等的汇编程序。
术语强类型没有一个公认的定义。因此,除非您定义“强类型”的含义,否则无法回答您的问题。
以我的经验,“强类型”和“弱类型”这两个术语仅由巨魔使用,因为它们缺乏定义允许巨魔重新定义它们以适应他们的议程。除了开始激烈的战争之外,这些术语几乎没有用。
您可能还想看看强类型语言的关键方面是什么?在 StackOverflow 上。
在“弱类型”和“强类型”之间存在多个并行途径的连续统一体,这两个术语甚至都没有很好的定义。
C 是静态类型的,因为编译器知道每个局部变量和结构成员的声明类型是什么。
如果每个对象都有特定类型但编译器无法知道该类型,则动态类型语言可能仍然是强类型的。
不是强类型。
考虑以下函数原型告诉您参数的数据类型:
void func (int n, char ch, ...);
没有。所以我建议强类型在这里不适用。
您查询的原因是什么?我问的原因是这是一个很小的区别,您对“强类型”的特殊用法可能需要或多或少的澄清。我肯定会说 Java 和其他语言对隐式类型对话有更严格的限制。
当没有“强类型”的具体定义时,很难提供具体的答案。我会说 C 是强类型的,因为每个变量和每个表达式都有一个类型,但弱类型是因为它允许您使用强制类型转换来更改类型并将一种类型的表示重新解释为另一种类型。
我会说 C 的类型与您的编译器/平台要求的一样强。例如,如果您在严格的平台上构建,取消引用类型双关指针可能会中断:
void m_free(void **p)
{
if (*p != NULL) {
free(*p);
*p = NULL;
}
}
....
char *str = strdup("foo");
m_free((void **) &foo);
现在,如果您告诉编译器跳过严格的别名,这将不是问题,但不是很便携。所以,从这个意义上说,突破语言的界限是可能的,但可能不是最好的主意。这超越了典型的铸造,即铸造 int as long 并且确实显示了 void 可能的陷阱之一。
所以,我想说 C 基本上是严格类型的,但它的各种编译器假定程序员最了解并允许一定的灵活性。这真的取决于编译器,有些人不会接受那些潜在的 oops。所以从这个意义上说,选择的编译器在回答问题时确实发挥了作用。正确的通常与您的编译器允许您摆脱的不同。
c 是弱类型,b 是无类型。
我会说它是强类型,因为每个表达式都有一个不是它的值的函数的类型;ei 它可以在运行前知道。
OTOH 我不确定这是对强类型的正确描述。我能看到的唯一更强有力的主张是保证你不能在运行时通过重新解释类型转换、联合、调用其他语言、指针、汇编语言等来颠覆类型系统。像这样的语言存在但如此残缺,以至于除了高度保证和学术界之外的程序员似乎对它们没有太大兴趣。正如有人指出的那样,要真正做到这一点,您开始需要拥有nonZeroInt
诸如此类的类型。呸。