C语言 C 作为“低级”语言有多“低”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/5020246/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How "low" does C go as a "low-level" language?
提问by eric.christensen
We often hear that C is a low-level language, but how low does it go? The lowest level I am aware of is memory management using pointers. Are there further levels I have yet to discover? What does "close to the hardware" mean? How "close to the hardware" is C?
我们经常听说C是低级语言,但到底低到什么程度呢?我所知道的最低级别是使用指针进行内存管理。是否还有我尚未发现的更深层次?“接近硬件”是什么意思?C 有多“接近硬件”?
回答by Edwin Buck
Use the standard terminology. Higher level languages and Lower level languages.
使用标准术语。高级语言和低级语言。
High level languages are designed for the ease of the person writing the language.
高级语言是为方便编写语言的人而设计的。
Lower level languages are designed for the ease of the computer running the language.
较低级别的语言旨在使计算机运行该语言的便利性。
C is just a step up from assembly language, which is practically a human translation of machine code. It doesn't get any lower than machine code, but people don't read hexadecimal very well, so assembly is considered the lowest level programming language.
C 只是汇编语言的一个进步,汇编语言实际上是机器代码的人工翻译。它并不比机器代码低,但是人们不太会阅读十六进制,因此汇编被认为是最低级别的编程语言。
Most C operations can be translated into less than ten machine instructions. Some can be translated into a single machine instruction (depending on many circumstances). By comparison, many high-level languages might require dozens to thousands of machine instructions to implement a particular operation.
大多数 C 操作可以翻译成不到 10 条机器指令。有些可以翻译成单个机器指令(取决于许多情况)。相比之下,许多高级语言可能需要数十到数千条机器指令来实现特定操作。
The "level" of a language is mostly an abstract concept. It is not useful for much except comparing one language to another in the context of trying to understand if you will have to write more source code in one or another, or if you will have to know more about the machine's architecture in one language as compared to another.
语言的“层次”多半是一个抽象的概念。除了在尝试理解您是否必须用一种或另一种语言编写更多源代码的上下文中将一种语言与另一种语言进行比较之外,它没有多大用处,或者如果相比之下,您是否必须更多地了解一种语言的机器架构到另一个。
回答by KeithS
C is little more than a procedural wrapper around ASM. A good C programmer, who knows what's behind that language, should be able to look at a code snippet and write out the ASM that the code would compile into. Those ASM instructions can be translated 1:1 to binary machine instructions. It's pretty much one step above assembly, and as such you can write C code that does ANYTHING the computer is capable of, BUT, being at such a low level, it is relatively primitive in terms of what you have to be specific about. For instance, memory is treated as such, and not abstracted into constructs like the "heap". Creating a "new" object in an OO language is as simple as saying so; the equivalent C code would involve a malloc for the sum of the size of all the members of that object, and pointers to each of the object's members within the block.
C 只不过是 ASM 的程序包装器。一个优秀的 C 程序员,知道该语言背后是什么,应该能够查看代码片段并写出代码将编译成的 ASM。这些 ASM 指令可以 1:1 转换为二进制机器指令。它几乎比汇编高一步,因此您可以编写计算机能够完成的任何事情的 C 代码,但是,在如此低的级别上,就您必须具体说明的内容而言,它相对原始。例如,内存是这样处理的,而不是抽象成像“堆”这样的结构。用 OO 语言创建一个“新”对象就是这么简单;等效的 C 代码将涉及用于该对象所有成员的大小总和的 malloc,以及指向每个对象的指针'
回答by bta
C is sometimes referred to as "portable assembly language". Essentially anything that you can do in assembly, you can do in C (either through features built into the language or through inline assembly).
C 有时被称为“便携式汇编语言”。基本上你可以在汇编中做的任何事情,你都可以在 C 中做(通过语言内置的功能或通过内联汇编)。
回答by Mr Coder
A person who creates hardware (cpu, motherboard, etc) also provide its machine language (assembly language). That becomes the lowest level itself. Then some other person writes a compiler for C which converts C syntax into native assembly language for that hardware (please correct me if I am wrong). With C you can use assembly hence lowest level reached!!
创建硬件(cpu、主板等)的人也提供其机器语言(汇编语言)。这本身就成为最低级别。然后其他人为 C 编写了一个编译器,它将 C 语法转换为该硬件的本地汇编语言(如果我错了,请纠正我)。使用 C,您可以使用汇编,因此达到最低级别!!
回答by Kevin Sylvestre
The definition of 'low' is a bit difficult, but C supports an number of system calls, gotos, and even assembly mixing through extensions.
'low' 的定义有点困难,但 C 支持许多系统调用、goto,甚至通过扩展进行程序集混合。
回答by peoro
You need to define what you mean by low levelin order to answer this question.
您需要定义低级别的含义才能回答这个问题。
C lets you do kind of everything you could do with assembly, but well not everything. If you want to do something weird/particular/unusual you could need to use assembly, although for most(/all?) real purposes C will be more then enough, assuming you've got a good compiler for your hardware.
C 可以让你做任何你可以用汇编做的事情,但不是所有的事情。如果你想做一些奇怪/特殊/不寻常的事情,你可能需要使用汇编,尽管对于大多数(/所有?)真正的目的,C 将足够了,假设你的硬件有一个很好的编译器。
EDIT: Elaborating this a little further...
编辑:进一步阐述这一点......
C doesn't give you any guarantee about the assembly instruction it will be compiled into, and only gives some partial indications about objects will be allocated in memory.
C 不给你任何关于它将被编译成的汇编指令的保证,并且只给出一些关于对象将在内存中分配的部分指示。
In general If you need to have stuff in memory in a particular way, of if you need a particular sequence of assembly instruction to be ran, you'll probably have to use some other language (probably assembly directly), otherwise in generalC will be fine.
一般来说,如果您需要以特定方式在内存中存储内容,或者如果您需要运行特定的汇编指令序列,您可能必须使用其他语言(可能直接汇编),否则通常C 会没事的。
Of course we can find as many special cases as we want to: if your has got some special assembly operations that let you do fancy high levelstuff, C won't probably be able to exploit these.
当然,我们可以找到尽可能多的特殊情况:如果您有一些特殊的汇编操作,可以让您做一些高级别的东西,C 可能无法利用这些。
C has been thought to replace assembly on normal(maybe I could say general purpose) processors, it won't be ideal on processors with a native functional assembly or in many other contexts.
C 被认为在普通(也许我可以说是通用)处理器上替换程序集,它在具有本机功能程序集的处理器或许多其他上下文中并不理想。
You cannot just say "how level is C?", you need to do the opposite: define what kind of low levelstuff you need and then see if C is able to do that.
你不能只说“C 的级别如何?”,你需要做相反的事情:定义你需要什么样的低级别的东西,然后看看 C 是否能够做到这一点。
回答by nos
The memory you can manage on general purpose OS' are usually virtual memory, so it usually all a fraud - your C pointers doesn't contain the physical memory addresses, there's a whole layer deeper than that.
您可以在通用操作系统上管理的内存通常是虚拟内存,因此通常都是骗局——您的 C 指针不包含物理内存地址,还有一整层比这更深。
Getting below that requires you to program the MMU, which isn't easily done in C, it usually requires some very architecture dependant assembly and your code would need to run in some form of privileged mode(as the OS kernel does)
低于它需要您对MMU进行编程,这在 C 中不容易完成,它通常需要一些非常依赖于体系结构的程序集,并且您的代码需要以某种形式的特权模式运行(就像操作系统内核一样)
There might also be various other co-processorsor whole range of instruction setsit can be hard to get at directly in C.
回答by Daniel Earwicker
How about register? A keyword on a local variable declaration that asks the compiler to store it in a CPU register - though it may ignore your suggestion.
怎么样register?局部变量声明上的关键字,要求编译器将其存储在 CPU 寄存器中 - 尽管它可能会忽略您的建议。
However, GNU C extends this to the point where you can specify a particular register you'd like to use!
但是,GNU C 对此进行了扩展,您可以指定要使用的特定寄存器!
register int foo asm ("a5");
回答by Tommy
The main thing that C obscures, to the extent that it obscures anything at all, is flow control, in a few edge cases. The only thing I've ever written in assembly that didn't translate well to C involved hopping into a block of code at an arbitrary point, having it execute from that position, periodically checking a certain status condition and upon finding the need, storing the current program location somewhere and exiting. Then next time, I jumped back in at the same position as that block of code last exited. Co-operative coroutines, I guess you'd call them.
在一些边缘情况下,C 所掩盖的主要事情是流控制,以至于它掩盖了任何事物。我曾经用汇编语言编写的唯一不能很好地转换为 C 的内容涉及在任意点跳转到代码块,让它从该位置执行,定期检查某个状态条件并在发现需要时,存储某处的当前程序位置并退出。然后下一次,我跳回与上次退出的代码块相同的位置。合作协程,我想你会打电话给他们。
The C solution was to use two separate threads, communicating via semaphores. But threads aren't part of the C language itself.
C 解决方案是使用两个单独的线程,通过信号量进行通信。但是线程不是 C 语言本身的一部分。
回答by Will Hartung
C today is used in many cases as a "portable assembly language" because the semantics of the language can be pretty much just a thin veneer above the underlying machine architecture.
今天的 C 在许多情况下被用作“可移植汇编语言”,因为该语言的语义几乎只是底层机器架构之上的一层薄薄的饰面。
In the past, it was fairly straight forward to look at lines of C code and have a good idea what the actual machine language would be that the C code would generate.
在过去,查看 C 代码行并很好地了解 C 代码将生成的实际机器语言是什么是相当直接的。
When taken in it entirety along with its surrounding development environment, it is straightforward to have perfect control over memory layout of data structures and overall memory placement. Mind, this kind of C code is, as a whole, non portable as it relies on implementations details of the compiler that the C standard allows to be flexible and implementation based. But in the large, the C code itself can be MOSTLY portable. This is aspect of the language is what led to its popularity in such systems as Unix in allowing the bulk of the OS to be portable across machines with as little implementation specific aspects of an implementation being in, say, assembly language, as possible.
当连同其周围的开发环境一起考虑时,可以直接完美地控制数据结构的内存布局和整体内存布局。请注意,这种 C 代码作为一个整体是不可移植的,因为它依赖于 C 标准允许灵活且基于实现的编译器的实现细节。但总的来说,C 代码本身在很大程度上是可移植的。正是这种语言的这一方面导致了它在诸如 Unix 之类的系统中的流行,因为它允许大部分 OS 可以跨机器移植,而实现的实现特定方面尽可能少,例如,汇编语言。
Today, with modern compilers and their optimizations, C can be less literal. What you see in the C code may not be translated literally in to what you get in the assembly because of the actual optimizations made by the compiler.
今天,有了现代编译器及其优化,C 可以不那么直白了。由于编译器进行了实际优化,您在 C 代码中看到的内容可能不会按字面意思转换为您在程序集中得到的内容。
A simple contrived example is something like:
一个简单的人为例子是这样的:
int func(int a, int b) {
int c;
int d;
d = 10;
return a * d;
}
In a simple compiler, an implementation may well allocate 4 int's on the stack, 2 for the arguments, and 2 for the work variables. An obvious optimization is to not allocate the 'c' variable at all, as it is unused. A further optimization is to ignore 'd' as well, and simply use the constant 10. And even smarter compiler may well see how this func is being used and inline it automatically in the calling function, eliminating the subroutine call completely.
在一个简单的编译器中,一个实现可能会在堆栈上分配 4 个 int,2 个用于参数,2 个用于工作变量。一个明显的优化是根本不分配 'c' 变量,因为它没有被使用。进一步的优化是也忽略 'd',并简单地使用常量 10。即使更聪明的编译器也可能会看到这个 func 是如何使用的,并在调用函数中自动内联它,完全消除子例程调用。
So, on the one hand you can see the code and say "this is what it will look like in assembly", and thus treat it as a low level wrapper on top of assembly. On the other, you can turn the modern compilers optimizations up so that they are less literal, thus keeping the semantics of what you're expressing in code, if not the actual perfect implementation.
因此,一方面您可以看到代码并说“这就是它在汇编中的样子”,从而将其视为汇编之上的低级包装器。另一方面,您可以将现代编译器的优化调高,使它们的文字更少,从而保持您在代码中表达的语义,如果不是实际的完美实现。

