printf
函数
printf
函数是 C 语言中用于将格式化的数据输出到标准输出 (通常是屏幕)的函数。它位于 stdio.h
头文件中,因此在使用之前需要包含该头文件。
printf
函数的格式说明符
格式说明符 | 说明 | 示例 |
---|---|---|
%d 或 %i |
输出或输入十进制有符号整数 | printf("%d", 10); scanf("%d", &num); |
%u |
输出或输入十进制无符号整数 | printf("%u", 10U); scanf("%u", &unsigned_num); |
%o |
输出或输入八进制无符号整数 | printf("%o", 012); scanf("%o", &octal_num); |
%x 或 %X |
输出或输入十六进制无符号整数,%x 输出小写字母,%X 输出大写字母 |
printf("%x", 0xFF); scanf("%x", &hex_num); |
%f |
输出或输入单精度浮点数 | printf("%f", 3.14f); scanf("%f", &float_num); |
%lf |
输出或输入双精度浮点数 | printf("%lf", 3.14159); scanf("%lf", &double_num); |
%c |
输出或输入单个字符 | printf("%c", 'A'); scanf("%c", &char_var); |
%s |
输出或输入字符串(不包含空格,以空格或换行符结束) | printf("%s", "hello"); scanf("%s", str); |
%p |
输出指针的地址,以十六进制表示 | printf("%p", &ptr); scanf("%p", &ptr); |
%e 或 %E |
以科学计数法输出或输入浮点数,%e 为小写,%E 为大写 |
printf("%e", 12345.6789); scanf("%e", &float_num); |
%g 或 %G |
根据数值大小自动选择 %f 或 %e 输出浮点数,%g 为小写,%G 为大写 |
printf("%g", 0.0000123); scanf("%g", &float_num); |
%n |
不输出任何内容,但将已输出的字符数存储在对应的整型变量中 | int num; printf("hello world%n", &num); 会将 11 存储在 num 中 |
高级格式化选项
格式说明符 | 说明 | 示例 |
---|---|---|
%[flags][width][.precision][length]specifier |
组合使用各种选项进行格式化输出或输入 | printf("%8.2f", 3.14159); 输出浮点数,宽度为 8,保留 2 位小数 |
Flags(标志)
标志 | 说明 | 示例 |
---|---|---|
- |
左对齐 | printf("%-8d", 10); 输出整数,宽度为 8,左对齐 |
+ |
强制输出正负号 | printf("%+d", 10); 输出 +10 |
(空格) | 正数前输出空格,负数前输出负号 | printf("% d", 10); 输出 10 |
0 |
用 0 填充宽度 | printf("%08d", 10); 输出整数,宽度为 8,不足用 0 填充 |
# |
对于 %o ,输出八进制数时加前缀 0 ;对于 %x 或 %X ,输出十六进制数时加前缀 0x 或 0X ;对于 %f 、%e 或 %g ,即使没有小数部分也输出小数点 |
printf("%#o", 10); 输出 012 |
cpp
#include <stdio.h>
int main() {
int num = 10;
// 输出整数,宽度为 5,左对齐
printf("整数: %-5d\n", num);
return 0;
}
Width(宽度)
说明 | 示例 |
---|---|
指定最小输出宽度 | printf("%5d", 10); 输出整数,宽度为 5 |
Precision(精度)
说明 | 示例 |
---|---|
对于浮点数,指定小数点后的位数;对于字符串,指定最大输出长度 | printf("%.2f", 3.14159); 保留 2 位小数 |
cpp
#include <stdio.h>
int main() {
int num = 10;
float f = 3.14159;
// 输出整数,宽度为 5
printf("整数: %5d\n", num);
// 输出浮点数,保留两位小数
printf("浮点数: %.2f\n", f);
return 0;
}
Length(长度)
长度修饰符 | 说明 | 示例 |
---|---|---|
h |
与 d 、i 、o 、x 或 u 一起使用,表示短整型 |
printf("%hd", (short)10); |
l |
与 d 、i 、o 、x 或 u 一起使用,表示长整型;与 e 、f 或 g 一起使用,表示双精度浮点数 |
printf("%ld", (long)10L); printf("%lf", 3.14); |
ll |
与 d 、i 、o 、x 或 u 一起使用,表示长长整型 |
printf("%lld", (long long)123456789012345LL); |
L |
与 e 、f 或 g 一起使用,表示长双精度浮点数 |
printf("%Lf", 3.14L); |
scanf
函数
scanf
函数是 C 语言中用于从标准输入(通常是键盘)读取格式化数据的函数。同样位于 stdio.h
头文件中。
scanf
函数的格式说明符
格式说明符 | 说明 | 示例 | 输入 | 存储变量 |
---|---|---|---|---|
%d 或 %i |
十进制整数 | scanf("%d", &num); |
10 |
int num; |
%u |
无符号十进制整数 | scanf("%u", &num); |
4294967295 |
unsigned int num; |
%o |
八进制整数 | scanf("%o", &num); |
12 |
int num; |
%x 或 %X |
十六进制整数 | scanf("%x", &num); <br>scanf("%X", &num); |
ff <br>FF |
int num; |
%f |
浮点数 | scanf("%f", &num); |
3.14159 |
float num; |
%e 或 %E |
科学计数法表示的浮点数 | scanf("%e", &num); <br>scanf("%E", &num); |
3.141590e+00 <br>3.141590E+00 |
float num; |
%c |
单个字符 | scanf("%c", &ch); |
A |
char ch; |
%s |
字符串 | scanf("%s", str); |
Hello |
char str[50]; |
tips
- 对于
%s
格式说明符,scanf
函数会读取字符串直到遇到空格、制表符或换行符。如果要读取包含空格的字符串,可以使用fgets
函数。 - 对于
%c
格式说明符,scanf
会读取下一个字符,包括空格和换行符,所以如果前面有输入,可能需要处理多余的空格或换行符。
为了避免读取到换行符,可以在 %c
前加一个空格:
cpp
#include <stdio.h>
int main() {
char ch1, ch2;
// 读取字符,可能会读取到换行符
scanf("%c", &ch1);
// 读取下一个字符,跳过空格和换行符
scanf(" %c", &ch2);
printf("你输入的第一个字符是: %c\n", ch1);
printf("你输入的第二个字符是: %c\n", ch2);
return 0;
}
使用 getchar
函数清除多余字符
cpp
#include <stdio.h>
int main() {
char ch;
scanf("%d"); // 假设前面有一个整数输入
getchar(); // 读取并丢弃换行符
scanf("%c", &ch); // 读取字符
return 0;
}
二进制(Binary)
是一种以 2 为基数的计数系统,仅使用数字 0 和 1 来表示数值。通常,我们使用二进制数的位(bit)来表示数据,一个字节(byte)由 8 位二进制数组成。
二进制转十进制
从右往左,将二进制数的每一位乘以 2^n(n 从 0 开始),然后将结果相加。
cpp
1011(二进制)表示:1 乘 2的三次方 + 0 乘 2的二次方 + 1 乘 2的一次方 + 1 乘 2的零次方
= 8 + 0 + 2 + 1
=11(十进制)
十进制转二进制
将十进制数除以 2,取余数,将商继续除以 2,直到商为 0。将每次得到的余数从下往上排列,就是对应的二进制数。
cpp
// 将十进制数 10 转换为二进制
10 ÷ 2 = 5······0
5 ÷ 2 = 2······1
2 ÷ 2 = 1······0
1 ÷ 2 = 0······1
//因此十进制的二进制从下往上排列余数 1010
位运算符
按位与(&
)
对两个操作数的每一位进行逻辑与操作(即当两位都为 1 时结果为 1,否则为 0)。
cpp
#include <stdio.h>
int main() {
int a = 0b1010; // 二进制表示,C99 标准开始支持,也可写成 10 然后通过其他方式理解其为二进制
int b = 0b1100;
int result = a & b; // 按位与
printf("按位与结果: %d\n", result); // 输出为 8,即 0b1000
return 0;
}
按位或(|
)
对两个操作数的每一位进行逻辑或操作(即当两位中至少有一位为 1 时结果为 1,否则为 0)。
cpp
#include <stdio.h>
int main() {
int a = 0b1010;
int b = 0b1100;
int result = a | b; // 按位或
printf("按位或结果: %d\n", result); // 输出为 14,即 0b1110
return 0;
}
按位异或(^
)
对两个操作数的每一位进行逻辑异或操作(即当两位相异时结果为 1,相同时为 0)。
cpp
#include <stdio.h>
int main() {
int a = 0b1010;
int b = 0b1100;
int result = a ^ b; // 按位异或
printf("按位异或结果: %d\n", result); // 输出为 6,即 0b0110
return 0;
}
按位取反(~
)
对操作数的每一位进行取反操作(即 0 变为 1,1 变为 0)。
cpp
#include <stdio.h>
int main() {
int a = 0b1010;
int result = ~a; // 按位取反
printf("按位取反结果: %d\n", result); // 输出为 -11,即 0b1111111111111111111111111111110101
return 0;
}
左移(<<
)
将操作数的二进制表示向左移动指定的位数,右边补 0。
cpp
#include <stdio.h>
int main() {
int a = 0b1010;
int result = a << 1; // 左移 1 位
printf("左移结果: %d\n", result); // 输出为 20,即 0b10100
return 0;
}
右移(>>
)
将操作数的二进制表示向右移动指定的位数,对于无符号数,左边补 0;对于有符号数,根据编译器和系统可能是补 0 或补符号位。
cpp
#include <stdio.h>
int main() {
int a = 0b1010;
int result = a >> 1; // 右移 1 位
printf("右移结果: %d\n", result); // 输出为 5,即 0b0101
return 0;
}
二进制数的存储和表示
在内存中,整数通常以二进制补码的形式存储。对于有符号整数:
- 正数的补码就是其原码(二进制表示)。
- 负数的补码是其原码取反加 1。
cpp
#include <stdio.h>
int main() {
int a = -5;
// 原码:10000000 00000000 00000000 00000101
// 反码:11111111 11111111 11111111 11111010
// 补码:11111111 11111111 11111111 11111011
printf("存储的二进制补码表示: %d\n", a); // 输出为 -5
return 0;
}
原码
原码是最直观的表示有符号数的方法,它将最高位用作符号位(0 表示正数,1 表示负数),其余位表示数值的绝对值。
cpp
原码:10000000 00000000 00000000 00000101
// 最高位 1 表示这个数是负数
// 其余位 0000000 00000000 00000000 00000101 表示数值部分,即 5。
// 因此,这个原码表示的是 -5。
反码
反码是对原码除符号位外的所有位取反得到的。
cpp
原码:10000000 00000000 00000000 00000101
// 符号位不变,仍然是 1
// 对其余位取反
// 原码的数值部分 0000000 00000000 00000000 00000101 取反后得到 1111111 11111111 11111111 11111010。
反码:11111111 11111111 11111111 11111010
补码
补码是在反码的基础上加 1 得到的,它是计算机中最常用的表示有符号数的方式,因为使用补码可以方便地进行加减运算。
cpp
原码:10000000 00000000 00000000 00000101
反码:11111111 11111111 11111111 11111010
//直接加 1
11111111 11111111 11111111 11111010
+ 00000000 00000000 00000000 00000001
11111111 11111111 11111111 11111011
//补码:11111111 11111111 11111111 11111011
为什么使用补码?
-
简化运算 :使用补码可以将减法运算转换为加法运算,这样硬件只需要实现加法器就可以同时完成加法和减法运算。例如,对于
a - b
,可以表示为a + (-b)
,而-b
的补码可以通过b
的补码取反加 1 得到。cpp// 要计算 3 - 5,在计算机中会将其转换为 3 + (-5) // 3 的原码和补码相同 原码:00000000 00000000 00000000 00000011 补码:00000000 00000000 00000000 00000011 // -5 的原码 原码:10000000 00000000 00000000 00000101 反码:11111111 11111111 11111111 11111010 补码:11111111 11111111 11111111 11111011 //计算 3 + (-5) 00000000 00000000 00000000 00000011 (3 的补码) + 11111111 11111111 11111111 11111011 (-5 的补码) 11111111 11111111 11111111 11111110 // 这是一个负数的补码 // 将其转换回原码来查看结果 // 先对补码取反加 1 得到原码 // 补码:11111111 11111111 11111111 11111110 // 取反:10000000 00000000 00000000 00000001 // 加 1:10000000 00000000 00000000 00000010 // 所以结果是 -2,即 3 - 5 = -2。
-
唯一表示零 :使用原码和反码表示有符号数时,零有正零和负零两种表示方式,而使用补码 表示时,零只有一种表示方式(全零)。
总结
- 原码:最直观,但在加减运算时需要单独处理符号位,不便于硬件实现。
- 反码:在原码基础上对数值位取反,但仍存在正负零的问题。
- 补码:在反码基础上加 1,解决了正负零问题,并且可以将减法转换为加法,方便硬件实现运算
二进制数的应用
标志位操作
使用二进制的位来表示不同的标志。
cpp
#include <stdio.h>
#define FLAG_A 0b0001
#define FLAG_B 0b0010
#define FLAG_C 0b0100
int main() {
int flags = 0;
flags |= FLAG_A; // 设置 FLAG_A
flags |= FLAG_B; // 设置 FLAG_B
if (flags & FLAG_A) {
printf("FLAG_A 已设置\n");
}
if (flags & FLAG_B) {
printf("FLAG_B 已设置\n");
}
if (flags & FLAG_C) {
printf("FLAG_C 已设置\n");
}
return 0;
}
位掩码
使用位掩码来提取或修改特定的位。
cpp
#include <stdio.h>
int main() {
int num = 0b10101010;
int mask = 0b00110000;
int result = num & mask; // 提取特定的位
printf("提取结果: %d\n", result); // 输出为 0b00100000
return 0;
}
八进制(Octal)
使用数字 0
到 7
,在 C 语言中,以数字 0
开头表示八进制数。
八进制转十进制
从右往左,将八进制数的每一位乘以 8^n(n 从 0 开始),然后将结果相加。
cpp
013 八进制 表示 = 1 乘 8的一次方 + 3 乘 8的零次方
= 8 + 3
= 11(十进制)
十进制转八进制
将十进制数除以 8,取余数,将商继续除以 8,直到商为 0。将每次得到的余数从下往上排列,就是对应的八进制数。
cpp
将十进制数 10 转换为八进制
10 ÷ 8 = 1 ······ 2
1 ÷ 8 = 0 ······ 1
// 结果是 012
十进制(Decimal)
是我们日常生活中最常用的计数系统,使用数字 0
到 9
。在 C 语言中,直接使用数字表示十进制数,例如 10
, 255
, 0
等。
cpp
11(十进制)表示 = 1 乘 10的一次方 + 1 乘 10的零次方
= 10 + 1
= 11
十六进制(Hexadecimal)
使用数字**0
到 9
和字母 A
到 F
(或 a
到 f
)**表示,在 C 语言中,以 0x
或 0X
开头表示十六进制数。
十六进制转十进制
从右往左,将十六进制数的每一位乘以 16^n (n 从 0 开始),对于 A 到 F 的数字,其值分别为 10 到 15。将结果相加。
cpp
0xFF 十六进制 表示 = 15 乘 16的一次方 + 15 乘 16的零次方
= 240 + 15
= 255
十进制转十六进制
将十进制数除以 16,取余数,将商继续除以 16,直到商为 0。余数为 10 到 15 时用 A 到 F 表示,将每次得到的余数从下往上排列,就是对应的十六进制数。
cpp
将十进制数 255 转换为十六进制
255 ÷ 16 = 15 ······ 15 (F)
15 ÷ 16 = 0 ······ 15 (F)
// 结果是 0xFF
二进制与其他进制的转换
-
二进制转八进制
-
方法一 :先将二进制转十进制,再将十进制转八进制。
cpp// 假设我们有二进制数 101101 // 二进制转十进制 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 =32 + 0 + 8 + 4 + 0 + 1 = 45(十进制) // 十进制转八进制 45 ÷ 8 = 5······5(余数) 5 ÷ 8 = 0······5(余数) // 所以八进制的结果是55
cpp#include <stdio.h> #include <math.h> // 二进制转十进制 int binaryToDecimal(long long binary) { int decimal = 0; int power = 0; while (binary > 0) { decimal += (binary % 10) * pow(2, power); binary /= 10; power++; } return decimal; } // 十进制转八进制 int decimalToOctal(int decimal) { int octal = 0; int i = 1; while (decimal > 0) { octal += (decimal % 8) * i; decimal /= 8; i *= 10; } return octal; } int main() { long long binary = 101101; int decimal = binaryToDecimal(binary); int octal = decimalToOctal(decimal); printf("二进制数 %lld 转换为八进制数是: %d\n", binary, octal); return 0; }
-
方法二 (直接转换法):从二进制数的小数点开始,向左(或向右)每三位一组划分(不够三位时,高位补0),然后将每组二进制数转换成对应的八进制数。
cpp// 由于 2^3 = 8,所以可以将二进制数按三位一组划分,每组二进制数可以直接对应一个八进制数 // 对于二进制数 101101 // 分组:101 101(高位补 0 后) // 101 对应八进制 5,101 对应八进制 5 // 八进制结果是 55。
cpp#include <stdio.h> #include <string.h> // 二进制转八进制 int binaryToOctalDirect(char *binary) { int octal = 0; int len = strlen(binary); int i = 0; while (i < len) { int group = 0; int base = 1; for (int j = 0; j < 3 && i < len; j++) { group += (binary[len - 1 - i] - '0') * base; base *= 2; i++; } octal = octal * 10 + group; } return octal; } int main() { char binary[] = "101101"; int octal = binaryToOctalDirect(binary); printf("二进制数 %s 转换为八进制数是: %d\n", binary, octal); return 0; }
-
-
二进制转十六进制
-
方法一 :先将二进制转十进制,再将十进制转十六进制。
cpp// 假设我们有二进制数 1101101 // 二进制转十进制 1 * 2^6 + 1 * 2^5 + 0 * 2^4 + 1 * 2^3 + 1 * 2^2 + 0 * 2^1 + 1 * 2^0 =64 + 32 + 0 + 8 + 4 + 0 + 1 =109(十进制) // 十进制转十六进制 109 ÷ 16 =6······13(余数,用 D 表示) 6 ÷ 16 =0······6 // 十六进制结果是 6D
cpp#include <stdio.h> #include <math.h> // 二进制转十进制 int binaryToDecimal(long long binary) { int decimal = 0; int power = 0; while (binary > 0) { decimal += (binary % 10) * pow(2, power); binary /= 10; power++; } return decimal; } // 十进制转十六进制 void decimalToHex(int decimal) { char hex[100]; int i = 0; while (decimal > 0) { int remainder = decimal % 16; if (remainder < 10) { hex[i++] = remainder + '0'; } else { hex[i++] = remainder - 10 + 'A'; } decimal /= 16; } for (int j = i - 1; j >= 0; j--) { printf("%c", hex[j]); } printf("\n"); } int main() { long long binary = 1101101; int decimal = binaryToDecimal(binary); printf("二进制数 %lld 转换为十六进制数是: ", binary); decimalToHex(decimal); return 0; }
-
方法二 (直接转换法):从二进制数的小数点开始,向左(或向右)每四位一组划分(不够四位时,高位补0),然后将每组二进制数转换成对应的十六进制数。
cpp// 由于 2^4=16,所以可以将二进制数按四位一组划分,每组二进制数可以直接对应一个十六进制数 // 对于二进制数 1101101 分组:0110 1101(高位补 0 后) 0110 对应十六进制 6,1101 对应十六进制 D。 所以十六进制结果是 6D。
cpp#include <stdio.h> #include <string.h> // 二进制转十六进制 void binaryToHexDirect(char *binary) { int len = strlen(binary); for (int i = len - 1; i >= 0; i -= 4) { int group = 0; int base = 1; for (int j = 0; j < 4 && i - j >= 0; j++) { group += (binary[i - j] - '0') * base; base *= 2; } if (group < 10) { printf("%d", group); } else { printf("%c", group - 10 + 'A'); } } printf("\n"); } int main() { char binary[] = "1101101"; printf("二进制数 %s 转换为十六进制数是: ", binary); binaryToHexDirect(binary); return 0; }
-
八进制与十六进制的转换
-
八进制转十六进制
-
方法一 :先将八进制转十进制,再将十进制转十六进制。
cpp// 假设我们有八进制数 345。 // 八进制转十进制 = 3 * 8^2 + 4 * 8^1 + 5 * 8^0 =192 + 32 +5 =229(十进制) 十进制转十六进制 229 ÷ 16 =14······ 5 (余数,用 5 表示) 14 ÷ 16 =0······ 14 (余数,用 E 表示) //十六进制结果是 E5
cpp#include <stdio.h> #include <math.h> // 八进制转十进制 int octalToDecimal(int octal) { int decimal = 0; int power = 0; while (octal > 0) { decimal += (octal % 10) * pow(8, power); octal /= 10; power++; } return decimal; } // 十进制转十六进制 void decimalToHex(int decimal) { char hex[100]; int i = 0; while (decimal > 0) { int remainder = decimal % 16; if (remainder < 10) { hex[i++] = remainder + '0'; } else { hex[i++] = remainder - 10 + 'A'; } decimal /= 16; } for (int j = i - 1; j >= 0; j--) { printf("%c", hex[j]); } printf("\n"); } int main() { int octal = 345; int decimal = octalToDecimal(octal); printf("八进制数 %d 转换为十六进制数是: ", octal); decimalToHex(decimal); return 0; }
-
方法二 (间接转换法):先将八进制转二进制,再将二进制转十六进制。
cpp// 对于八进制数 345 // 八进制转二进制 // 3 对应 011,4 对应 100,5 对应 101 // 二进制数为 011100101 // 二进制转十六进制 // 分组:0111 0010 1(高位补 0 后)。 // 0111 对应 7,0010 对应 2,0001 对应 1。 // 所以十六进制结果是 E5。
cpp#include <stdio.h> #include <string.h> // 八进制转二进制 void octalToBinary(int octal) { char binary[100] = ""; int index = 0; while (octal > 0) { int digit = octal % 10; switch (digit) { case 0: strcat(binary, "000"); break; case 1: strcat(binary, "001"); break; case 2: strcat(binary, "010"); break; case 3: strcat(binary, "011"); break; case 4: strcat(binary, "100"); break; case 5: strcat(binary, "101"); break; case 6: strcat(binary, "110"); break; case 7: strcat(binary, "111"); break; } octal /= 10; } int len = strlen(binary); for (int i = len - 1; i >= 0; i--) { printf("%c", binary[i]); } printf("\n"); } // 二进制转十六进制 void binaryToHex(char *binary) { int len = strlen(binary); for (int i = len - 1; i >= 0; i -= 4) { int group = 0; int base = 1; for (int j = 0; j < 4 && i - j >= 0; j++) { group += (binary[i - j] - '0') * base; base *= 2; } if (group < 10) { printf("%d", group); } else { printf("%c", group - 10 + 'A'); } } printf("\n"); } int main() { int octal = 345; printf("八进制数 %d 转换为十六进制数的过程:\n", octal); octalToBinary(octal); binaryToHex(octalToBinary(octal)); return 0; }
-
-
十六进制转八进制
-
方法一 :先将十六进制转十进制,再将十进制转八进制。
cpp有十六进制数 A3 十六进制转十进制 =10* 16^1+3*16^0 =160+3 =163(十进制) 十进制转八进制 163 ÷ 8 =20 ······3 20 ÷ 8 =2 ······4 2 ÷ 8 =0 ······2 所以八进制结果是 243
cpp#include <stdio.h> #include <math.h> // 十六进制转十进制 int hexToDecimal(char *hex) { int decimal = 0; int len = strlen(hex); for (int i = len - 1, power = 0; i >= 0; i--, power++) { int value; if (hex[i] >= '0' && hex[i] <= '9') { value = hex[i] - '0'; } else if (hex[i] >= 'A' && hex[i] <= 'F') { value = hex[i] - 'A' + 10; } else if (hex[i] >= 'a' && hex[i] <= 'F') { value = hex[i] - 'a' + 10; } decimal += value * pow(16, power); } return decimal; } // 十进制转八进制 int decimalToOctal(int decimal) { int octal = 0; int i = 1; while (decimal > 0) { octal += (decimal % 8) * i; decimal /= 8; i *= 10; } return octal; } int main() { char hex[] = "A3"; int decimal = hexToDecimal(hex); int octal = decimalToOctal(decimal); printf("十六进制数 %s 转换为八进制数是: %d\n", hex, octal); return 0; }
-
追更
printf函数的应用
width应用
cpp
#include <stdio.h>
int main() {
// 左对齐
printf("左对齐: %-8d\n", 10);
// 强制输出正负号
printf("强制输出正负号: %+d\n", 10);
printf("强制输出正负号: %+d\n", -10);
// 正数前输出空格,负数前输出负号
printf("正数前输出空格: % d\n", 10);
printf("负数前输出负号: % d\n", -10);
// 用 0 填充宽度
printf("用 0 填充宽度: %08d\n", 10);
printf("用 0 填充宽度: %08d\n", -10);
// 对于 %o,输出八进制数时加前缀 0;对于 %x 或 %X,输出十六进制数时加前缀 0x 或 0X;
// 对于 %f、%e 或 %g,即使没有小数部分也输出小数点
printf("八进制加前缀: %#o\n", 10);
printf("十六进制加前缀 (小写): %#x\n", 10);
printf("十六进制加前缀 (大写): %#X\n", 10);
printf("浮点数加小数点: %#f\n", 10.0);
printf("浮点数加小数点: %#e\n", 10.0);
printf("浮点数加小数点: %#g\n", 10.0);
return 0;
}
控制台打印
cpp
左对齐: 10
强制输出正负号: +10
强制输出正负号: -10
正数前输出空格: 10
负数前输出负号: -10
用 0 填充宽度: 00000010
用 0 填充宽度: -0000010
八进制加前缀: 012
十六进制加前缀 (小写): 0xa
十六进制加前缀 (大写): 0XA
浮点数加小数点: 10.000000
浮点数加小数点: 1.000000e+01
浮点数加小数点: 10.0000
Flags应用
cpp
#include <stdio.h>
int main() {
// 左对齐
int num1 = 42;
printf("左对齐: |%-8d|\n", num1);
// 强制输出正负号
int num2 = 33;
int num3 = -25;
printf("强制输出正负号 (正数): |%+d|\n", num2);
printf("强制输出正负号 (负数): |%+d|\n", num3);
// 正数前输出空格,负数前输出负号
int num4 = 18;
int num5 = -12;
printf("正数前输出空格: |% d|\n", num4);
printf("负数前输出负号: |% d|\n", num5);
// 用 0 填充宽度
int num6 = 7;
int num7 = -49;
printf("用 0 填充宽度 (正数): |%08d|\n", num6);
printf("用 0 填充宽度 (负数): |%08d|\n", num7);
// 对于 %o,输出八进制数时加前缀 0;对于 %x 或 %X,输出十六进制数时加前缀 0x 或 0X;对于 %f、%e 或 %g,即使没有小数部分也输出小数点
int num8 = 20;
float num9 = 123.0;
printf("八进制加前缀: |%#o|\n", num8);
printf("十六进制加前缀 (小写): |%#x|\n", num8);
printf("十六进制加前缀 (大写): |%#X|\n", num8);
printf("浮点数加小数点: |%#f|\n", num9);
printf("浮点数加小数点 (科学计数法): |%#e|\n", num9);
printf("浮点数加小数点 (自动选择格式): |%#g|\n", num9);
return 0;
}
cpp
左对齐: |42 |
强制输出正负号 (正数): |+33|
强制输出正负号 (负数): |-25|
正数前输出空格: | 18|
负数前输出负号: |-12|
用 0 填充宽度 (正数): |00000007|
用 0 填充宽度 (负数): |-00000049|
八进制加前缀: |024|
十六进制加前缀 (小写): |0x14|
十六进制加前缀 (大写): |0X14|
浮点数加小数点: |123.000000|
浮点数加小数点 (科学计数法): |1.230000e+02|
浮点数加小数点 (自动选择格式): |123.000|
Precision应用
cpp
#include <stdio.h>
int main() {
// 对于浮点数,指定小数点后的位数
float pi = 3.1415926;
float euler = 2.7182818;
printf("pi 保留两位小数: %.2f\n", pi);
printf("euler 保留三位小数: %.3f\n", euler);
// 对于字符串,指定最大输出长度
char str[] = "Hello, World!";
printf("字符串截取前 5 个字符: %.5s\n", str);
printf("字符串截取前 8 个字符: %.8s\n", str);
return 0;
}
cpp
pi 保留两位小数: 3.14
euler 保留三位小数: 2.718
字符串截取前 5 个字符: Hello
字符串截取前 8 个字符: Hello, W
Length 应用
cpp
#include <stdio.h>
int main() {
// 使用 h 表示短整型
short short_num = 10;
printf("短整型: %hd\n", short_num);
// 使用 l 表示长整型
long long_num = 1000000L;
printf("长整型: %ld\n", long_num);
// 使用 l 表示双精度浮点数
double double_num = 3.14;
printf("双精度浮点数: %lf\n", double_num);
// 使用 ll 表示长长整型
long long long_long_num = 123456789012345LL;
printf("长长整型: %lld\n", long_long_num);
// 使用 L 表示长双精度浮点数
long double long_double_num = 3.14L;
printf("长双精度浮点数: %Lf\n", long_double_num);
return 0;
}
cpp
短整型: 10
长整型: 1000000
双精度浮点数: 3.140000
长长整型: 123456789012345
长双精度浮点数: 3.140000