printf中的转换类型(无强制转换运算符)

问题描述 投票:0回答:1

我正在尝试运行以下代码来演示转换的工作原理。

#include <stdio.h>
int main()
{
    int x=5;
    int y=2;
    float z;
    printf("x=%d\n", x);
    printf("y=%d\n", y);

    //Doing division as it is
    z= x/y;
    printf("With no preliminar assignment: (z=x/y)\n");
    printf("\"z\" is: %d (integer)  or %lf (double) or %f(float)\n\n\n", z, z, z);

    //Doing assignment before division
    printf("With the assignment: (z=x)\n");
    z=x;
    printf("\"z\" before division is:");
    printf("%d (integer)  or %lf (double) or %f(float)\n", z, z, z);

    //Doing division after assignment
    z/=y;
    printf("\"z\" after division with assignment: (z=z/y)");
    printf(" is: %d (integer)  or %lf (double) or %f(float)\n", z, z, z);

    return 0;
}

输出是:

x=5
y=2
With no preliminar assignment: (z=x/y)
"z" is: 0 (integer)  or 0.000000 (double) or 0.000000(float)


With the assignment: (z=x)
"z" before division is:0 (integer)  or 0.000000 (double) or 0.000000(float)
"z" after division with assignment: (z=z/y) is: 0 (integer)  or 0.000000 (double) or 0.000000(float)

这使我感到怀疑,也是因为我的大学教授编写了以下代码:

int x=5;
int y=2;
float z;

int main (void) {
    z = x / y;
    return 0;
}

对他来说,z将假定为2.0(在逻辑上是正确的,但在printf中不是)。

所以,我的最后一个问题是,为什么在所有printf中结果都是0?(我不想使用类型转换运算符)

c casting type-conversion printf
1个回答
0
投票

printf(),与许多可变函数一样,使用格式字符串告诉函数调用堆栈上期望使用哪种类型的参数,但这并不意味着根据格式对此类参数进行了任何转换字符串

无论如何,任何体面的编译器都会警告您有关格式/参数类型不匹配的信息,这意味着您故意忽略了它们。。

可能是您在参数提升和格式说明符之间造成了混淆。

在可变自变量函数中,未明确定义的参数(由...标识的参数以标准方式处理,如C标准ISO / IEC 9899:201x,第6.5.2.2节函数调用中所述)。在第[[6项中,我们读为:

如果表示被调用函数的表达式的类型为不包括原型,整数提升在每个参数以及类型为float的参数都被提升为double

这些被称为默认参数提升

如果参数数量不等于参数数量,行为是不确定的。如果函数的类型定义为包括一个原型,或者该原型以省略号结尾(,...)或提升后的参数类型不是与参数类型兼容,其行为是未定义。如果函数的类型不是包括原型,以及升级后的参数类型与升级后的参数不兼容,行为是不确定的,以下情况除外:

  • 已晋升type是带符号的整数类型,另一个提升的类型是对应的无符号整数类型,并且该值可表示为两种类型;
  • 两种类型都是指向字符类型或void的合格或不合格>版本的指针。

因此,如果要获得有意义的输出,请

必须明确转换参数

,如下所示:printf(" is: %d (integer) or %lf (double) or %f(float)\n", (int)z, z, z);
请注意,仅强制转换为int,将其他2个条目保留为默认升级,这会将float转换为double,以满足该函数基于格式字符串的期望。

代码中的值全为零的问题是由于参数大小int / double的不匹配而导致堆栈无法包装。

© www.soinside.com 2019 - 2024. All rights reserved.