二进制、八进制、十进制和十六进制的相互转换
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 |
#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 位小数 |
#include <stdio.h>int main() {int num = 10;float f = 3.14159;// 输出整数,宽度为 5printf("整数: %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
前加一个空格:
#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
函数清除多余字符
#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 开始),然后将结果相加。
1011(二进制)表示:1 乘 2的三次方 + 0 乘 2的二次方 + 1 乘 2的一次方 + 1 乘 2的零次方= 8 + 0 + 2 + 1=11(十进制)
十进制转二进制
将十进制数除以 2,取余数,将商继续除以 2,直到商为 0。将每次得到的余数从下往上排列,就是对应的二进制数。
// 将十进制数 10 转换为二进制10 ÷ 2 = 5······0
5 ÷ 2 = 2······1
2 ÷ 2 = 1······0
1 ÷ 2 = 0······1
//因此十进制的二进制从下往上排列余数 1010
位运算符
按位与(&
)
对两个操作数的每一位进行逻辑与操作(即当两位都为 1 时结果为 1,否则为 0)。
#include <stdio.h>int main() {int a = 0b1010; // 二进制表示,C99 标准开始支持,也可写成 10 然后通过其他方式理解其为二进制int b = 0b1100;int result = a & b; // 按位与printf("按位与结果: %d\n", result); // 输出为 8,即 0b1000return 0;
}
按位或(|
)
对两个操作数的每一位进行逻辑或操作(即当两位中至少有一位为 1 时结果为 1,否则为 0)。
#include <stdio.h>int main() {int a = 0b1010;int b = 0b1100;int result = a | b; // 按位或printf("按位或结果: %d\n", result); // 输出为 14,即 0b1110return 0;
}
按位异或(^
)
对两个操作数的每一位进行逻辑异或操作(即当两位相异时结果为 1,相同时为 0)。
#include <stdio.h>int main() {int a = 0b1010;int b = 0b1100;int result = a ^ b; // 按位异或printf("按位异或结果: %d\n", result); // 输出为 6,即 0b0110return 0;
}
按位取反(~
)
对操作数的每一位进行取反操作(即 0 变为 1,1 变为 0)。
#include <stdio.h>int main() {int a = 0b1010;int result = ~a; // 按位取反printf("按位取反结果: %d\n", result); // 输出为 -11,即 0b1111111111111111111111111111110101return 0;
}
左移(<<
)
将操作数的二进制表示向左移动指定的位数,右边补 0。
#include <stdio.h>int main() {int a = 0b1010;int result = a << 1; // 左移 1 位printf("左移结果: %d\n", result); // 输出为 20,即 0b10100return 0;
}
右移(>>
)
将操作数的二进制表示向右移动指定的位数,对于无符号数,左边补 0;对于有符号数,根据编译器和系统可能是补 0 或补符号位。
#include <stdio.h>int main() {int a = 0b1010;int result = a >> 1; // 右移 1 位printf("右移结果: %d\n", result); // 输出为 5,即 0b0101return 0;
}
二进制数的存储和表示
在内存中,整数通常以二进制补码的形式存储。对于有符号整数:
- 正数的补码就是其原码(二进制表示)。
- 负数的补码是其原码取反加 1。
#include <stdio.h>int main() {int a = -5;// 原码:10000000 00000000 00000000 00000101// 反码:11111111 11111111 11111111 11111010// 补码:11111111 11111111 11111111 11111011printf("存储的二进制补码表示: %d\n", a); // 输出为 -5return 0;
}
原码
原码是最直观的表示有符号数的方法,它将最高位用作符号位(0 表示正数,1 表示负数),其余位表示数值的绝对值。
原码:10000000 00000000 00000000 00000101 // 最高位 1 表示这个数是负数
// 其余位 0000000 00000000 00000000 00000101 表示数值部分,即 5。
// 因此,这个原码表示的是 -5。
反码
反码是对原码除符号位外的所有位取反得到的。
原码:10000000 00000000 00000000 00000101// 符号位不变,仍然是 1
// 对其余位取反// 原码的数值部分 0000000 00000000 00000000 00000101 取反后得到 1111111 11111111 11111111 11111010。
反码:11111111 11111111 11111111 11111010
补码
补码是在反码的基础上加 1 得到的,它是计算机中最常用的表示有符号数的方式,因为使用补码可以方便地进行加减运算。
原码: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 得到。// 要计算 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,解决了正负零问题,并且可以将减法转换为加法,方便硬件实现运算
二进制数的应用
标志位操作
使用二进制的位来表示不同的标志。
#include <stdio.h>#define FLAG_A 0b0001
#define FLAG_B 0b0010
#define FLAG_C 0b0100int main() {int flags = 0;flags |= FLAG_A; // 设置 FLAG_Aflags |= FLAG_B; // 设置 FLAG_Bif (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;
}
位掩码
使用位掩码来提取或修改特定的位。
#include <stdio.h>int main() {int num = 0b10101010;int mask = 0b00110000;int result = num & mask; // 提取特定的位printf("提取结果: %d\n", result); // 输出为 0b00100000return 0;
}
八进制(Octal)
使用数字 0
到 7
,在 C 语言中,以数字 0
开头表示八进制数。
八进制转十进制
从右往左,将八进制数的每一位乘以 8^n(n 从 0 开始),然后将结果相加。
013 八进制 表示 = 1 乘 8的一次方 + 3 乘 8的零次方= 8 + 3= 11(十进制)
十进制转八进制
将十进制数除以 8,取余数,将商继续除以 8,直到商为 0。将每次得到的余数从下往上排列,就是对应的八进制数。
将十进制数 10 转换为八进制10 ÷ 8 = 1 ······ 2
1 ÷ 8 = 0 ······ 1// 结果是 012
十进制(Decimal)
是我们日常生活中最常用的计数系统,使用数字 0
到 9
。在 C 语言中,直接使用数字表示十进制数,例如 10
, 255
, 0
等。
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。将结果相加。
0xFF 十六进制 表示 = 15 乘 16的一次方 + 15 乘 16的零次方= 240 + 15= 255
十进制转十六进制
将十进制数除以 16,取余数,将商继续除以 16,直到商为 0。余数为 10 到 15 时用 A 到 F 表示,将每次得到的余数从下往上排列,就是对应的十六进制数。
将十进制数 255 转换为十六进制 255 ÷ 16 = 15 ······ 15 (F)
15 ÷ 16 = 0 ······ 15 (F)// 结果是 0xFF
二进制与其他进制的转换
-
二进制转八进制
- 方法一:先将二进制转十进制,再将十进制转八进制。
// 假设我们有二进制数 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
#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),然后将每组二进制数转换成对应的八进制数。
// 由于 2^3 = 8,所以可以将二进制数按三位一组划分,每组二进制数可以直接对应一个八进制数 // 对于二进制数 101101 // 分组:101 101(高位补 0 后) // 101 对应八进制 5,101 对应八进制 5 // 八进制结果是 55。
#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; }
- 方法一:先将二进制转十进制,再将十进制转八进制。
-
二进制转十六进制
- 方法一:先将二进制转十进制,再将十进制转十六进制。
// 假设我们有二进制数 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
#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),然后将每组二进制数转换成对应的十六进制数。
// 由于 2^4=16,所以可以将二进制数按四位一组划分,每组二进制数可以直接对应一个十六进制数// 对于二进制数 1101101分组:0110 1101(高位补 0 后)0110 对应十六进制 6,1101 对应十六进制 D。 所以十六进制结果是 6D。
#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; }
- 方法一:先将二进制转十进制,再将十进制转十六进制。
八进制与十六进制的转换
-
八进制转十六进制
- 方法一:先将八进制转十进制,再将十进制转十六进制。
// 假设我们有八进制数 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
#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; }
- 方法二(间接转换法):先将八进制转二进制,再将二进制转十六进制。
// 对于八进制数 345 // 八进制转二进制 // 3 对应 011,4 对应 100,5 对应 101 // 二进制数为 011100101 // 二进制转十六进制 // 分组:0111 0010 1(高位补 0 后)。 // 0111 对应 7,0010 对应 2,0001 对应 1。 // 所以十六进制结果是 E5。
#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; }
- 方法一:先将八进制转十进制,再将十进制转十六进制。
-
十六进制转八进制
- 方法一:先将十六进制转十进制,再将十进制转八进制。
有十六进制数 A3十六进制转十进制 =10* 16^1+3*16^0 =160+3 =163(十进制)十进制转八进制 163 ÷ 8 =20 ······3 20 ÷ 8 =2 ······4 2 ÷ 8 =0 ······2所以八进制结果是 243
#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应用
#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;
}
控制台打印
左对齐: 10
强制输出正负号: +10
强制输出正负号: -10
正数前输出空格: 10
负数前输出负号: -10
用 0 填充宽度: 00000010
用 0 填充宽度: -0000010
八进制加前缀: 012
十六进制加前缀 (小写): 0xa
十六进制加前缀 (大写): 0XA
浮点数加小数点: 10.000000
浮点数加小数点: 1.000000e+01
浮点数加小数点: 10.0000
Flags应用
#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;
}
左对齐: |42 |
强制输出正负号 (正数): |+33|
强制输出正负号 (负数): |-25|
正数前输出空格: | 18|
负数前输出负号: |-12|
用 0 填充宽度 (正数): |00000007|
用 0 填充宽度 (负数): |-00000049|
八进制加前缀: |024|
十六进制加前缀 (小写): |0x14|
十六进制加前缀 (大写): |0X14|
浮点数加小数点: |123.000000|
浮点数加小数点 (科学计数法): |1.230000e+02|
浮点数加小数点 (自动选择格式): |123.000|
Precision应用
#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;
}
pi 保留两位小数: 3.14
euler 保留三位小数: 2.718
字符串截取前 5 个字符: Hello
字符串截取前 8 个字符: Hello, W
Length 应用
#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;
}
短整型: 10
长整型: 1000000
双精度浮点数: 3.140000
长长整型: 123456789012345
长双精度浮点数: 3.140000
相关文章:
二进制、八进制、十进制和十六进制的相互转换
printf 函数 printf 函数是 C 语言中用于将格式化的数据输出到标准输出(通常是屏幕)的函数。它位于 stdio.h 头文件中,因此在使用之前需要包含该头文件。 printf 函数的格式说明符 格式说明符说明示例%d 或 %i输出或输入十进制有符号整数p…...
分布式缓存redis
分布式缓存redis 1 redis单机(单节点)部署缺点 (1)数据丢失问题:redis是内存存储,服务重启可能会丢失数据 (2)并发能力问题:redis单节点(单机)部…...
day08_Kafka
文章目录 day08_Kafka课程笔记一、今日课程内容一、消息队列(了解)**为什么消息队列就像是“数据的快递员”?****实际意义**1、产生背景2、消息队列介绍2.1 常见的消息队列产品2.2 应用场景2.3 消息队列中两种消息模型 二、Kafka的基本介绍1、…...
fbx 环境搭建
python 3.7 3.8 版本支持 https://github.com/Shiiho11/FBX-Python-SDK-for-Python3.x 只有python3.7 https://www.autodesk.com/developer-network/platform-technologies/fbx-sdk-2020-3 scipy安装: python安装scipy_scipy1.2.1库怎么安装-CSDN博客 smpl 2 fbx…...
【大数据】机器学习------神经网络模型
一、神经网络模型 1. 基本概念 神经网络是一种模拟人类大脑神经元结构的计算模型,由多个神经元(节点)组成,这些节点按照不同层次排列,通常包括输入层、一个或多个隐藏层和输出层。每个神经元接收来自上一层神经元的输…...
YOLOv5训练长方形图像详解
文章目录 YOLOv5训练长方形图像详解一、引言二、数据集准备1、创建文件夹结构2、标注图像3、生成标注文件 三、配置文件1、创建数据集配置文件2、选择模型配置文件 四、训练模型1、修改训练参数2、开始训练 五、使用示例1、测试模型2、评估模型 六、总结 YOLOv5训练长方形图像详…...
【Vim Masterclass 笔记11】S06L24 + L25:Vim 文本的插入、变更、替换与连接操作同步练习(含点评课)
文章目录 S06L24 Exercise 06 - Inserting, Changing, Replacing, and Joining1 训练目标2 操作指令2.1. 打开 insert-practice.txt 文件2.2. 练习 i 命令2.3. 练习 I 命令2.4. 练习 a 命令2.5. 练习 A 命令2.6. 练习 o 命令2.7. 练习 O 命令2.8. 练习 j 命令2.9. 练习 R 命令2…...
【计算机网络】深入浅出计算机网络
第一章 计算机网络在信息时代的作用 计算机网络已由一种通信基础设施发展成一种重要的信息服务基础设施 CNNIC 中国互联网网络信息中心 因特网概述 网络、互联网和因特网 网络(Network)由若干结点(Node)和连接这些结点的链路…...
HTTP详解——HTTP基础
HTTP 基本概念 HTTP 是超文本传输协议 (HyperText Transfer Protocol) 超文本传输协议(HyperText Transfer Protocol) HTTP 是一个在计算机世界里专门在 两点 之间 传输 文字、图片、音视频等 超文本 数据的 约定和规范 1. 协议 约定和规范 2. 传输 两点之间传输…...
ubuntu 安装 python
一、安装python依赖的包。 sudo apt-get install -y make zlib1g zlib1g-dev build-essential libbz2-dev libsqlite3-dev libssl-dev libxslt1-dev libffi-dev openssl python3-tklibsqlite3-dev需要在python安装之前安装,如果用户操作系统已经安装python环境&…...
CSS:定位
CSS定位核心知识点详解 CSS定位是网页布局中的重要概念,它允许开发者将元素放置在页面的指定位置。以下是对CSS定位所有相关详细重要知识点的归纳: 为什么要使用定位: 小黄色块在图片上移动,吸引用户的眼球。 当我们滚动窗口的…...
ros2笔记-7.1 机器人导航介绍
7.1 机器人导航介绍 7.1.1 同步定位与地图构建 想要导航,就是要确定当前位置跟目标位置。确定位置就是定位问题。 手机的卫星导航在室内 受屏蔽,需要其他传感器获取位置信息。 利用6.5 章节的仿真,打开并运行 会发现轨迹跟障碍物都被记录…...
一些常见的Java面试题及其答案
Java基础 1. Java中的基本数据类型有哪些? 答案:Java中的基本数据类型包括整数类型(byte、short、int、long)、浮点类型(float、double)、字符类型(char)和布尔类型(boo…...
今日总结 2025-01-14
学习目标 掌握运用 VSCode 开发 uni - app 的配置流程。学会将配置完善的项目作为模板上传至 Git,实现复用。项目启动 创建项目:借助 Vue - Cli 方式创建项目,推荐从国内地址 https://gitee.com/dcloud/uni - preset - vue/repository/archiv…...
图像处理|开运算
开运算是图像形态学中的一种基本操作,通常用于去除小的噪声点,同时保留目标物体的整体形状。它结合了 腐蚀 和 膨胀 操作,且顺序为 先腐蚀后膨胀(先腐蚀后膨胀,胀开了,开运算)。 开运算的作用 …...
基于当前最前沿的前端(Vue3 + Vite + Antdv)和后台(Spring boot)实现的低代码开发平台
项目是一个基于当前最前沿的前端技术栈(Vue3 Vite Ant Design Vue,简称Antdv)和后台技术栈(Spring Boot)实现的低代码开发平台。以下是对该项目的详细介绍: 一、项目概述 项目名称:lowcode-s…...
ASP.NET Core - 依赖注入(三)
ASP.NET Core - 依赖注入(三) 4. 容器中的服务创建与释放 4. 容器中的服务创建与释放 我们使用了 IoC 容器之后,服务实例的创建和销毁的工作就交给了容器去处理,前面也讲到了服务的生命周期,那三种生命周期中对象的创…...
Unity 视频导入unity后,播放时颜色变得很暗很深,是什么原因导致?
视频正常播放时的颜色: 但是,当我在unity下,点击视频播放按钮时,视频的颜色立马变得十分昏暗: 解决办法: 将File—BuildSettings—PlayerSettings—OtherSettings下的Color Space改为:Gamma即可…...
数仓建模(五)选择数仓技术栈:Hive ClickHouse 其它
在大数据技术的飞速发展下,数据仓库(Data Warehouse,简称数仓)成为企业处理和分析海量数据的核心工具。市场上主流数仓技术栈丰富,如Hive、ClickHouse、Druid、Greenplum等,对于初学者而言,选择…...
MySQL主从:如何处理“Got Fatal Error 1236”或 MY-013114 错误(percona译文)
错误的 GTID 如今,典型的复制设置使用 GTID 模式,完整的错误消息可能如下所示: mysql > show replica status\G *************************** 1. row ***************************Replica_IO_Running: NoReplica_SQL_Running: YesLast_I…...
01.14周二F34-Day55打卡
文章目录 1. Jim 在看电视的时候他的老婆正在做饭。(两个动作同时进行)2. 他刚睡着电话就响了。3. 我正在想事情,这时忽然有人从后面抓我胳膊。4. 我们总是边吃火锅边唱歌。5. 他一听说出了事故,马上就来了现场。6. He entered the room until I returned. (英译汉)7.直到…...
Docker 部署 Typecho
1. 官网 https://typecho.org/插件 & 主题 https://github.com/typecho-fans/plugins https://typechx.com/ https://typecho.work/2. 通过 compose 文件安装 github官网: https://github.com/typecho/Dockerfile 新建一个目录,存放 typecho 的相…...
electron 打包后的 exe 文件,运行后是空白窗口
一、代码相关问题 1. 页面加载失败 1.1 原因 在 Electron 应用中,若loadFile或loadURL方法指定的页面路径或 URL 错误,就无法正确加载页面,导致窗口空白。 1.2. 解决 仔细检查loadFile或loadURL方法中传入的路径或 URL 是否正确…...
《leetcode-runner》如何手搓一个debug调试器——架构
本文主要聚焦leetcode-runner对于debug功能的整体设计,并讲述设计原因以及存在的难点 设计引入 让我们来思考一下,一个最简单的调试器需要哪些内容 首先,它能够接受用户的输入 其次,它能够读懂用户想让调试器干嘛,…...
matlab实现了一个优化的遗传算法,用于求解注汽站最优位置的问题
function [best_chromosome, best_fitness] optimized_genetic_algorithm()%% 遗传算法参数初始化% 定义井信息,包括坐标、管道长度、流量、压力等wells defineWells(); % 返回井的结构体数组N length(wells); % 注汽井数量% 遗传算法相关参数L_chromosome 20; …...
八股学习 Redis
八股学习 Redis 使用场景常见问题问题1、2示例场景缓存穿透解决方案一解决方案二 问题3示例场景缓存击穿解决方案 问题4示例场景缓存雪崩解决方案 问题5示例场景双写一致性强一致方案允许延时一致方案 问题6RDB方式AOF方式两种方式对比 问题7示例场景惰性删除定期删除 使用场景…...
C++ 中 :: 的各种用法
C 中 :: 的各种用法 文章目录 C 中 :: 的各种用法1. 全局作用域解析示例:访问全局变量 2. 类作用域2.1. 访问类的静态成员示例:访问静态成员2.2. 定义类外成员函数示例:定义类外成员函数 3. 命名空间作用域3.1. 访问命名空间中的成员示例&…...
【Redis】初识分布式系统
目录 单机架构 分布式系统 应用数据分离架构 应用服务集群架构 读写分离/主从分离架构 冷热分离架构 垂直分库 微服务架构 分布式名词概念 本篇博文,将根据分布式系统的演进一步一步介绍每一种架构的形式,最后为大家总结了一些分布式中常用的…...
【EI 会议征稿】第四届材料工程与应用力学国际学术会议(ICMEAAE 2025)
2025 4th International Conference on Materials Engineering and Applied Mechanics 重要信息 大会官网:www.icmeaae.com 大会时间:2025年3月7-9日 大会地点:中国西安 截稿时间:2025年1月24日23:59 接受/拒稿通知…...
redisson 连接 redis5报错 ERR wrong number of arguments for ‘auth‘ command
依赖版本 org.redisson:redisson-spring-boot-starter:3.25.2 现象 启动报错 org.redisson.client.RedisException: ERR wrong number of arguments for ‘auth’ command. channel: [xxx] command: (AUTH), params: (password masked) 原因 redis6以下版本认证参数不包含用…...
GPT(General Purpose Timer)定时器
基本概念: 在嵌入式系统中,General Purpose Timer(GPT)是一种非常重要的硬件组件,用于提供定时功能。 定义:通用定时器是一种能够提供精确时间测量和控制功能的电子设备或电路模块。它可以产生周期性的时…...
Node.js - HTTP
1. HTTP请求 HTTP(Hypertext Transfer Protocol,超文本传输协议)是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端(通常是浏览器、手机应用或其他网络工具)发送给服务器的消息,用来请求资源或执行…...
Vue数据响应式,reaction,ref的使用
目录 数据响应式 如何使用 reactionyu区别 数据响应式 什么是数据响应式 简单来说就是当数据变了的时候,页面的展示也会跟着发生变化。 在Vue当中我们有两个函数可以实现这个功能reaction,ref 如何使用 首先这两个函数在是在Vue对象中我们可以先对…...
【Vue实战】Vuex 和 Axios 拦截器设置全局 Loading
目录 1. 效果图 2. 思路分析 2.1 实现思路 2.2 可能存在的问题 2.2.1 并发请求管理 2.2.2 请求快速响应和缓存带来的问题 3. 代码实现 4. 总结 1. 效果图 如下图所示,当路由变化或发起请求时,出现 Loading 等待效果,此时页面不可见。…...
JVM:ZGC详解(染色指针,内存管理,算法流程,分代ZGC)
1,ZGC(JDK21之前) ZGC 的核心是一个并发垃圾收集器,所有繁重的工作都在Java 线程继续执行的同时完成。这极大地降低了垃圾收集对应用程序响应时间的影响。 ZGC为了支持太字节(TB)级内存,设计了基…...
在 Ubuntu 上安装和配置 Redis
在 Ubuntu 上安装和配置 Redis,并使用发布-订阅(Pub/Sub)功能,可以按照以下步骤进行: 一、安装 Redis 1. 更新包列表 首先,更新本地的包列表以确保获取到最新的软件包信息: sudo apt update…...
【WPS】【WORDEXCEL】【VB】实现微软WORD自动更正的效果
1. 代码规范方面 添加 Option Explicit:强制要求显式声明所有变量,这样可以避免因变量名拼写错误等情况而出现难以排查的逻辑错误,提高代码的健壮性。使用 On Error GoTo 进行错误处理:通过设置错误处理机制,当代码执行…...
相机SD卡照片数据不小心全部删除了怎么办?有什么方法恢复吗?
前几天,小编在后台友收到网友反馈说他在整理相机里的SD卡,原本是想把那些记录着美好瞬间的照片导出来慢慢欣赏。结果手一抖,不小心点了“删除所有照片”,等他反应过来,屏幕上已经显示“删除成功”。那一刻,…...
【机器学习:十四、TensorFlow与PyTorch的对比分析】
1. 发展背景与社区支持 1.1 TensorFlow的背景与发展 TensorFlow是Google于2015年发布的开源深度学习框架,基于其前身DistBelief系统。作为Google大规模深度学习研究成果的延续,TensorFlow从一开始就定位为生产级框架,强调跨平台部署能力和性…...
从零搭建一个Vue3 + Typescript的脚手架——day1
1.开发环境搭建 (1).配置vite vite简介 Vite 是一个由尤雨溪开发的现代化前端构建工具,它利用了浏览器对 ES 模块的原生支持,极大地提升了开发服务器的启动速度和热更新效率。Vite 不仅适用于 Vue.js,还支持 React、Svelte 等多种框架&…...
unity打包sdk热更新笔记
基础打包需要知识: 安装包大小不要超过2G,AB包数量过多会影响加载和构建,多次IO,用Gradle打包,要支持64位系统,不同的渠道包:让做sdk的人支持,提供渠道包的打包工具 配置系统环境变量…...
算法-贪心算法简单介绍
下面是贪心算法视频课的导学内容. 目录 1. 什么是贪心算法?2. 贪心算法简单的三个例子:1. 找零问题2. 最小路径和问题3. 背包问题 3. 贪心算法的特点4. 贪心算法学习的方式? 1. 什么是贪心算法? 简单来说, 我们称以局部最优进而使得全局最优的一种思想实现出来的算法为贪心…...
1Hive概览
1Hive概览 1hive简介2hive架构3hive与Hadoop的关系4hive与传统数据库对比5hive的数据存储 1hive简介 Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供类SQL查询功能。 其本质是将SQL转换为MapReduce/Spark的任务进…...
Linux SUID提权
文章目录 1. SUID/SGID2. 查找SUID文件3. SUID/SGID提权3.1 SUID配置不当3.2 SUID systemctl提权3.3 $PATH变量劫持 参考 1. SUID/SGID SUID(Set User ID)意味着如果某个用户对属于自己的文件设置了这种权限,那么其他用户在执行这一脚本时也…...
RabbitMQ确保消息可靠性
消息丢失的可能性 支付服务先扣减余额和更新支付状态(这俩是同步调用),然后通过RabbitMq异步调用支付服务更新订单状态。但是有些情况下,可能订单已经支付 ,但是更新订单状态却失败了,这就出现了消息丢失。…...
用plotly制作一条带颜色的时间轴,显示学习情况
前一篇文章我写到用matplotlib制作一条带颜色的时间轴,显示学习情况-CSDN博客,这是我在工作地方写的程序,我回家后发现家里的笔记本用不了matplotlib,所以我尝试用plotly这另外的模块也写一段程序,让我的程序能够回家使…...
MySQL:索引
目录 1.MySQL索引是干什么的 2.铺垫知识 3.单个page的理解 4.页目录 单页情况 多页情况 1.MySQL索引是干什么的 MySQL的索引是提高查询效率,主要提高海量数据的检索速度。 2.铺垫知识 操作系统与磁盘之间IO的基本单位是4kb。 数据库是一个应用层软件&#…...
Kylin: `GLIBC_2.34‘ not found
需要查看服务器GLIBC版本 strings /lib64/libc.so.6 |grep GLIBC_如果没有,有两种办法,一种是libc.so.6降级,但是这样很容易将服务器搞崩溃 所以可以尝试下载对应版本 glibc 打包编译,重新建立软连,下列是RPM资源可以…...
ASP.NET Core - 依赖注入(四)
ASP.NET Core - 依赖注入(四) 4. ASP.NET Core默认服务5. 依赖注入配置变形 4. ASP.NET Core默认服务 之前讲了中间件,实际上一个中间件要正常进行工作,通常需要许多的服务配合进行,而中间件中的服务自然也是通过 Ioc…...
【全套】基于分类算法的学业警示预测信息管理系统
【全套】基于分类算法的学业警示预测信息管理系统 【摘 要】 随着网络技术的发展基于分类算法的学业警示预测信息管理系统是一种新的管理方式,同时也是现代学业预测信息管理的基础,利用互联网的时代与实际情况相结合来改变过去传统的学业预测信息管理中…...