学嵌入式C语言,看这一篇就够了(4)

打印 上一主题 下一主题

主题 1438|帖子 1438|积分 4314


C语言的输入输出

C语言标准在发布的同时,ANSI构造同时也一起发布了和C语言相关的函数库,也就是标准C库,标准C库集成了很多的API函数接口,比如常用的输入和输出函数就是标准C库提供的
用户如果打算利用标准C库的函数,就必须要包含函数库对应的头文件,比如输入输出函数对应的头文件就叫做stdio.h

  • stdio指的是Standard Input Output(标准输入输出)
  • 在linux体系下stdio.h的位置在 /usr/include/stdio.h
格式化输出

一般标准C库中提供了很多关于输出的函数接口,其中最常用的就是printf()函数




(1)标记说明


(2)字符宽度


(3)转换精度



(4)长度修饰


注意:计算机内部存储多字节的数据时会涉及到大端小端,差别的处置处罚器架构采用的模式是差别的,一般X86架构采用小端模式,ARM架构一般采用大端模式(但是并不绝对)!!!!!!
  1. 一般用union可以简单判断系统大小端
复制代码
  1. /*****************************************************************
  2. *
  3. *   file name : endian.c
  4. *   author    : 18408107475@163.com
  5. *   date      : 2023/02/06
  6. *   function  : 判断系统是大小端
  7. *   note      : None
  8. *
  9. *   CopyRight (c) 2023  18408107475@163.com   All Right Reseverd
  10. ******************************************************************/
  11. #include <stdio.h>
  12. /*
  13.     联合体共用一块地址,对 int a 赋值时也能对 char b 赋值
  14. */
  15. union Endian
  16. {
  17.     int a;      //4个byte → 32bits → 0x00000000 → 0x12345678
  18.     char b;     //1byte → 8bits → 0x00 → 0x??
  19. }u;
  20. int main()
  21. {
  22.     u.a = 0x12345678;
  23.    
  24.     if(u.b == 0x78){
  25.         printf("当前系统是小端序(Little - endian)\n");
  26.         printf("%#x\n",u.b);
  27.     }else{
  28.         printf("当前系统是大端序(Big - endian)\n");
  29.     }
  30.     return 0;
  31. }
复制代码

(5)转换说明





(6)转义字符

在利用printf函数输出字符串时,用户可能需要输出一些转义字符 ‘\n’以及’\t’是比较常用的。
注意有的时候是需要把一些特别字符当做普通字符输出,比较 “” ,可以把 \” 和 \” 输出
(7)输出结果


重点:返回的是打印的字符个数(不包括 \0 ,因为输出遇到 \0 就结束了)

  • Quesion1:分析程序,答出程序的运行效果
  1. #include <stdio.h>
  2. int main()
  3. {
  4.     int i = 43;
  5.     printf("%d\n",printf("%d",printf("%d",i)));
  6.     return 0;
  7. }
复制代码

  • Answer1:
  1. 最内层 printf("%d", i) 输出 43,该函数返回值为输出字符数 2(字符 4 和 3 共 2 个)
  2. 中间 printf("%d", ...) 接收内层返回值 2,输出 2,此函数返回值为 1(字符 2 共 1 个)
  3. 最外层 printf("%d\n", ...) 接收中间返回值 1,输出 1 并换行
  4. 最终输出结果为:
  5. 4321(换行符也会生效,实际显示为 4321\n,但通常表现为下一行开始新内容)
复制代码

  • Quesion2:程序为什么是下面的运行效果?回答:从计算机组成原理的角度,工作服从问题

  • Answer2:
  1. 这是标准输出缓冲机制导致的差异:
  2. 左图程序:printf("hello") 无换行符 \n,输出先存入缓冲区,未立即显示。程序执行 sleep(5) 时,缓冲区未刷新,直到程序结束前缓冲区内容才被刷新输出,接着执行后续代码输出 world,最终 “hello” 和 “world” 一起显示
  3. 右图程序:printf("hello\n") 含换行符 \n,会触发缓冲区刷新,“hello” 立即显示。执行 sleep(5) 延时后,再输出 “world\n”,“world” 也正常显示
