当前位置:   article > 正文

C 语言的 printf() 函数_c语言printf函数

c语言printf函数

概述

函数的作用: Print formatted output to the standard output stream.

函数原型:

int printf( const char *format [, argument]... );
  • 1

printf 函数的基本格式:

printf(“格式字符串”, 待打印项1, 待打印项2, …);

待打印项1, 待打印项2 等都是要打印的项, 可以是变量, 常量或者在打印之前可以先进行求值的表达式, 然后打印这个表达式的值.

格式字符串中包含两种不同的信息:

  1. 实际要打印的字符.
  2. 转换说明.

示意图1:

在这里插入图片描述

示意图2:

在这里插入图片描述

向 printf 或 其他没有在函数原型中指明形参类型的函数, 传递实参时, short 类型实参被转换为 int, float 类型实参被转换为 double.

转换说明 conversion specification

int

int 类型, 即基本整型, 通常只有十进制, 转换说明为:

%d
  • 1

short int

short int 简称为 short, 即短整型. 转换说明要加前缀 h, 即:

%hd
  • 1

long int

long int 简称为 long, 即长整型. 转换说明要加前缀 l, 即:

%ld
  • 1

long long int

long long int 简称为 long long, 即长长整型, 是 C99 新增, C90 不支持. 转换说明要加前缀 ll, 即:

%lld
  • 1

unsigned int

unsigned int 简称 unsigned, 即无符号基本整型.

有三种进制, 即十进制, 八进制, 十六进制.

以八进制和十六进制输出时, 会将符号位视为数值位, 故以八进制或十六进制形式输出整数时只能用于无符号整数.

printf() 不支持以八进制和十六进制形式输出有符号数, 也没有对应的转换说明符.

十进制:

%u
  • 1

十进制没有前缀, 若加了 # 则结果未定义.

八进制:

显示前缀:%#o(得到前缀 0)
不显示前缀:%o
  • 1
  • 2

十六进制:

显示前缀:%#x(得到前缀 0x),%#X(得到前缀 0X)
不显示前缀:%x,%X
使用 x 则十六进制数用 1-9 和 a-f 表示.
使用 X 则十六进制数用 1-9 和 A-F 表示.
  • 1
  • 2
  • 3
  • 4

程序示例:

