(void *)
避免编译器警告 。
size_t
类型的值,通常用于表示对象的大小 。
%
字符 。
#include
int main() {
// %a 和 %A:十六进制浮点数
float hex_float = 10.125;
printf("Lowercase hex float: %a\n", hex_float);
printf("Uppercase hex float: %A\n", hex_float);
// %c:字符
char character = 'A';
printf("Character: %c\n", character);
// %d 和 %i:十进制整数
int decimal_int = 123;
printf("Decimal integer (using %d): %d\n", decimal_int);
printf("Decimal integer (using %i): %i\n", decimal_int);
// %e 和 %E:科学计数法的浮点数
float scientific_float = 1234567.89;
printf("Scientific float (lowercase e): %e\n", scientific_float);
printf("Scientific float (uppercase E): %E\n", scientific_float);
// %f:小数
float float_num = 3.14159;
printf("Float number: %f\n", float_num);
double double_num = 3.141592653589793;
printf("Double number: %lf\n", double_num);
// %g 和 %G:根据情况自动选择浮点数表示法
double auto_float = 12345678.123456;
printf("Automatic float (lowercase g): %g\n", auto_float);
printf("Automatic float (uppercase G): %G\n", auto_float);
// %hd, %ho, %hx, %hu:short int 相关
short int num = 255;
printf("Decimal short int: %hd\n", num); // 输出十进制短整型
printf("Octal short int: %ho\n", num); // 输出八进制短整型
printf("Hexadecimal short int: %hx\n", num); // 输出十六进制短整型(小写字母)
printf("Unsigned short int: %hu\n", (unsigned short int)num); // 输出无符号短整型
// %ld, %lo, %lx, %lu:long int 相关
long int l_num = 1234567890;
printf("Decimal long int: %ld\n", l_num); // 输出十进制长整型
printf("Octal long int: %lo\n", l_num); // 输出八进制长整型
printf("Hexadecimal long int: %lx\n", l_num); // 输出十六进制长整型(小写字母)
printf("Unsigned long int: %lu\n", (unsigned long int)l_num); // 输出无符号长整型
// %lld, %llo, %llx, %llu:long long int 相关
long long int ll_num = 12345678901234567890LL;
printf("Decimal long long int: %lld\n", ll_num); // 输出十进制长双整型
printf("Octal long long int: %llo\n", ll_num); // 输出八进制长双整型
printf("Hexadecimal long long int: %llx\n", ll_num); // 输出十六进制长双整型(小写字母)
printf("Unsigned long long int: %llu\n", (unsigned long long int)ll_num); // 输出无符 号长双整型
// %Le:科学计数法表示的 long double 类型浮点数
long double long_double_num = 123456789.123456789L;
printf("Long double scientific: %Le\n", long_double_num);
// %Lf:long double 类型浮点数
printf("Long double: %Lf\n", long_double_num);
// %n:已输出的字符串数量
int num_chars = 0;
printf("This is a test string%n", &num_chars);
printf("Number of characters printed before %n: %d\n", num_chars);
// %o:八进制整数
int octal_num = 0123;
printf("Octal integer: %o\n", octal_num);
// %p:指针(用来打印地址)
int *ptr = &decimal_int;
printf("Pointer address: %p\n", (void *)ptr);
// %s:字符串
char str[] = "Hello, World!";
printf("String: %s\n", str);
// %u:无符号整数
unsigned int unsigned_num = 4294967295;
printf("Unsigned integer: %u\n", unsigned_num);
// %x:十六进制整数
int hex_num = 255;
printf("Hex integer (lowercase): %x\n", hex_num);
// %zd:size_t 类型
size_t size = sizeof(int);
printf("Size of int: %zd\n", size);
// %%:输出一个百分号
printf("Percent sign: %%\n");
return 0;
}
printf
等函数中的占位符一起使用,用来控制输出的格式,以下是一些常见的格式化输出修饰符及其使用方法。一、宽度修饰符
[数字]
:指定输出的最小宽度。
int num = 123;
printf("%5d", num);
这里的 5
是宽度修饰符,会输出 123
,因为 num
的实际长度是 3 位,使用 5
作为宽度修饰符会在左边填充 2 个空格,使输出总宽度为 5 位。
对于浮点数:
float f_num = 3.14;
printf("%8.2f", f_num);
这里 8
是总宽度,会输出 3.14
,其中 .2
表示保留 2 位小数,总宽度为 8 位,包括数字、小数点和空格,在左边填充 4 个空格。
对于字符串:
char str[] = "hello";
printf("%10s", str);
输出 hello
,在左边填充 5 个空格,使总宽度为 10 位。
二、精度修饰符
‘.’[数字]
:对于不同类型的数据,精度修饰符有不同的含义。
对于浮点数:
float f_num = 3.14159;
printf("%.2f", f_num);
这里 .2
表示保留 2 位小数,会输出 3.14
。如果和宽度修饰符一起使用:
printf("%8.2f", f_num);
会输出 3.14
,先保证总宽度为 8 位,同时保留 2 位小数。
对于字符串:
char str[] = "hello world";
printf("%.5s", str);
这里 .5
表示只输出字符串的前 5 个字符,会输出 hello
。
三、标志修饰符
‘-
’:左对齐输出。对于整数:
int num = 123;
printf("%-5d", num);
会输出 123
,与上面的 %5d
相反,是在右边填充 2 个空格,实现左对齐。
对于浮点数:
float f_num = 3.14;
printf("%-8.2f", f_num);
会输出 3.14
,保留 2 位小数,总宽度为 8 位,在右边填充 4 个空格,实现左对齐。
对于字符串:
char str[] = "hello";
printf("%-10s", str);
会输出 hello
,在右边填充 5 个空格,实现左对齐。
四、零填充修饰符
‘0’
:使用零而不是空格进行填充。
对于整数:
int num = 123;
printf("%05d", num);
会输出 00123
,在左边填充 2 个零,总宽度为 5 位。
对于浮点数:
float f_num = 3.14;
printf("%08.2f", f_num);
会输出 003.1400
,总宽度为 8 位,保留 2 位小数,左边填充 2 个零。
五、符号显示修饰符
‘+
’:对于正数显示 +
号。对于整数:
int num = 123;
printf("%+d", num);
会输出 +123
,显示正号。对于负数,无论是否使用 +
修饰符,都会显示负号。
对于浮点数:
float f_num = 3.14;
printf("%+f", f_num);
会输出 +3.140000
,显示正号。
六、空格显示修饰符
(空格):正数前显示一个空格。
int num = 123;
printf("% d", num);
会输出 123
,正数前面会有一个空格,对于负数,会正常显示负号。
对于浮点数:
float f_num = 3.14;
printf("% f", f_num);
会输出 3.140000
,正数前面有一个空格。
七、哈希修饰符
‘#
’:int oct_num = 10;
printf("%#o", oct_num);
会输出 012
,会在八进制数前面加 0
前缀。正常使用 %o
输出时,会输出 12
。
int hex_num = 10;
printf("%#x", hex_num);
会输出 0xa
,会在十六进制数前面加 0x
前缀。使用 %x
输出时,会输出 a
。
对于浮点数:
float f_num = 3.0;
printf("%#g", f_num);
对于 %g
或 %G
,会强制显示小数点,输出 3.00000
。对于 %f
会输出 3.000000
,效果和不使用 #
相同。
八.动态宽度和精度修饰符(使用 *
)
printf
中使用 *
来表示宽度或精度是由一个参数提供的,而不是在格式字符串中直接给出。int width = 8;
int num = 123;
printf("%*d", width, num);
这里 width
作为 *
的参数,将 num
以 8 位宽度输出,输出为 123
,即左边填充 5 个空格。
用于精度:
int precision = 2;
float f_num = 3.14159;
printf("%.*f", precision, f_num);
这里 precision
作为 *
的参数,将 f_num
保留 2 位小数输出,输出为 3.14
。
结合前面使用的示例
以下是一个结合多个修饰符的复杂示例:
long long int large_num = 12345678901234567890LL;
int width = 20;
int precision = 5;
printf("%+#0*.*llx", width, precision, large_num);
+
表示正数要显示 +
号。#
表示对于十六进制数要显示 0x
前缀。0
表示使用零填充。*
表示宽度由 width
变量指定。.*
表示精度由 precision
变量指定。一、输出功能:
%d
:通常被认为是用于输出十进制整数的标准占位符。
int num = 10;
printf("The number using %d is: %d", num, num);
%d
来输出 num
的值,它会将 num
作为十进制整数显示,输出为 The number using %d is: 10
。%i
:
printf
函数中 %i
通常和 %d
一样,仅输出十进制整数,但是当与 scanf
函数结合使用时,%i
可以根据输入数字的前缀来识别不同的进制。int num;
scanf("%i", &num);
如果用户输入 010
,num
将被存储为八进制数对应的十进制值,即 8;如果输入 0x10
,num
将被存储为十六进制数对应的十进制值,即 16;如果输入 10
,则会将其存储为十进制数 10。
二、输入功能
%d
:当使用 scanf
函数时,%d
只会将输入解释为十进制整数。
int num;
scanf("%d", &num);
10
、010
还是 0x10
,它都会将输入视为十进制数,尝试将其存储为十进制整数。如果输入 010
,num
会存储为十进制数 10,而不是八进制数对应的十进制值 8;输入 0x10
会导致存储错误或未预期的结果,因为 %d
不识别十六进制前缀。%i
:
scanf
中,%i
可以根据输入的前缀自动识别进制。int num;
scanf("%i", &num);
010
时,num
将存储为八进制数 010 的十进制等效值,即 8。0x10
时,num
将存储为十六进制数 0x10 的十进制等效值,即 16。10
时,num
将存储为十进制数 10。printf
函数,%d
和 %i
的使用几乎没有区别,都能正确输出有符号的十进制整数;但对于 scanf
函数,%i
更灵活,可根据输入数字的前缀识别进制,而 %d
仅将输入解释为十进制整数。在日常编程中,对于 printf
函数,可根据个人习惯使用 %d
或 %i
输出十进制整数;对于 scanf
函数,如果需要自动识别输入数字的进制,应使用 %i
,否则使用 %d
明确表示仅接受十进制输入。如下:
#include
int main()
{
char name[15];
scanf("%14s", name);
return 0;
#include
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d-%d-%d", &year, &month, &day);
printf("%d %d %d\n", year, month, day);
return 0;
}
#include
int main()
{
int year = 0;
int month = 0;
int day = 0;
scanf("%d%*c%d%*c%d", &year, &month, &day);
return 0;
}
printf
和 scanf
函数中,%[]
是一种比较特殊的格式化字符串,主要用于输入或输出一系列字符。以下是关于它的一些使用情况:一、在 scanf
中的使用:
%[]
可以用来读取一个字符集合。
char str[100];
scanf("%[abc]", str);
scanf
调用会读取输入的字符,只要输入的字符是 a
、b
或 c
中的任何一个,就会存储到 str
中,直到遇到不在该集合中的字符为止。例如,如果输入是 abcaa
,那么 str
将存储 abcaa
。如果输入是 abcdef
,str
只会存储 abc
,因为 d
不在 abc
集合中。char str[100];
scanf("%[a-z]", str);
str
中,直到遇到不在 a-z
范围的字符。例如,如果输入是 abcdefg123
,str
将存储 abcdefg
。char str[100];
scanf("%[^a-z]", str);
^
表示取反,%[^a-z]
会读取所有不是小写字母的字符,存储到 str
中。如果输入是 123abc
,str
将存储 123
。二、在 printf
中的使用(较少使用):
在 printf
中使用 %[]
不太常见,但可以通过自定义函数和 %s
占位符结合使用,来实现对字符集合的格式化输出。
#include
#include
void print_custom(const char *str) {
int len = strlen(str);
for (int i = 0; i < len; i++) {
if (str[i] >= 'a' && str[i] <= 'z') {
putchar(str[i]);
}
}
}
int main() {
char str[] = "Hello123World";
printf("Lowercase letters: ");
print_custom(str);
return 0;
}
在这个例子中,print_custom
函数只打印输入字符串中的小写字母。如果想在 printf
中使用 %[]
类似的功能,可能需要自定义这样的函数,因为 printf
本身不直接支持 %[]
进行输出筛选。
三、注意事项:
scanf
中的 %[]
注意事项:
%[^\n]
并结合 fgets
来控制输入长度。例如: char str[100];
fgets(str, sizeof(str), stdin);
str
中,最多存储 99 个字符,最后一个留给 \0
终止符。scanf
函数在使用 %[]
时不会自动在输入字符串末尾添加 \0
终止符,除非输入结束或者遇到不符合集合的字符。因此,确保存储数组有足够的空间,并手动添加终止符(如果需要)。四、高级用法:
结合 *
进行抑制赋值:
char str[100];
int num;
scanf("%*d %[a-z]", str);
scanf
调用会跳过一个整数(%*d
会读取一个整数,但不会存储它),然后将接下来输入的小写字母存储到 str
中。%[]
提供了一种方便的方式来控制字符的输入和输出,尤其在需要筛选特定字符集合时非常有用,但使用时要注意可能出现的缓冲区溢出问题和终止符的添加,以确保程序的安全性和正确性。