2. C语言 -- 打印

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dugudaibo/article/details/82712273

本博客主要内容为 “小甲鱼” 视频课程《带你学C带你飞》【第一季】 学习笔记,在这里仅作学习交流。在文章中可能出现一些错误或者不准确的地方,如发现请积极指出,十分感谢。
也欢迎大家一起讨论交流,如果你觉得这篇文章对你有所帮助,记得评论、点赞哦 ~(。・∀・)ノ゙

1. 从一个报错讲起

  在上一篇文章中,我们使用了C语言在屏幕中输出了"Hello World!"这句话,但是就printf这个函数而言,他的使用却不是只有这么简单。比如说我们如何在屏幕上答应输出鱼形图案,可以首先尝试下面的这段代码

#include <stdio.h>

int main()
{
	printf("
        **             *
      *******         **
    ************     ***
  ***************** ****
****** @ ***************
  ***************** ****
    ************     ***
      *******         **
        **             *");

	return 0;
}

但是在使用gcc进行编译的时候会出现如下的报错

图1. 使用 gcc 对上面的代码进行编译后所报错误

  出现这种问题的原因在于,printf的用法不符合要求,那正确的用法又是怎样的呢?

2. printf 函数

  printf 函数用于打印格式化字符串到标准输出流,其函数原型为

#include <stdio.h>
...
int printf ( const char * format, ... );

其中的 format 参数是一个格式化字符串,由格式化占位符和普通字符组成,“,”后面接的是与占位符所对应的数字或者字符串等。格式化占位符(以 % 开头)用于指明输出的参数值如何格式化。

2.1 格式化占位符(format)的语法

  格式化占位符(format)的具体语法如下

%[flags][width][.precision][length]specifier

其中的 “[]” 表示可选参数,因此每一个格式化占位符均以 % 开始,以转换字符(specifier)结束。因此下面将首先讲解 specifier(转换字符,必选)的内容及含义,在讲述其他参数。对于这些参数并不需要都背下来,只需要记下你在日常编程中经常遇到的即可。

2.1.1 specifier(转换字符,必选)

转换字符 参数类型;转换结果
c char;字符
d int;有符号十进制整数
e double;以指数形式输出单、双精度浮点数(小写 e)
E 同上(大写 E)
f double;以小数形式输出单、双精度浮点数
g double;以 %f 或 %e 中较短的输出宽度输出单、
双精度浮点数(指数显示小写 e)
G 同上(指数显示大写 E)
o unsigned int;无符号八进制(无前导 0)
s char *;字符串
u int;无符号十进制
x unsigned int;无符号十六进制(无前导 0x)
X 同上(无前导 0X)
p void *;指针值
n int *;存放已写字符的个数
% 不进行参数转换;% 自身


其中需要注意的是,如果 % 后边的字符不是转换字符,则其行为没有定义。

2.1.2 flags(标志,可选)

  flags(标志,可选)的内容即含义如下:

标志 含义
- 指定被转换的参数在其字段内左对齐(默认是右对齐)
+ 指定在输出的数前面加上正负号
空格 如果第一个字符不是正负号,则在其前面加上一个空格
0 对于数值转换,当输出长度小于字段宽度时,添加前导 0 进行填充
# 指定另一种输出形式:
1. 如果转换字符为 o,则第一个数字为 0
2. 如果转换字符为 x 或 X,则指定在输出的非 0 值钱加 0x 或 0X
3. 对于转换字符为 e、E、f、g 或 G 的情况,指定输出总是包含一个小数点。
另外,对于转换字符为 g 或 G,还指定输出值尾部无意义的 0 将被保留

2.1.3 width(宽度,可选)

  width(宽度,可选)是一个数值,用于指定最小字段的宽度。转换后的参数输出宽度至少要达到这个数值。如果参数的字符数小于该数值,则在参数左边(如果 flags 设置为 -,要求左对齐的话则在右边)填充一些字符。填充字符通常为空格,但是如果 flags 设置为 0,则填充字符为数字 0。

2.1.4 .precision(.精度,可选)

  .precision(.精度,可选),通过点号(.)分隔字段的宽度和精度

  • 对于字符串,它指定打印的字符的最大个数
  • 对于整数,它指定打印的数字位数(必要时可加填充位 0 以达到宽度要求)
  • 对于转换字符为 e、E 或 f,它指定打印的小数点后的数字位数
  • 对于转换字符为 g 或 G,它指定打印的有效数字位数

2.1.5 length(长度修饰符,可选)

  length(长度修饰符,可选)的值可以是 h、hh、l、ll 或 L

  • hh 表示将相应的参数按 signed char 或 unsigned char 类型输出
  • h 表示将相应的参数按 short 或 unsigned short 类型输出
  • l 表示将相应的参数按 long 或 unsigned long 类型输出
  • ll 表示将相应的参数按 long long 或 unsigned long long 类型输出
  • L 表示将相应的参数按 long double 类型输出

2.2 附加参数语法

  在 printfint printf ( const char * format, ... );中的 ...就是附加参数。该参数的个数由格式化字符串决定。每个参数的值应当与前面格式化字符串中的占位符类型和位置一一对应。

2.3 返回值

  如果函数调用成功,返回值是实际打印的字符数(不包含表示字符串结束的 ‘\0’);如果函数调用失败,返回值是一个负数。

2.4 使用示例

  下面这个例子将使用上面的方法进行一个演示

#include <stdio.h>

int main()
{
        int a = 520;
        int x = 1;
        char b = 'a';
        char greeting[]="two words";
        float c = 3.14;
        double d = 3.141592653;

        printf("尝试打印输出两个整型数字%d和%d在一个句子中\n", a,x);
        printf("尝试打印输出一个字符%c在一个句子中\n", b);
        printf("尝试打印输出一个字符串%s在一个句子中\n", greeting);
        printf("尝试打印输出一个精确到小数点后两位的数字:%.2f\n", c);
        printf("尝试打印输出一个精确到小数点后9位、宽度为11位的数字:%11.9f\n", d);

        return 0;
}

编译执行上面的程序可以得到如下的结果
这里写图片描述

图2. 打印输出的结果

3. 转义字符

  通过上面的分析我们可以看到,在printf中看到const char * format应该是一个字符串,但是最开始的那种写法明显不是一个字符串,那我们应该如何调整使得他变为一个字符串呢?此时可以通过转义字符完成。

  在 C 语言中,用双引号括起来的内容我们称之为字符串,也就是我们平时所说的文本。字符串可以由可见字符和转义字符组成,像上面所示的那条鱼的主要组成部分——星号(*),就是可见字符。可见字符就是你输入什么,显示出来就是什么。而你如果想将一个字符串分为两行来显示,那么你就需要使用到转义字符。转义字符一般是表示特殊含义的非可见字符,以反斜杠开头,常见的转义字符及其含义如下表
这里写图片描述

图3. 常见的转义字符及其含义

在字符串中反斜杠 + 字符是转义字符,表示特殊含义。但反斜杠如果后边不带任何字符(直接换行),表示我们希望 C 语言将该行以及下一行看做是一个整体。

    所以为了打印输出一条鱼,我们可以通过\n\一起使用得到,具体代码如下

#include <stdio.h>

int main()
{
        printf("\n\
        **             *\n\
      *******         **\n\
    ************     ***\n\
  ***************** ****\n\
****** @ ***************\n\
  ***************** ****\n\
    ************     ***\n\
      *******         **\n\
        **             *\n");

        return 0;
}

执行结果如下图所示

   当然这样的图案可以打印很多,参考网站 “表情符号大全”我们可以获得很多表情,或者自定义一个表情,比如说下面的派大星

#include <stdio.h>

int main()
{
        printf("\n\
────────────────────██████────────── \n\
──────────────────██▓▓▓▓▓▓██──────── \n\
────────────────██▓▓▓▓▒▒▒▒██──────── \n\
────────────────██▓▓▒▒▒▒▒▒██──────── \n\
──────────────██▓▓▓▓▒▒▒▒██────────── \n\
──────────────██▓▓▒▒▒▒▒▒██────────── \n\
────────────██▓▓▓▓▒▒▒▒▒▒██────────── \n\
────────────████▒▒████▒▒██────────── \n\
────────────██▓▓▒▒▒▒▒▒▒▒██────────── \n\
──────────██────▒▒────▒▒██────────── \n\
──────────████──▒▒██──▒▒██────────── \n\
──────────██────▒▒────▒▒██────────── \n\
──────────██▒▒▒▒▒▒▒▒▒▒▒▒██────────── \n\
──────────████████████▒▒▒▒██──────── \n\
────────██▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██────── \n\
──────██▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒██──── \n\
────██▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒██── \n\
──██▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒██ \n\
██▓▓▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒██ \n\
██▓▓▒▒▓▓▒▒▒▒▒▒▓▓▓▓▒▒▒▒▒▒▒▒▒▒▓▓▓▓▒▒██ \n\
██▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓██ \n\
──████▐▌▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▐▌▐▌████── \n\
────██▐▌▐▌▌▌▌▌▌▌▌▌▐▌▐▌▐▌▐▌▌▌▐▌██──── \n\
────██▌▌▐▌▐▌▌▌▐▌▌▌▌▌▐▌▌▌▌▌▌▌▌▌██──── \n\
──────██▌▌▐▌▐▌▐▌▐▌▐▌▐▌▐▌▌▌▌▌██────── \n\
──────██▐▌▐▌▐▌████████▐▌▌▌▌▌██────── \n\
────────██▒▒██────────██▒▒██──────── \n\
────────██████────────██████────────\n");

        return 0;
}

输出结果如下

#参考
[1] “小甲鱼” 视频课程《带你学C带你飞》【第一季】P3
[2] “表情符号大全”网站上的派大星

欢迎大家关注我的知乎号(左侧)和经常投稿的微信公众号(右侧)
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/dugudaibo/article/details/82712273