C语言高级输出及进阶

在C语言中,有三个函数可以用来在显示器上输出数据,它们分别是:

	puts():只能输出字符串,并且输出结束后会自动换行。putchar():只能输出单个字符。printf():可以输出各种类型的数据。

printf() 是最灵活、最复杂、最常用的输出函数,完全可以替代 puts() 和 putchar(),我们将重点介绍 printf() 的高级用法。

格式控制符回顾
在这里插入图片描述

printf() 的高级用法

printf() 可以有更加炫酷、更加个性、更加整齐的输出形式。

假如现在老师要我们输出一个 4×4 的整数矩阵,为了增强阅读性,数字要对齐,怎么办呢?我们显然可以这样做:

#include <stdio.h>
int main()
{int a1=20, a2=345, a3=700, a4=22;int b1=56720, b2=9999, b3=20098, b4=2;int c1=233, c2=205, c3=1, c4=6666;int d1=34, d2=0, d3=23, d4=23006783;printf("%d        %d       %d       %d\n", a1, a2, a3, a4);printf("%d     %d      %d     %d\n", b1, b2, b3, b4);printf("%d       %d       %d         %d\n", c1, c2, c3, c4);printf("%d        %d         %d        %d\n", d1, d2, d3, d4);return 0;
}

运行结果:

20        345       700       22
56720     9999      20098     2
233       205       1         6666
34        0         23        23006783

矩阵一般在大学的《高等数学》中会讲到,m×n 的数字矩阵可以理解为把 m×n 个数字摆放成 m 行 n 列的样子。
看,这是多么地自虐,要敲那么多空格,还要严格控制空格数,否则输出就会错位。更加恶心的是,如果数字的位数变了,空格的数目也要跟着变。例如,当 a1 的值是 20 时,它后面要敲八个空格;当 a1 的值是 1000 时,它后面就要敲六个空格。每次修改整数的值,都要考虑修改空格的数目。

类似的需求随处可见,整齐的格式会更加美观,让人觉得生动有趣。其实,我们大可不必像上面一样,printf() 可以更好的控制输出格式。更改上面的代码:

#include <stdio.h>
int main()
{int a1=20, a2=345, a3=700, a4=22;int b1=56720, b2=9999, b3=20098, b4=2;int c1=233, c2=205, c3=1, c4=6666;int d1=34, d2=0, d3=23, d4=23006783;printf("%-9d %-9d %-9d %-9d\n", a1, a2, a3, a4);printf("%-9d %-9d %-9d %-9d\n", b1, b2, b3, b4);printf("%-9d %-9d %-9d %-9d\n", c1, c2, c3, c4);printf("%-9d %-9d %-9d %-9d\n", d1, d2, d3, d4);return 0;
}

输出结果:

20        345       700       22
56720     9999      20098     2
233       205       1         6666
34        0         23        23006783

这样写起来更加方便,即使改变某个数字,也无需修改 printf() 语句,增加或者减少空格数目。

**%-9d中,d表示以十进制输出,9表示最少占9个字符的宽度,宽度不足以空格补齐,-表示左对齐。**综合起来,%-9d表示以十进制输出,左对齐,宽度最小为9个字符。大家可以亲自试试%9d的输出效果。

printf() 格式控制符的完整形式如下:

%[flag][width][.precision]type

[ ] 表示此处的内容可有可无,是可以省略的。

1 . type 表示输出类型,比如 %d、%f、%c、%lf,type 就分别对应 d、f、c、lf;再如,%-9d中 type 对应 d。

type 这一项必须有,这意味着输出时必须要知道是什么类型。

2 . width 表示最小输出宽度,也就是至少占用几个字符的位置;例如,%-9d中 width 对应 9,表示输出结果最少占用 9 个字符的宽度。

当输出结果的宽度不足 width 时,以空格补齐(如果没有指定对齐方式,默认会在左边补齐空格);当输出结果的宽度超过 width 时,width 不再起作用,按照数据本身的宽度来输出。

width 的用法:

#include <stdio.h>
int main(){int n = 234;float f = 9.8;char c = '@';char *str = "http://www.baidu.com";printf("%10d%12f%4c%8s", n, f, c, str);return 0;
}

运行结果:

 234    9.800000   @http://www.baidu.com

输出解释:

	n 的指定输出宽度为 10,234 的宽度为 3,所以前边要补上 7 个空格。f 的指定输出宽度为 12,9.800000 的宽度为 8,所以前边要补上 4 个空格。str 的指定输出宽度为 8,"http://www.baidu.com" 的宽度为 20,超过了 6,所以指定输出宽度不再起作用,而是按照 str 的实际宽度输出。

