有人会用c语言做吗,真的好多没学啊,做出来不完整老是提示出错,结果运行不出来,就是不会做c语言
低级语言的一个关键属性是程序员可以很容易地理解语言的抽象机如何映射到底层物理机。在 PDP-11 上肯定是这样的,因为每个 C 语言表达式都映射到一至两个指令。类似地,编译器将局部变量直接降到栈槽,并将原始类型映射成 PDP-11 可以直接操作的元素。
从那时起,为了维护人们对 C 语言可以很容易映射到底层硬件并能够提供快速执行的代码的印象,C 语言的实现变得越来越复杂。2015 年的一份针对 C 语言程序员、编译器开发者和标准委员会成员的调查指出了几个有关 C 语言可理解性的问题。例如,C 语言的实现可以填充结构体(不是数组),以确保所有字段都能够对齐目标。如果将结构体归零,然后设置一些字段,那么填充位是否都为零?根据调查结果,36%的人表示会是零,29%的人表示不知道。事实上,根据编译器(和优化级别)的不同,它可能是也可能不是。
这是一个相当简单的例子,但很大一部分程序员的理解要么是错的,要么不确定。当你在使用指针时,C 语言的语义就会变得更加混乱。BCPL 模型非常简单:值就是单词。每个单词就是某些数据或某些数据的地址。内存是通过地址进行索引的扁平存储单元阵列。
相比之下,C 语言模型允许在各种目标平台上实现,包括分段式架构(指针可能是分段 ID 和偏移量),甚至是基于垃圾回收机制的虚拟机。C 语言规范十分谨慎地限制对指针的操作,以避免此类系统出现问题。人们对 C 语言缺陷报告 260 的反应就包括了指针起源(provenance)的概念。
然而,“起源”这个词根本没有出现在 C11 规范中,所以完全由编译器来决定它的含义。例如,GCC(GNU 编译器集合)和 Clang 在对指针进行强制转换是否保留起源这个问题上存在不同的理解。编译器可以自由决定指向不同 malloc 结果或栈分配的两个指针总是不相等,即使指针的按位比较操作可能显示它们描述的是相同的地址。
这些误解本质上不是纯粹的学术问题。例如,我们已经从有符号整数溢出(C 语言的未定义行为)和一些代码中找到了安全漏洞。对于后者,在进行空值检查之前取消引用指针是在告诉编译器指针不能为空,因为取消引用空指针在 C 语言中是未定义行为,因此可以假定这种情况不会发生(https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-1897)。
因此,我们很难说程序员可以准确理解 C 语言程序将如何映射到底层架构。