#include<stdio.h>
int main(void)
{
	unsigned int x = 100;

	printf("dec = %u; octal = %o; hex = %x\n", x, x, x);

	printf("dec = %u; octal = %o; hex = %X\n", x, x, x);

	printf("dec = %u; octal = %#o; hex = %#x\n", x, x, x);

	printf("dec = %u; octal = %#o; hex = %#X\n", x, x, x);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

结果:

dec = 100; octal = 144; hex = 64
dec = 100; octal = 144; hex = 64
dec = 100; octal = 0144; hex = 0x64
dec = 100; octal = 0144; hex = 0X64
  • 1
  • 2
  • 3
  • 4

unsigned short int

unsigned short int 简称 unsigned short, 即无符号短整型, 分三种进制进行打印:

十进制:

%hu
  • 1

八进制:

显示前缀: %#ho
不显示前缀: %ho
  • 1
  • 2

十六进制:

显示前缀: %#hx 或 %#hX
不显示前缀: %hx 或 %hX
  • 1
  • 2

unsigned long int

unsigned long int 简称为 unsigned long, 即无符号长整形.

十进制:

%lu
  • 1

八进制:

显示前缀: %#lo
不显示前缀: %lo
  • 1
  • 2

十六进制:

显示前缀: %#lx 或 %#lX
不显示前缀: %lx 或 %lX
  • 1
  • 2

unsigned long long int

unsigned long long int 简称为 unsigned long long, 即无符号长长整型.

十进制:

%llu
  • 1

八进制:

显示前缀: %#llo
不显示前缀: %llo
  • 1
  • 2

十六进制:

显示前缀: %#llx 或 %#llX
不显示前缀: %llx 或 %llX
  • 1
  • 2

short, long, long long 就是在 int 的 d 前面加前缀 h, l, ll.

unsigned short, unsigned long, unsigned long long 就是在 unsigned 的 o 前面加前缀 h, l, ll.

此类前缀称为修饰符.

有符号类型只能以十进制输出 (虽然有符号的正数以十六进制和八进制输出也不会出错, 但只是刚好符号位为 0 而已).

无符号类型可以三种进制 (十进制, 八进制, 十六进制) 输出. 要显示八进制前缀 0 和十六进制前缀 0x 或 oX 时在转换说明的 % 后面加 #.

布尔型

转换说明:

%u
  • 1

字符型

转换说明:

%c
  • 1

地址

转换说明:

%p
  • 1

指针之差

%td

浮点型

float 和 double

十进制:

%f
  • 1

指数计数法:

%e

%E
  • 1
  • 2
  • 3

十六进制:

%a

%A
  • 1
  • 2
  • 3

long double

十进制:

%Lf
  • 1

指数计数法:

%Le
  • 1

十六进制:

%La
  • 1

给未在函数原型中显式说明参数类型的函数(如 printf())传递参数时,C 编译器会把 float 类型的值自动转换为 double 类型。

%g

根据值的不同, 自动选择 %f 或者 %e 来打印浮点数, %e 格式用于指数小于 -4 或者大于或等于精度时.

%G

根据值的不同, 自动选择 %f 或者 %E 来打印浮点数, %e 格式用于指数小于 -4 或者大于或等于精度时.

修饰符

以上各个百分号后面的字母叫做 转换字符 . 在 转换字符百分号 之间还可以有 修饰符 . 修饰符可以修饰基本的转换说明.

转换说明即由三部分组成: 百分号, 修饰符, 转换字符 .

数字

表示宽度

转换说明中, 小数点前面的数字可以表示待打印项的最小字段宽度, 在指定宽度范围内, 内容右对齐.

如果字段宽度不能容纳待打印的内容, 系统会自动使用刚好合适的宽度.

程序示例1:

#include<stdio.h>
#include<string.h>
int main(void)
{
	printf("**********\n");
	printf("%10s\n", "hello");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结果:

**********
     hello
  • 1
  • 2

程序示例2:

#include<stdio.h>
#include<string.h>
int main(void)
{
	printf("**********\n");
	printf("%10d\n", 30);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结果:

**********
        30
  • 1
  • 2

程序示例3:

#include<stdio.h>
#include<string.h>
int main(void)
{
	printf("**********\n");
	printf("%10s\n", "hello world!");
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结果;

**********
hello world!
  • 1
  • 2

表示精度

转换说明中, 小数点后面的数字还可以表示浮点数的精度, 即浮点数的小数点后面有几个数字, 可以四舍五入.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	float a = 1235.56789;

	printf("%e\n", a);    // 默认的情况,小数点后面6个数字,可以进行四舍五入
	printf("%.4e\n", a);  // 明确指定小数点后面4个数字,可以进行四舍五入
	printf("%.4f\n", a);  // 明确指定小数点后面4个数字,可以进行四舍五入

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

结果:

1.235568e+03
1.2356e+03
1235.5679
  • 1
  • 2
  • 3

这种精度表示方式适用于 %e,%E 和 %f.

小数点前面的数字表示字段宽度, 小数点后面的数字表示输出的浮点数的小数点后面的位数.

可以看出, 这里发生了四舍五入.

如果转换说明中, 只是用了小数点, 则说明输出的数字没有小数部分, 即没有小数点以及小数点后面的数字. 也就是说 %.f%.0f 两者效果相同.

在去掉小数部分时依然会发生四舍五入.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	float a = 12345.88888;
	printf("%.f\n", a);  
	printf("%.0f\n", a); 

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结果;

12346
12346
  • 1
  • 2

可以看出这里发生了四舍五入.

表示待打印字符的最多个数

在转换说明 %s 中, 在小数点后面加数字, 可以表示待打印的字符的最多个数.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	char name[20] = "helloworld";
	printf("%s\n", name);         // 直接输出整个字符串
	printf("%.5s\n", name);       // 最多输出5个字符

	printf("********************\n");
	printf("%10.6s\n", name);     // 输出的字符串最多占用10个位置,最多输出6个字符,默认右对齐
	printf("%-10.5s\n", name);    // 输出的字符最多占用10个位置,最多输出5个字符,左对齐

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

结果:

helloworld
hello
********************
    hellow
hello
  • 1
  • 2
  • 3
  • 4
  • 5

表示整数的最少位数

%d 转换说明中, 小数点后面有数字时, 该数字表示待输出的整数最小占用的位数, 如果指定的位数小于数字的真实位数, 则忽视这个位数的要求而直接打印数字, 如果指定的位数大于数字的真实位数, 则数字靠右打印, 左侧用数字0补齐要求的位数. 不论哪种情况待打印的数字都是完整输出的.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 12345;
	
	// 最小打印四位数字,原数字超过了四位,则直接忽视这个 4,打印原始的数字
	printf("%.4d\n", a);  
	
	// 最小打印六位数字,原数字为五位,则打印原始的数字,原始数字靠右,左侧用 0 补齐六位
	printf("%.6d\n", a);  

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

结果:

12345
012345
  • 1
  • 2

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 12345;
	printf("**********\n");
	printf("%10.7d\n", a);  // 指定字段宽度为 10, 至少输出 7 个数字, 不够的用 0 不足位数

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结果:

**********
   0012345
  • 1
  • 2

标记

标记有五种: -, +, 空格, #, 0.

可以不使用或者使用多个标记.

-

- 可以使得在指定的字段范围内, 待打印项左对齐.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 123;
	printf("**********\n");
	printf("%-10d\n", a);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结果:

**********
123
  • 1
  • 2

+

有符号值若为正, 则在前面显示 +. 若为负, 则在前面显示 -.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 123;
	int b = -123;
	printf("%+d\n", a);
	printf("%+d\n", b);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

结果:

+123
-123
  • 1
  • 2

空格

有符号值若为正, 则在前面显示空格, 不显示任何符号, 若为负, 则在前面显示减号.

如果在转换说明的修饰符中, 正号 + 和 空格同时存在, 则正号起作用而空格不起作用.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 123;
	int b = -123;
	printf("% d\n", a);
	printf("%+ d\n", a);
	printf("% d\n", b);
	printf("%+ d\n", b);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结果;

 123
+123
-123
-123
  • 1
  • 2
  • 3
  • 4

#

对于 %o, 输出将以 0 开始.

对于 %x 和 %X, 输出将以 0x 和 0X 开头.

对于所有的浮点数, 即使没有小数部分也会打印一个小数点.

程序示例:

#include<stdio.h>
#include<string.h>

int main(void)
{
	float a = 123e2;
	printf("%.0f\n", a);
	printf("%#.0f\n", a);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结果:

12300
12300.
  • 1
  • 2

对于 %g 和 %G 格式, # 方式结果后面的 0 被删除.

0

对于数值格式, 用前导0代替空格填充字段宽度.

对于整数格式, 如果出现 - 标记或者指定最少输出的数字个数, 则忽略 0 这个标记.

程序示例1:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 88;
	printf("**********\n");
	printf("%10d\n", a);
	printf("%010d\n", a);  // 用前导 0 代替空格填充字段宽度
	printf("%-010d\n", a);  // 出现 - 标记, 标记 0 不起作用

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

结果:

**********
        88
0000000088
88
  • 1
  • 2
  • 3
  • 4

程序示例2:

#include<stdio.h>
#include<string.h>

int main(void)
{
	float a = 1.2345;
	printf("**********\n");
	printf("%10.3f\n", a);
	printf("%010.3f\n", a);  // 对于浮点数,指定了精度,但标记 0 依然起作用,只有整数里面的标记 0 可能被覆盖不起作用

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

结果:

**********
     1.235
000001.235
  • 1
  • 2
  • 3

程序示例3:

#include<stdio.h>
#include<string.h>

int main(void)
{
	int a = 12345;
	printf("**********\n");
	printf("%10d\n", a);     // 指定字段宽度为10
	printf("%10.3d\n", a);   // 指定最少输出3位,实际为5位,因此3被忽视,直接输出原来的数字
	printf("%010d\n", a);    // 不指定整数最少输出的数字个数,标记 0 起作用
	printf("%010.3d\n", a);  // 指定整数最少输出的数字个数,标记 0 不起作用

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结果:

**********
     12345
     12345
0000012345
     12345
  • 1
  • 2
  • 3
  • 4
  • 5

转换说明的意义

数据存储在计算机中是以二进制的数字形式存储的, 但是用 printf 将其显示在屏幕上时显示的是字符. 比如在屏幕上显示 42 是显示字符 4 和字符 2.

转化说明就负责这一转换过程. 转换说明就是一种翻译说明.

%%

可以使用 %% 打印一个百分号 %

程序示例:

#include<stdio.h>
#include<string.h>
int main(void)
{
	printf("Only %d%% students are good.", 30);
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

结果:

Only 30% students are good.
  • 1

常见错误

1.

用 %d 打印浮点数时,不会将浮点数转换为整型。

程序示例:

#include<stdio.h>
int main(void)
{
	float a = 10.1111115;
	printf("%d\n", a);
	return 0;
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结果;

-1610612736
  • 1

各个系统结果可能不同。

刷新输出

首先 printf 将输出发送到缓冲区 (buffer), 这是一个中间存储区域, 然后缓冲区的内容再被发送到屏幕上.

C 标准明确规定了何时向屏幕发送缓冲区的内容, 即刷新缓冲区:

缓冲区满了
遇到换行符
需要输入

printf 函数的返回值

returns the number of characters printed, or a negative value if an error occurs.

printf() 函数返回它打印的字符的个数.

如果输出有误, 则 printf() 返回一个负值.

程序示例:

#include<stdio.h>
int main(void)
{
	printf("%d\n", printf("Hello\n"));
	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

结果:

Hello
6
  • 1
  • 2

显然, 需要求 printf("Hello\n") 表达式的返回值, 需要先计算该表达式, 效果是打印出一句话, 即 Hello.

此返回值包括了所有的字符, 尤其是空格和转义字符如 \n 等.

* 修饰符的用法

输出时可以不预先指定字段的宽度, 可以通过程序来指定.

可以用 * 修饰符来替换字段宽度.

此时需要另一个参数来告诉函数, 这个字段宽度应该是多少.

即, 如果转换说明是 %*d, 则参数列表中应该包含 *d 对应的值.

该技巧也可用于浮点值指定精度和字段宽度.

程序示例:

#include<stdio.h>
#define NUMBER 123
int main(void)
{
	printf("Please enter field width: ");
	int width = 0;
	scanf("%d", &width);
	printf("This integer is %*d\n", width, NUMBER);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

结果:

Please enter field width: 6
This integer is    123
  • 1
  • 2

程序示例:

#include<stdio.h>
#define NUMBER 123.456789
int main(void)
{
	printf("Please enter field width: ");
	int width = 0;
	scanf("%d", &width);
	printf("Please enter precision: ");
	int precision = 0;
	scanf("%d", &precision);
	printf("This number is %*.*f.\n", width,precision,NUMBER);

	return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

结果:

Please enter field width: 14
Please enter precision: 3
This number is        123.457.
  • 1
  • 2
  • 3
本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号