3 . .precision 表示输出精度,也就是小数的位数。
当小数部分的位数大于 precision 时,会按照四舍五入的原则丢掉多余的数字;
当小数部分的位数小于 precision 时,会在后面补 0。

另外,.precision 也可以用于整数和字符串,但是功能却是相反的:

	用于整数时,.precision 表示最小输出宽度。与 width 不同的是,整数的宽度不足时会在左边补 0,而不是补空格。用于字符串时,.precision 表示最大输出宽度,或者说截取字符串。当字符串的长度大于 precision 时,会截掉多余的字符;当字符串的长度小于 precision 时,.precision 就不再起作用。

请看下面的例子:

#include <stdio.h>
int main(){int n = 123456;double f = 882.923672;char *str = "abcdefghi";printf("n: %.9d  %.4d\n", n, n);printf("f: %.2lf  %.4lf  %.10lf\n", f, f, f);printf("str: %.5s  %.15s\n", str, str);return 0;
}

运行结果:

n: 000123456  123456
f: 882.92  882.9237  882.9236720000
str: abcde  abcdefghi

输出解说:

	对于 n,.precision 表示最小输出宽度。n 本身的宽度为 6,当 precision 为 9 时,大于 6,要在 n 的前面补 3 个 0;当 precision 为 4 时,小于 6,不再起作用。对于 f,.precision 表示输出精度。f 的小数部分有 6 位数字,当 precision 为 2 或者 4 时,都小于 6,要按照四舍五入的原则截断小数;当 precision 为 10 时,大于 6,要在小数的后面补四个 0。对于 str,.precision 表示最大输出宽度。str 本身的宽度为 9,当 precision 为 5 时,小于 9,要截取 str 的前 5 个字符;当 precision 为 15 时,大于 9,不再起作用。

4 . **flag 是标志字符。**例如,%#x中 flag 对应 #,%-9d中 flags 对应-。下表列出了 printf() 可以用的 flag:
在这里插入图片描述

请看下面的例子:

#include <stdio.h>
int main(){int m = 192, n = -943;float f = 84.342;printf("m=%10d, m=%-10d\n", m, m);  //演示 - 的用法printf("m=%+d, n=%+d\n", m, n);  //演示 + 的用法printf("m=% d, n=% d\n", m, n);  //演示空格的用法printf("f=%.0f, f=%#.0f\n", f, f);  //演示#的用法return 0;
}

运行结果:

m=       192, m=192      
m=+192, n=-943
m= 192, n=-943
f=84, f=84.

输出解说:

	当以%10d输出 m 时,是右对齐,所以在 192 前面补七个空格;当以%-10d输出 m 时,是左对齐,所以在 192 后面补七个空格。m 是正数,以%+d输出时要带上正号;n 是负数,以%+d输出时要带上负号。m 是正数,以% d输出时要在前面加空格;n 是负数,以% d输出时要在前面加负号。%.0f表示保留 0 位小数,也就是只输出整数部分,不输出小数部分。默认情况下,这种输出形式是不带小数点的,但是如果有了#标志,那么就要在整数的后面“硬加上”一个小数点,以和纯整数区分开。

printf() 无法立即输出

printf() 有一个尴尬的问题,就是有时候不能立即输出,请看下面的代码:

#include<stdio.h>
#include<unistd.h>
int main()
{printf("百度");sleep(5);  //程序暂停5秒钟printf("http://www.baidu.com");return 0;
}

这段代码使用了两个 printf() 语句,它们之间有一个 sleep() 函数,该函数的作用是让程序暂停 5 秒,然后再继续执行。sleep() 是 Linux 和 Mac OS 下特有的函数,不能用于 Windows。当然,Windows 下也有功能相同的暂停函数,叫做 Sleep()。

我们不妨修改一下代码,在第一个 printf() 的最后添加一个换行符,如下所示:
printf(“百度\n”);
再次编译并运行程序,发现第一个 printf() 首先输出(程序运行后立即输出),等待 5 秒以后,第二个 printf() 才输出。

为什么一个换行符\n就能让程序的表现有天壤之别呢?按照通常的逻辑,程序运行后第一个 printf() 应该立即输出,而不是等待 5 秒以后再和第二个 printf() 一起输出,也就是说,第二种情形才符合我们的惯性思维。然而,第一种情形该如何理解呢?

其实,这一切都是输出缓冲区(缓存)在作怪!

从本质上讲,printf() 执行结束以后数据并没有直接输出到显示器上,而是放入了缓冲区,直到遇见换行符\n才将缓冲区中的数据输出到显示器上。

