在学生时代生涯,老师常常会说一个语言是强类型还是弱类型,比如认为C语言是强类型,Python/Js是弱类型语言;在工作后学习Golang时看到了一本书《Go语言设计与实现》(电子版链接:https://draveness.me/golang/)却说,C语言是弱类型语言,我把这个观点同同事以及在公司的教授分享沟通,发现大家对这个观点持有不同意见,在翻阅资料,搜索引擎后,我却也同意了C语言是弱类型语言这个观点,那么为什么说——C语言是弱类型语言呢?

1.强弱类型区别

首先我们明确无论是IEEE还是语言标准的协会也好,对强弱类型并没有一个明确的、权威的划分,对于强弱类型而言,我们往往同他的现象和特性中进行判断:

强类型:

在编译期间会有更加严格的类型限制,也就是编译器会在编译期间发现变量的赋值、返回值和函数调用时出现的类型错误。

弱类型:

弱类型的编程语言在出现类型错误可能会在运行时进行隐式类型转换,这可能会造成运行错误。

作为一种抽象定义,其语言使用者要想要区分强弱类型,更应该注意:

  • 类型的转换是显示的还是隐式的?
  • 编译器会帮助我们推断变量的类型么?

2.C语言特点

直接上一段C语言的代码分析。

#include<stdio.h>

int main(void) {
	char a='a';
	int b=10;
	int c=a+b;
	return 0;
}

上述C语言代码中,char类型和int类型是可以直接运算的,因为char类型会被提升为int类型,这其实是一种隐式类型转换,将精度小的转换为大的精度的。

再接着上一段代码

#include <stdio.h>

int main() {
    int a='abcd';
    putchar(a);
    return 0;
}

在这一段代码的输出结果中,显示是‘d’,而如果我们把int a='abcd';修改为int a='abcdf';,则会直接显示报错,提示我们

c:4:11: warning: multi-character character constant [-Wmultichar]
int a=’abcdf’;

而这类操作在其他的强类型语言中是无法做到的,顶多是一个int和float相加允许。

再进行一个补充:

int a = 0;
if(a) {
	
}

通过定义一个整形,让这个整形放入if中进行判断,在c语言中,是没有错误的可以通过,而再另一些语言,如Java和Golang中,则不行,会报错if只允许bool类型传入进行判断。

在《C专家编程》一书中,明确表达C是排斥强类型的,C的类型系统设计是为了作者区分硬件机器的不同数据类型(占用内存的子长)而非保护程序猿进行无效的操作。这一点也可以体现在Memset初始化非0,非1子节长度的数组的奇怪体验上。

虽然C语言是支持显示类型转换和隐式类型转换两种的,但是在一些特殊的应该传达出错误的场合,C语言却更加倾向于直接使用隐式类型转换专注于内存的实际情况,从这一点而言C语言是偏向于隐式的。

3.NULL思考——C语言与C++

NULL——空类型,其标准定义是:

#define NULL <either 0, 0L, or (void *)0> [0 in C++]

根据两行代码

  1. int n = NULL;
  2. int* p = NULL;

在C语言中,因为NULL类型是void*,他是一个万能指针类型,因此1不合法,不能将指针类型隐式的转换为整形,而2是合法的,void*隐式的允许转为任意类型指针

在C++中,由于禁止隐式的将void*转为任意其他的指针类型,所以为了让2合法,NULL类型被定义为了整形,同时也使得1合法化了。

从这一点可以看出,C语言的编译器在面对不同的类型时,选择采用void*万能类型去解释,而非具体的明确是什么基础变量,在Java,C# 等后来语言中,为了解决这一思维,又纷纷的创建了object这一概念来解决类型推断,也逐渐发展出了对象思维。

总结

从各种编程语言大概的一个分类常识而言,C语言的种种迹象确实让它有着属于符合弱类型的判断,因而我更加认可C语言是弱类型的这一观点,但在实际情况中,每一种语言都是有着各自不同的特点的,就像两栖动物的存在一样有着其自己的生态位,就C语言而言,其灵活的指针决定了它的生态位。过分追逐弱类型强类型是无意义的。

就拿Google:C is weakly typed? 来结束:

C is strongly typed in that the variable type must be specified when declaring the variable. However, C can also be regarded as weakly typed because users can convert data types through a cast and without compiler errors.

 

分类: C

0 条评论

发表回复

Avatar placeholder

您的电子邮箱地址不会被公开。 必填项已用*标注