C 使用长变量存储字符并打印它
我将C 使用长变量存储字符并打印它,c,printf,long-integer,type-mismatch,integer-promotion,C,Printf,Long Integer,Type Mismatch,Integer Promotion,我将char存储在long变量中,并尝试使用printf打印它 long a = 'A'; printf("%c \n",a); 考虑到默认参数升级,参数升级为int,但由于long的排名高于int,因此不应升级(或实际降级)为int 现在,如果它没有升级到int,在printf语句中,当我们试图使用%c打印long变量时,是否存在类型不匹配。根据C标准,这种行为应该是未定义的,但是编译器将A完美地打印为输出,没有任何错误或警告。为什么会这样 我正在使用GCC代码块编译器。将“A”的ASCII
char
存储在long
变量中,并尝试使用printf
打印它
long a = 'A';
printf("%c \n",a);
考虑到默认参数升级,参数升级为int
,但由于long
的排名高于int
,因此不应升级(或实际降级)为int
现在,如果它没有升级到int
,在printf语句中,当我们试图使用%c
打印long
变量时,是否存在类型不匹配。根据C标准,这种行为应该是未定义的,但是编译器将A
完美地打印为输出,没有任何错误或警告。为什么会这样
我正在使用GCC代码块编译器。将“A”的ASCII值转换为一个长数字并存储,printf函数将其转换回char(与%c相同),然后打印回“A” 实际上,“A”只是一个标准化定义的数字,所以应该没有问题
如果我错了,请纠正我。将“A”的ASCII值转换为一个长数字并存储,printf函数将其转换回char,就像%c一样,并打印回“A” 实际上,“A”只是一个标准化定义的数字,所以应该没有问题 如果我错了,请纠正我 根据C标准,这个行为应该是未定义的,但是编译器可以完美地打印一个输出,没有任何错误或警告。为什么会这样 未定义的行为表示未定义该行为。这意味着你不能期望它以某种方式表现。有些事情比其他事情更可能发生,但UB基本上意味着任何事情都可能发生 另外,您没有收到警告的原因是您没有激活警告
$ gcc -Wall main.c
main.c: In function ‘main’:
main.c:6:14: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
6 | printf("%c \n",a);
| ~^ ~
| | |
| int long int
| %ld
我建议使用-Wall-Wextra-pedantic-std=c11-Werror
请注意,警告指出格式“%c”需要类型为“int”的参数
,因此将int
传递给%c
是完全正确的。如果您传递一个char
,它将被提升为int
相关的:
促销:
未定义的行为:
根据C标准,这个行为应该是未定义的,但是编译器可以完美地打印一个输出,没有任何错误或警告。为什么会这样
未定义的行为表示未定义该行为。这意味着你不能期望它以某种方式表现。有些事情比其他事情更可能发生,但UB基本上意味着任何事情都可能发生
另外,您没有收到警告的原因是您没有激活警告
$ gcc -Wall main.c
main.c: In function ‘main’:
main.c:6:14: warning: format ‘%c’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=]
6 | printf("%c \n",a);
| ~^ ~
| | |
| int long int
| %ld
我建议使用-Wall-Wextra-pedantic-std=c11-Werror
请注意,警告指出格式“%c”需要类型为“int”的参数
,因此将int
传递给%c
是完全正确的。如果您传递一个char
,它将被提升为int
相关的:
促销:
未定义的行为:你对“未定义的行为”有什么期望?仅仅因为某些行为是未定义的,并不意味着它不起作用。常量
'A'
实际上是int
而不是C中的char
。当你将错误大小的螺钉塞进机器时,有时有效,有时无效。你对“未定义的行为”有什么期望?仅仅因为某些行为未定义并不意味着它不起作用。常量'A'
实际上是int
而不是C中的char
。当你将错误大小的螺钉塞进机器时,有时有效,有时无效。printf
不需要这样做,但无论如何,我认为它隐式地强制转换了。。C实际上并不关心数据类型,除非是数组和指针。。对吗?对于%c
,printf
尝试获取一个int
参数,然后它将该参数转换(或行为类似)为一个无符号字符
,并将其打印出来。但是当一个long
被传递时,printf
不希望得到它并将其转换。它在OP的尝试中的行为可能与执行该操作时的行为相同,但结果可能是不同的,并且说printf
将存储的long
转换为字符是不正确的。此外,C标准对字符值的规定非常宽松。@EricPostChil您的注释通常太好,不能仅作为注释。这个答案肯定对OP的帮助最大,因为它显示了实际发生的情况,而且似乎发生了什么。printf
不需要这样做,但无论如何,我认为它隐式地进行了转换。。C实际上并不关心数据类型,除非是数组和指针。。对吗?对于%c
,printf
尝试获取一个int
参数,然后它将该参数转换(或行为类似)为一个无符号字符
,并将其打印出来。但是当一个long
被传递时,printf
不希望得到它并将其转换。它在OP的尝试中的行为可能与执行该操作时的行为相同,但结果可能是不同的,并且说printf
将存储的long
转换为字符是不正确的。此外,C标准对字符值的规定非常宽松。@EricPostChil您的注释通常太好,不能仅作为注释。这个答案肯定对OP的帮助最大,因为它显示了实际发生的和似乎发生的情况。如果我尝试使用%c
打印int
变量而不是long int
,这是一个未定义的行为还是有效的?@Noshiii这是有效的。实际上,printf
中的%c
需要一个int
char
与int
兼容。如果我尝试