Windows中的效果,请看下面的代码:

#include<stdio.h>
#include<Windows.h>
int main()
{printf("百度");Sleep(5000);  //程序暂停5秒钟printf("http://www.baidu.com\n");return 0;
}

在 Windows 下,想让程序暂停可以使用 Windows.h 头文件中的 Sleep() 函数(S要大写),它和 Linux 下的 sleep() 功能相同。不过,sleep() 要求的时间单位是秒,而 Sleep() 要求的时间单位是毫秒,1 秒等于 1000 毫秒。这段代码中,我们要求程序暂停 5000 毫秒,也即 5 秒。

编译并运行程序,会发现第一个 printf() 首先输出(程序运行后立即输出),等待 5 秒以后,第二个 printf() 才输出。

在第一个 printf() 的最后添加一个换行符,情况也是一样的,第一个 printf() 从来不会和第二个 printf() 一起输出。

综上所述,Windows 和 Linux、Mac OS 的情况又不一样。这是因为,Windows 和 Linux、Mac OS 的缓存机制不同。

要想破解 printf() 输出的问题,必须要了解缓存,它能使你对输入输出的认识上升到一个更高的层次,以后不管遇到什么疑难杂症,都能迎刃而解。可以说,输入输出的“命门”就在于缓存。

你的赞是对我最大的支持!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/565130.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数学建模学习笔记(六)——多元线性回归分析

文章目录一、综述二、常见的回归分析三、对于相关性的理解四、一元线性回归模型五、对于回归系数的解释六、内生性七、四类线性模型回归系数的解释八、对于定性变量的处理——虚拟变量XXX九、下面来看一个实例十、扰动项需要满足的条件十一、异方差十二、多重共线性十三、逐步回…

没有bug队——加贝——Python 59,60

相关 tkinter 的介绍&#xff1a;Python 55&#xff0c;56 目录 59.题目&#xff1a;画图&#xff0c;综合例子。  60.题目&#xff1a;计算字符串长度。  len&#xff08;&#xff09;函数用法 59.题目&#xff1a;画图&#xff0c;综合例子。   程序分析&#xff…

爬虫必备反爬技能:使用动态ip

目录 一、为什么要使用动态代理ip? 二、如何申请动态代理ip&#xff1f; 三、如何使用动态ip&#xff1f; 一、为什么要使用动态代理ip? 使用它的好处在哪里呢&#xff1f; 保护你的网络免受外部攻击屏蔽你的IP地址限制不必要的内容更好的帮助你抓取网络数据绕过目标网站…

数学建模学习笔记(七)——图论最短路问题

文章目录一、综述二、图论最短路问题三、几个简单的作图方法四、Dijkstra&#xff08;迪杰斯特拉&#xff09;算法五、Bellman-Ford算法六、总结一、综述 本文主要根据图论的基本概念&#xff0c;介绍图论中常见的建模问题——最短路问题。同时&#xff0c;介绍了解决图论最短…

pycharm和pythonIDE安装详解

目录 一、pycharm下载安装 二、python下载安装 ​三、pycharm上配置python 我们可能显示的库不大一样&#xff0c;因为我这大都事先安装过了&#xff0c;就没有删​打印成功&#xff1a;标志配置完成​四、配置镜像源让你下载嗖嗖的快 4.1&#xff09;pycharm内部配置 4.2…

数学建模学习笔记(八)——分类模型

文章目录一、分类模型综述二、逻辑回归三、两点分布&#xff08;伯努利分布&#xff09;四、连接函数的取法五、Logistic回归模型六、在SPSS中进行二元Logistic回归七、预测结果较差的解决八、Fisher线性判别分析九、多分类问题十、总结一、分类模型综述 通过样本数据中的分类…

python基础入门(1)

目录 一、python入门 二、python缩进 三、Python注释 1&#xff09;单行注释 2&#xff09;多行注释 四、Python 变量 1&#xff09;变量定义理解 2&#xff09; 变量名命名 3&#xff09; 分配多个值 4&#xff09;输出变量 5&#xff09;全局变量与局部变量&#…

数学建模学习笔记(九)——聚类模型

文章目录一、聚类综述二、主要用到的聚类算法三、K-means聚类算法四、K-means算法五、对于K-means算法和K-means算法的讨论六、系统&#xff08;层次&#xff09;聚类算法七、DBSCAN算法八、总结一、聚类综述 聚类的主要目的就是将样本划分为由类似的对象组成的多个类的过程。…

python基础入门(2)

