简体   繁体   English

用C语言定义函数printf

[英]definition of function printf in C language

I have read that C language does not include instructions for input and for output and that printf, scanf, getchar, putchar are actually functions. 我已经读过C语言不包含用于输入和输出的指令,并且printf,scanf,getchar和putchar实际上是函数。

Which are the primitive C language instructions to obtain the function printf , then? 那么,获得功能printf的原始C语言指令是哪些? Thank you. 谢谢。

If you want to use printf , you have to #include <stdio.h> . 如果要使用printf ,则必须#include <stdio.h> That file declares the function. 该文件声明了该功能。

If you where thinking about how printf is implemented: printf might internally call any other functions and probably goes down to putc (also part of the C runtime) to write out the characters one-by-one. 如果您在考虑如何实现printf:printf可能会在内部调用任何其他函数,并且可能会进入putc (也是C运行时的一部分)来逐个写出字符。 Eventually one of the functions needs to really write the character to the console. 最终,其中一个功能需要真正将字符写入控制台。 How this is done depends on the operating system. 如何完成此操作取决于操作系统。 On Linux for example printf might internally call the Linux write function. 例如,在Linux上, printf可能会在内部调用Linux write函数。 On Windows printf might internally call WriteConsole . 在Windows上, printf可能在内部调用WriteConsole

The function printf is documented here ; 函数printf记录在这里 in fact, it is not part of the C language itself. 实际上,它不是C语言本身的一部分。 The language itself does not provide a means for input and output. 语言本身不提供输入和输出的手段。 The function printf is defined in a library, which can be accessed using the compiler directive #include <stdio.h> . 函数printf在库中定义,可以使用编译器指令#include <stdio.h>进行访问。

No programming language provides true "primitives" for I/O. 没有一种编程语言为I / O提供真正的“基元”。 Any I/O "primitives" rely on lower abstraction levels, in this language or another. 任何I / O“原语”都依赖于较低的抽象级别,无论是这种语言还是另一种语言。

I/O, at the lowest level, needs to access hardware. 最低级别的I / O需要访问硬件。 You might be looking at BIOS interrupts, hardware I/O ports, memory-mapped device controlers, or something else entirely, depending on the actual hardware your program is running on. 您可能正在查看BIOS中断,硬件I / O端口,内存映射的设备控制程序或其他所有内容,具体取决于程序所运行的实际硬件。

Because it would be a real burden to cater for all these possibilities in the implementation of the programming language , a hardware abstraction layer is employed. 由于在编程语言的实现中满足所有这些可能性将是一个真正的负担,因此采用了硬件抽象层 Individual I/O controllers are accessed by hardware drivers, which in turn are controlled by the operating system, which is providing I/O services to the application developer through a defined, abstract API. 各个I / O控制器由硬件驱动程序访问,而硬件驱动程序又由操作系统控制,操作系统通过定义的抽象API向应用程序开发人员提供I / O服务。 These may be accessed directly (eg by user-space assembly), or wrapped further (eg by the implementation of a programming language's interpreter, or standard library functions). 这些可以直接访问(例如,通过用户空间组装),也可以进一步包装(例如,通过编程语言的解释器或标准库函数的实现)。

Whether you are looking at "commands" like (bash) echo or (Python) print , or library functions like (Java) System.out.println() or (C) printf() or (C++) std::cout , is just a syntactic detail: Any I/O is going through several layers of abstraction, because it is easier, and because it protects you from all kinds of erroneous or malicious program behaviour. 无论您正在查看的是“ bash” echo或“ Python” print类的“命令”,还是诸如(Java) System.out.println()或(C) printf()或(C ++) std::cout类的库函数,只是一个语法上的细节:任何I / O都要经历几层抽象,因为它更容易,并且因为它可以保护您免受各种错误或恶意程序行为的侵害。

Those are the "primitives" of the respective language. 这些相应语言的“原始语”。 If you're digging down further, you are leaving the realm of the language, and enter the realm of its implementation . 如果您要进一步研究,您将离开该语言的领域,并进入其实现的领域。


I once worked on a C library implementation myself. 我曾经亲自进行过C库实现。 Ownership of the project has passed on since, but basically it worked like this: 此后,该项目的所有权就已经转移了 ,但是基本上它是这样工作的:

  • printf() was implemented by means of vfprintf() (as was, eventually, every function of the *printf() family). printf()是通过printf()实现的vfprintf()最终, *printf()系列的每个函数也是如此)。
  • vfprintf() used a couple of internal helpers to do the fancy formatting, writing into a buffer. vfprintf()使用了几个内部助手来进行精美的格式化,并将其写入缓冲区。
  • If the buffer needed to be flushed, it was passed to an internal writef() function. 如果需要刷新缓冲区,则将其传递给内部writef()函数。
  • this writef() function needed to be implemented differently for each target system. 对于每个目标系统,都需要以不同的方式实现该writef()函数。 On POSIX, it would call write() . 在POSIX上,它将调用write() On Win32, it would call WriteFile() . 在Win32上,它将调用WriteFile() And so on. 等等。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM