【纯干货】深度底层剖析,你所不知道的printf

文章目录

注意

视频

再观printf函数

print为什么要加个f

格式符是什么时候被解析的?

如何实现变参函数

来实现一个printf吧

printf是否有检测功能

printf只能输出在命令行吗

结语

注意

本文为针对C语言的基础技术向,更适合刚入门需要进阶的同学技术进阶使用,当然我会尽量用简单的语言让哪怕是初学者也可以看得懂,核心知识有如下部分:

变参函数的概念和使用

__attribute__(())的概念和使用

printf函数的实现

视频

本文可以结合视频一起食用,效果更佳:视频链接

再观printf函数

相信绝大部分同学写的第一个程序,应该就是大名鼎鼎的Hello World程序了,这个程序闻名于著名的《C语言程序设计(The C Programming Language)》(C语言之父丹尼斯·里奇(Dennis Ritchie)著)一书中,非常经典,以至于程序员们学习任何语言,都会先用这个语言运行个Hello World出来。

在C语言中,这个程序一般写出来是这个样子的:

#include

int main()

{

printf("Hello World!\n");

return 0;

}

如果在命令行运行这个程序的话,你将获得一行Hello World!输出。

如果你是一个不喜欢思考的初学者,可能会认为printf也许是C语言里面最基础最简单的函数了,毕竟这个程序这么简洁、格式这么规范、使用这么简单、甚至闭着眼睛都不会写错。

但如果我们往细究往深了想呢?printf它是如何实现的呢?我们是否可以实现一个自己的printf函数呢?为什么它会运行在命令行中而不是从屏幕某个规定的位置显示呢……

这时你可能会发现,woc,printf似乎比我们想象的要复杂太多了,你以为的简单小函数,其实却是个超级大boss。不过不要担心,我们会从基础开始讲,而且我会保证尽量说得简单明了。

print为什么要加个f

现在,我们重新抱着认真学习的态度来观察printf这个函数吧。首先我们从名字来解析一下。

我们知道,在英语中,print有打印、印刷的意思,这个词语完全可以解释将字符串打印到电脑屏幕上这个过程,那么为什么这个函数的名字要加上f呢?

其实这个f是format的缩写,即格式化的意思,printf其实为格式化打印的意思。那么格式化这个是怎么来的?

现在想想,如果我们希望在屏幕上输出一个变量该怎么做呢?最简单的方法就是使用格式字符,就如下面这个程序一样:

#include

int main()

{

int a = 25;

printf("a = %d\n", a);

return 0;

}

这个函数将会在屏幕上输出一行a = 25,在这个过程中%d就是变量a的格式符,它在字符串中占位,然后字符串在输出的时候,遇到了这个占位符,就会解析a的具体值,并把它转换为字符串的形式输出出来。

现在从这个功能中我们其实可以发现很多问题,我们来逐一解释:

格式符是什么时候被解析的?

这个问题是我在学习理解printf的时候第一个思考的问题,即格式符是如何什么时候被解析的,答案有两种,对应了两种不同的结果。

首先是在编译阶段被解析,这种方式的话也有两种情况,一是编译器有针对printf这类函数的优化,二是编译器会主动把字符串中的格式符变成某种执行效果。而另一种方案是printf函数内部实现的解析格式符。

我们可以用如下的程序来测试(为了方便,后面我们生成程序的名称都为demo.exe):

#include

int main(int argc, char* argv[])

{

int a