printf函数打印(一)—— 过程解析篇

程序运行的时候,会自动打开三个文件,分别是stdin、stdout、stderr

这三个文件对应的外设分别是 键盘、显示器、显示器

这三个文件对应的文件描述符为 0、1、2

printf函数在显示器上打印数据是如何实现的??


目录

一、通过write函数理解打印的过程

二、小测试:关闭fd = 1,然后调用printf函数,观察是否会打印

1、测试前说明

 2、开始测试

3、测试结果

三、测试结果原因分析


一、通过write函数理解打印的过程

首先我们来看一段代码

我们要打印数据,本质上就是向 fd = 1指向的文件输送数据(因为默认情况下 fd = 1指向的文件是显示器文件)

所以我们通过write函数向fd = 1 写入数据 ==》  向显示器文件写入数据

这已经十分接近 printf函数的打印过程了,但是还没有结束

二、小测试:关闭fd = 1,然后调用printf函数,观察是否会打印

我们从上面知道,向fd = 1写入的数据,会打印在显示器上

但是我们关闭 fd = 1呢??? 

1、测试前说明

这里需要事先说明一下

open函数:建立 struct files文件结构体  之间的联系

close函数:断开 struct files文件结构体  之间的联系

                (准确说是 断开文件内核缓冲区和外设之间的关系)

        

 2、开始测试

(1)关闭fd = 1的文件描述符 ——》 断开了 1下标和stdout文件的联系(上面右图)

(2)新建一个log.txt

创建文件时,会从0 开始遍历数组 fd_array [ ],发现 1 下标没有任何指向,会直接让下标1指向log.txt的文件结构体

(3)打印 "hello,world!"

3、测试结果

 本该打印的内容没有打印,我们来看看创建的log.txt里面的内容

 我们发现printf函数打印的内容 “显示” 到了log.txt中

三、测试结果原因分析

printf函数的功能:在显示器上打印指定的内容 ——》向显示器文件stdout中写入内容

首先,我们看看这里所谓的stdout到底是什么?!

stdout 的类型是File*,也就是对应文件结构体File的地址

每个文件结构体FILE中必定包含 封装好的文件描述符(如下)

typedef struct _IO_FILE FILE;   //在usr/include/stdio.h

struct _IO_FILE
{
    //其他的先不考虑...
    //...
    int _fileno; //封装的文件描述符
}

 而stdout对应的结构体 中封装好的文件描述符 fd = 1

                                                    

printf函数要打印内容那就去找stdout——》stdout对应的结构体 中封装好的文件描述符 fd = 1——》通过fd = 1定位到对应的文件结构体地址,然后向这个文件输送内容

孰不知,自己被偷家了,下标为1 对应的文件已经换成了其他文件log.txt

这就是printf打印的过程,只认stdout里包含的fd,即只认识下标,不管这个下标指向哪

拓展:

fprintf 也是如此,但是fprintf多个一个参数,那就是 输出到哪

fprintf(stdout,"hello,world");

这里的目的是打印到显示器,所以向stdout写入数据

这也就证明了

printf、fprintf要打印数据到显示器,都只知道向stdout打印,然后stdout中包含的文件描述符fd = 1

所以就去找 下标为 1对应的文件

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值