在printf()等可变函数中,整数提升可以以相反的顺序(例如,long int到int)发生吗?

时间:2017-07-07 10:55:56

标签: c

#include<stdio.h>
int main() {
    long a = 9;
    printf("a = %d",a);//output is 9 but with a warning 'expecting long int'
}

为什么这里不能长时间转换成int?

3 个答案:

答案 0 :(得分:2)

一般的变量函数和特别是printf族,都是奇怪的特殊情况。它们因其不存在的类型安全性而臭名昭着,因此如果传递错误的类型或使用错误的格式字符串,则会调用未定义的行为,并且可能发生任何事情。

在您的情况下,很可能intlong碰巧具有相同的表示形式,因此尽管有警告,程序仍然有效。

在常规功能的情况下,有一种降级&#34;如果将较大的整数类型传递给期望较小的整数类型的函数,则会发生这种情况。发生这种情况时,您会触发从较大类型到较小类型的转换,这是明确定义的。 (但是,如果混合使用不同签名的类型,结果将是编译器特定的。)

编译器倾向于警告这种隐式转换,因此最好使用强制转换显式进行转换。

答案 1 :(得分:1)

因为这是可变函数在C语言中的行为方式。 printf只是标准库中的一个函数,没有特殊处理。它被声明为

int printf(const char restrict *fmt, ...);

标准(C99的n1256草案)说(强调我的):

  

6.5.2.2函数调用
...

  6如果表示被调用函数的表达式具有不包含a的类型   原型,整数促销对每个参数执行,参数为   将 float类型提升为double 。这些被称为默认参数   促销 ...
  7 ...函数原型声明符中的省略号表示法   参数类型转换在最后声明的参数后停止。 默认参数   促销是在尾随参数上执行的

这意味着在printf的所有参数上,float都会转换为double,整数提升会出现整数提升。

在6.3.1.1算术操作数/布尔,字符和整数

  

2无论int还是unsigned int都可以在表达式中使用以下内容   使用:
   - 具有整数类型的对象或表达式,其整数转换等级较小   大于或等于int和unsigned int的等级    - _Bool,int,signed int或unsigned int类型的位字段   如果int可以表示原始类型的所有值,则该值将转换为int;   否则,它将转换为unsigned int。这些被称为整数   促销.48)整数促销活动保持所有其他类型不变。

因为long的排名大于int,所以整数提升保持不变,格式应适合接受长:

long a = 9;
printf("a = %ld",a);

答案 2 :(得分:1)

以下传递long,但printf()期望由int引起"%d"。结果:未定义的行为(UB)。如果intlong的大小相同,那么UB可能看起来一切正常,或者可能会失败。这是UB。

long a = 9;
printf("a = %d",a);  // UB
  

为什么不能在这里长时间转换为int?

long可以转换,但代码没有像下面的代码那样指示。

printf("a = %d", (int) a);  // OK
  

整数提升可以以相反的顺序发生...在varivadic函数中如printf()?

整数促销不会以相反的顺序发生,除非代码明确地向下转换或分配给更窄的类型。

有些情况下降级将出现printf()一致 以下内容将sc提升为int,因为它已传递给printf()printf()int "%hhd"signed char会将其转换为signed char sc = 1; printf("a = %hhd", cs); // prints 1 ,然后打印该数值。

i

以下将printf()传递给int作为printf()int"%hhd" signed chari会将其转换为int i = 0x101; printf("a = %hhd", i); // prints 1 ,然后打印该数值。所以在这种情况下,看起来就像with open("state_abbreviations.csv", "r") as f: # you can use csv.DictReader() instead but lets strive for performance reader = csv.reader(f) next(reader) # skip the header # assuming the first column holds the abbreviation, second the full state name state_map = {state[0]: state[1] for state in reader} 被降级了一样。

state_map