目录 一、Python数据类型 1&#xff09;置数据类型 2&#xff09;获取数据类型 3&#xff09;设置数据类型 4&#xff09;设置特定数据类型 6&#xff09;练习题 二、python数字- 1&#xff09;整数 2&#xff09;浮点数 3&#xff09;虚数 4&#xff09;类型转换 …

C语言scanf:获取输入的内容

获取外部输入数据内容 在C语言中&#xff0c;有多个函数可以从键盘获得用户输入&#xff1a; scanf()&#xff1a;和 printf() 类似&#xff0c;scanf() 可以输入多种类型的数据。getchar()、getche()、getch()&#xff1a;这三个函数都用于输入单个字符。gets()&#xff1a;获…

数学建模学习笔记(十)——时间序列模型

文章目录一、时间序列综述二、时间序列数据以及基本概念三、时间序列分解四、指数平滑模型五、一元时间序列分析的模型六、AR&#xff08;p&#xff09;模型七、MA&#xff08;q&#xff09;模型八、ARMA&#xff08;p, q&#xff09;模型九、模型选择&#xff1a;AIC 和 BIC 准…

python基础入门(3)之字符串

目录 一、Python字符串 1.字符串基本使用 1&#xff09;字符串理解 2&#xff09;将字符串分配给变量 3&#xff09;多行字符串 4&#xff09;字符串是数组 5)遍历字符串 6)字符串长度 7)检查字符串 8)检查如果不是 2.切片字符串 1)切片 2)从头开始切片 3)切到最…

数学建模学习笔记(十一)——预测模型

文章目录一、综述二、灰色预测简介三、GM&#xff08;1, 1&#xff09;模型四、使用灰色系统建模的前提 —— 准指数规律检验五、对于GM(1, 1)的检验六、GM&#xff08;1, 1&#xff09;模型的拓展七、什么时候使用灰色预测八、神经网络模型一、综述 本文首先介绍了灰色预测模…

python基础入门(4)之布尔值

目录 一、Python布尔值 1)比较 2)评估值和变量 3)布尔真值 4)布尔假值 5)函数可以返回布尔值 6)练习题 一、Python布尔值 布尔值表示两个值之一&#xff1a; True或False。在编程中&#xff0c;您经常需要知道表达式是否为 True或False。举一些例子就明白了。 1)比较 当…

C语言if else语句详解

前面我们看到的代码都是顺序执行的&#xff0c;也就是先执行第一条语句&#xff0c;然后是第二条、第三条……一直到最后一条语句&#xff0c;这称为顺序结构。 但是对于很多情况&#xff0c;顺序结构的代码是远远不够的&#xff0c;这时我们就要使用判断语句即if else语句。 …

数学建模学习笔记(十二)——奇异值分解

文章目录一、综述二、奇异值分解三、使用SVD进行降维四、SVD的评价及应用一、综述 奇异值分解是线性代数中一种重要的矩阵分解方法&#xff0c;它在图形的压缩等方面具有重要的意义及作用。 二、奇异值分解 三个引理&#xff1a; AB 和 BA 非零的特征值完全相同&#xff1b;…

python基础入门(5)之运算符

目录 一、python运算符 1)算术运算符 2)赋值运算符 一、python运算符 1)算术运算符 自己赋值粘贴运行下就懂了&#xff01; 加减法&#xff1a;&#xff08; -&#xff09; a2 b3 ca-b da-b print(c,d)乘除法&#xff1a;&#xff08;* /&#xff09; a(50-5*6)/4 print(…

Python实例 61,62

61.题目&#xff1a;打印出杨辉三角形 程序设计&#xff1a; 第一步&#xff1a;先找规律&#xff0c;抽象化问题&#xff1a; 首先我们观察到&#xff0c;第一行为[1]&#xff0c;我们直接赋给一个变量&#xff1a;初始化数列 p [1] 其次我们观察到&#xff0c;下面的每一…

C语言逻辑运算符详解

情景模式&#xff1a;现在研发出了一款新的软件&#xff0c;要求使用者必须成年&#xff0c;并且成绩大于等于60&#xff0c;该怎么办呢&#xff1f; 或许你会想到使用嵌套的 if 语句&#xff0c;类似下面这样的代码&#xff1a; #include <stdio.h> int main() {int a…

Python实例 63,64

目录 63.题目&#xff1a;画椭圆 1.tkinter画椭圆 2.turtle画椭圆 64.题目&#xff1a;利用ellipse 和 rectangle 画图 63.题目&#xff1a;画椭圆 1.tkinter画椭圆 #63 from tkinter import * x 360 y 160 top y - 30 bottom y - 30canvas Canvas(width 500,height …