【问题标题】:Confused about K&R c explanation on type conversions对类型转换的 K&R c 解释感到困惑
【发布时间】:2014-08-11 01:53:32
【问题描述】:

这本书在第 45 页说了以下内容:

由于函数调用的参数是表达式,因此在将参数传递给函数时也会发生类型转换。在没有函数原型的情况下,charshort 变为 intfloat 变为 double。这就是我们将函数参数声明为 intdouble 的原因,即使使用 charfloat 调用函数也是如此。

我不明白最后一句话在说什么。有人能引导我走向正确的方向吗?

【问题讨论】:

  • 这不再适用,因为函数原型是强制性的,对吧?
  • @FiddlingBits 原型在 C 中不是强制性的
  • 你能把那个例子放在现场吗
  • 声明是强制性的,但声明不必是原型。
  • 这条评论真的只适用于历史。忽略它不会丢失任何东西。

标签: c


【解决方案1】:

我们可以在这里看到这种情况。根据cplusplus.com,这是printf()的声明:

int printf(const char * format, ...);

... 意味着这个函数可以接受未知数量的未指定类型的参数,并且由于它是未指定的,所以将数字类型标准化为 intdouble 会发生在除第一个之外的所有 printf() 参数上,这是指定的。

例子:

char x = 10;
short y = 100;
int z = 1000;
printf("Values of char is %d, short is %d, and int is %d", x, y, z);

当传递给printf() 时,所有这些整数类型都会自动重铸为int。我们可以看到%d 对所有这些都有效。

请注意,大于doubleint 的类型不会被转换,例如long intlong doublelong long 等。这些类型是64 位的。

【讨论】:

  • z 未转换!
  • 否; z 未转换,因为它是 long,它不是比 int 短的类型。仅短于int 的类型(char 的三种风格和short 的两种风格转换为int;只有float 转换为doublelonglong double 均未转换。 (并且int z; 也不会转换为int,因为它已经是int,但这不会改变值。)
  • 通常longint 大小相同,但我明白你的意思。 64 位变量仍然作为 64 位传递。
  • 只有在 Windows 或 32 位平台上编程时,longint 大小相同。这些天来,我很少为任何一个编程。在 32 位和 64 位平台之间迁移时,传递给 printf() 并在格式字符串中指定的类型的草率会导致很多痛苦。
  • 您不能假设 long 和 int 的大小相同。我不知道你从哪里得到这个想法
【解决方案2】:

当您在 C 中为函数使用原型时(ansi C,因为原始 K&R 规范没有以这种方式定义参数)您将形式参数声明为具有类型。当您在实际表达式中匹配它时,可能会发生两件事:

  1. 形式参数和实际表达式是同一类型。在这种情况下,一切都很好,表达式值用于在调用函数之前初始化参数。
  2. 形式参数和实际表达式不是同一类型。在这种情况下,如果可能,编译器会尝试将实际表达式的类型自动转换为形参类型。

如果没有找到原型,则上面的规则强制执行,因此 chars 和 shorts 被提升为 int 值,所有浮点类型值被提升为 double。

引用段落中的最后一句话告诉您,在某些示例(未显示)中,类型被用于形式参数以确保实际表达式被转换为形式参数的类型。

【讨论】:

  • 在第二种情况下,没有找到原型:这是否意味着参数在函数调用时被重新转换为形式参数类型,或者它们只是被重新解释(即类型双关),这可能是错的?示例:假设您有函数int foo(double),但您没有在调用foo(123ull) 的翻译单元中声明此函数(ANSI C 允许这样做)。这是否意味着123ull 的位表示将简单地在函数体中被重新解释为double,或者当foo 被调用时会转换为double
  • 不,当没有找到原型时,您通常会收到有关某些未定义函数在没有声明的情况下被使用的警告,并且数据只是通过引用的转换传递给函数。这是旧的 C 方法,并且被维护以便遗留代码仍然可以编译。正如 K&R 在您的引用中所说,charshort 被转换为 intfloat 被转换为 double(但这并不总是这样,您引用的是第 2 版 K&R)
猜你喜欢
  • 2011-02-02
  • 1970-01-01
  • 2016-10-10
  • 2010-10-14
  • 2021-11-28
  • 1970-01-01
  • 1970-01-01
  • 2013-01-13
  • 1970-01-01
相关资源
最近更新 更多