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