就编译器类型检查和自动转换而言,printf的转换说明符是否与函数声明等效?
我正在尝试了解C基本数据类型自动类型转换,促销等,并想知道我是否可以使用printf而不是虚函数来检查会发生什么。
通过一个例子让我的问题更清楚,
void f1 (int a){}
int main() { f1('c'); return 0; }
帮助我理解如果我使用int参数声明一个函数但在调用中传递char类型会发生什么。
我想知道我是否可以致电
printf("%i", 'c');
出于上述目的。
此外,如果有人可以在C中指出某些关于类型表示/转换/促销的权威资源(在网络或书籍上),我将不胜感激。
答案 0 :(得分:3)
没有
许多编译器不对格式字符串进行任何类型检查。当使用-Wformat
时,gcc会这样做,但这些检查与分配时的检查是分开的。
printf
的参数按原样传递。唯一的转换可能是将其增加到处理器字大小(这是char
变为int
的方式)并且它不以任何方式依赖于格式字符串。请参阅Jonathan Leflfer的评论,该评论更准确地解释了这一点。
答案 1 :(得分:2)
printf("%i", 'c');
你将获得字符'c'的ASCII值,即99.有两种方法可以将char设置为int。
如果你只想要char的ASCII值,只需使用整数说明符打印char
。
如果要将char
转换为整数(如'0'为0或'1'为1),则需要执行以下操作
char a = '4';
int ia = a - '0'; //subtraction of '0'
为了更加清晰,只需增加一点,printf中的说明符说从堆栈弹出多少。如果是%d
,则弹出4 bytes
(假设为4字节的int),如果它是%c
,则弹出1 byte
等。
答案 2 :(得分:2)
printf的转换说明符是否等同于函数声明 编译器类型检查和自动转换是什么?
没有。将char
传递给可变参数函数时,您传递的值将被提升为int
。这与您使用的转换说明符无关。 C11 standard在§6.5.2.2p7中描述了这一点:
函数原型声明符中的省略号表示法导致 参数类型转换在最后声明的参数后停止。 默认参数提升是在尾随参数上执行的。
默认参数促销在§6.5.2.2p6中定义为整数促销的超集:
...对每个参数执行整数提升,并且 类型为
float
的参数将提升为double
。这些是 称为默认参数促销。
...整数促销在§6.3.1.1p2中定义:
如果
int
可以表示原始类型的所有值(限制为 通过宽度,对于一个位域,该值被转换为int
; 否则,它将转换为unsigned int
。这些被称为 整数促销。
通过一个例子让我的问题更清楚,
void f1(int a){}
int main(){f1('c');返回0; }
帮助我理解如果我用一个函数声明一个函数会发生什么 int参数但在调用中传递char类型。
不,它没有。 'c'
实际上是int
。如果你不相信我,请亲自看看:
#include <stdio.h>
#ifdef __cplusplus
#error "Don't compile C code with a C++ compiler."
#endif
int main(void) {
printf("sizeof 'c': %zu\n", sizeof 'c');
}
答案 3 :(得分:1)
当您将'c'作为参数传递给函数 f1 时,字母的ASCII值 c (99)< / strong>将存储到 a 。如果您修改下面的 f1 功能
void f1 (int a){
printf("\n %d",a); // prints the ascii value of charecter c
printf("\n %c",a); //prints the o/p as c
printf("\n %i",a); //prints the ascii value of charecter c again
}
O/p for the program
99
c
99
你问了
I want to know if I can just call printf("%i", 'c');
是的,您可以不需要执行 f1 功能。