复制代码
C语言标准输入输出缓冲区
计算机的CPU的性能好,所以CPU的执行服从高,但是计算机的输入设备和输出设备的服从低,所以CPU为了提高工作服从,要低落访问输入输出设备的次数

根据IO设备的差别,可以把缓冲区分为输入缓冲区和输出缓冲区,同样,根据刷新形式的差别,可以把缓冲区分为三种:全缓冲、行缓冲、无缓冲
  1. 全缓冲:指的是当缓冲区被填满就立即把数据冲刷到文件、或者在关闭文件、读取文件内容以及修改缓冲区类型时也会立即把数据冲刷到文件,一般读写文件的时候会采用
  2. 无缓冲:指的是没有缓冲区,直接输出,一般linux系统的标准出错stderr就是采用无缓冲,这样可以把错误信息直接输出
  3. 行缓冲:指的是当缓冲区被填满(一般缓冲区为4KB,就是4096字节)或者缓冲区中遇到换行符’\n’时,或者在关闭文件、读取文件内容以及修改缓冲区类型时也会立即把数据冲刷到文件中,一般操作IO设备时会采用,比如printf函数就是采用行缓冲
复制代码

  • Quesion3:
  1. 如果在使用printf函数输出字符串的时候忘了添加结束标志’\n’,并且没打算输出太多字符,请问此时要输出的字符串会不会输出?
复制代码

  • Answer3:
  1. 可以输出,当程序结束时会自动刷新缓冲区,如果输入缓存区中存在数据则被丢弃,如果输出缓存区存在数据,则会输出
复制代码

  • Quesion4:
  1. 如果在使用printf函数输出字符串的时候忘了添加结束标志’\n’,并且没打算输出太多字符,并且程序永远不退出,请问此时要输出的字符串会不会输出?
复制代码

  • Answer4:

  1. 不会输出,因为不满足刷新条件
复制代码
注意:用户可以选择手动刷新缓冲区,可以调用标准C库中的fflush()函数接口


注意:不要利用fflush函数区刷新输入缓冲区(stdin) ,因为一般编译器是不支持该操作!!!

  • Quesion5:查阅资料,了解输入输出缓存区为什么一般是4KB大小? 提示:涉及到linux的内存分页机制
  • Answer5:
  1. 首先,Linux 内存管理的分页机制,传统页大小是 4KB。缓冲区设为 4KB,读写时能与内存页匹配,减少 IO 次数。每次读写一个页大小,提升效率,减少系统调用开销。另外,硬件和系统设计的兼容性,4KB 是常见页大小,缓冲区适配这个尺寸,让数据传输更高效,减少碎片,优化缓存利用。现在组织这些点,形成清晰解析。
  2. 在 Linux 中,输入输出缓冲区设为 4KB 主要与内存分页机制相关:
  3. 1.内存页大小适配:Linux 传统内存页大小为 4KB,缓冲区大小与内存页对齐,可减少 I/O 操作次数。程序读写数据时,按 4KB 块操作,一次读写刚好对应一个内存页,提升数据传输效率。
  4. 2.降低系统调用开销:若缓冲区过小,需频繁触发系统调用完成数据读写;4KB 大小减少了调用次数,降低 CPU 与磁盘交互的开销。
  5. 3.硬件与系统协同优化:4KB 是硬件和操作系统长期协同的结果,适配磁盘等设备的读写单元,减少数据碎片化,让缓存机制更高效利用内存空间。
复制代码
格式化输入

用户会利用标准输入设备(键盘)写入数据,所以标准C库提供了一个输入函数scanf(),作用是把数据流写入到内存中

  • scanf指的是scan format(格式化扫描),用法类似于printf函数



注意:如果在scanf的字符串中利用了多个转换说明符,则输入的数据范例必须个转换范例一一对应
匹配字符




免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

星球的眼睛

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表