英文:
the reason why type char can be converted in specifier %d?
问题
我突然注意到,尽管%d只接受int类型,但我在char类型上使用了转换说明符%d。
这怎么可能?
根据C标准,转换说明符%d对应于int类型的参数。而且,如果任何参数不是相应转换规范的正确类型,行为是未定义的。
但是,无论我如何编译上述代码,我总是得到预期的输出。
我不应该总是期望这个输出吗?
或者,当传递给函数的参数时,char类型会扩展为int类型吗?所以它可以是65,我可以使用类型char的转换说明符%d吗?
英文:
I suddenly noticed that i've used conversion specifier %d with type char although %d takes only type int.
How is it possible?
According to c standard, conversion specifier %d is corresponding to type int argument.
And if any argument is not the correct type for the corresponding conversion specification,
the behavior is undefined.
#include <stdio.h>
int main(void){
char a= 'A'; // 'A' = 65 in ASCII
printf("%c\n", a);
printf("%d\n", a);
return 0;
}
----- output -----
A
65
But whenever i compile the code like above , i always get output as intended.
Shouldn't i expect this output always?
Or, IS type char expanded to type int when passed to function's argument? So it can be 65 and i can use specifier %d
with type char?
答案1
得分: 1
C 2018 6.5.2.2 7说:
如果表示被调用函数的表达式(printf
就是这个表达式)具有包含原型的类型(它有),则参数会被隐式转换,就像通过赋值一样,转换为相应参数的类型,将每个参数的类型视为其声明类型的未限定版本。函数原型声明符中的省略号表示在最后一个声明的参数之后停止参数类型转换。默认参数提升会对尾部参数执行。
printf
被声明为int printf(const char * restrict format, ...);
,所以在printf("%d\n", a);
中,"%d"
参数对应于format
参数,而a
对应于...
,使其成为尾部参数的一部分。因此,对其执行默认参数提升。这些在6.5.2.2 6中指定:
整数提升在6.3.1.1 2中指定:
如果int
可以表示原始类型的所有值(对于位字段受限制的宽度),则将值转换为int
;否则,将其转换为unsigned int
。这些被称为整数提升...
因此,您的char
参数a
会自动转换为int
,因此它是%d
的正确类型。
英文:
C 2018 6.5.2.2 7 says:
> … If the expression that denotes the called function [printf
is that expression] has a type that does include a prototype [it does], the arguments are implicitly converted, as if by assignment, to the types of the corresponding parameters, taking the type of each parameter to be the unqualified version of its declared type. The ellipsis notation in a function prototype declarator causes argument type conversion to stop after the last declared parameter. The default argument promotions are performed on trailing arguments.
printf
is declared <code>int printf(const char * restrict <i>format</i>, ...);</code>, so, in printf("%d\n", a);
, the "%d"
argument corresponds to the <code><i>format</i></code> parameter, and the a
corresponds to the ...
, making it part of the trailing arguments. So the default argument promotions are performed on it. These are specified in 6.5.2.2 6:
> … the integer promotions are performed on each argument, and arguments that have type float
are promoted to double
. These are called the default argument promotions.
The integer promotions are specified in 6.3.1.1 2:
> … If an int
can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int
; otherwise, it is converted to an unsigned int
. These are called the integer promotions…
Thus your char
argument a
is automatically converted to an int
, so it is the correct type for %d
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论