4

在这种情况下我们需要演员吗?:

#include <stdio.h>
#include <stdint.h>

int main(){

  // Say we're working with 32-bit variables.
  uint32_t a = 123456789;
  uint32_t b = 5123412;
  uint32_t c = 123049811;

  // We want to use 64-bit arithmetic at some intermediate stage, 
  // e.g. the a*b product here. After dividing by 'c', the result
  // again fits into a 32-bit unsigned, 'result'.
  uint32_t result = (uint64_t)a*b/c;

  // QUESTION HERE: Should we cast before the assignment? I.e.:
  //uint32_t result = (uint32_t)( (uint64_t)a*b/c );

  // Either way the result turns out OK on my system.
  printf("%u\n", (unsigned)result);

}
4

3 回答 3

2

对于任何赋值a = b;, 的值都b将转换为 的 类型的值a,前提是这是可能的,并且转换后的值被赋值给a。所以你建议的最外层演员是多余的。

但是,并非所有此类转换都是可能的,并且可以使用强制转换来强制转换,或在不存在直接转换的情况下创建合法转换链,如下一个示例所示:

foo x;

bar * y = (void *)&x;

foo *从to没有隐式转换bar *,但是从任何对象指针类型到和从隐式转换都存在void *(尽管未指定是否y具有可用或有用的值)。

显式强制转换的另一个用途是当它改变一个值的含义时——一个典型的例子是当您想将 I/O 的一个字节视为一个无符号值时。由于char可以是有符号或无符号的,因此将 achar直接转换为 anunsigned int可能会给出错误的答案。例如,我们想要-1值 255,而不是 -1。所以你需要:

char b = get_input();

unsigned int value = (unsigned char)b;

charto的转换unsigned char总是产生“预期的”无符号字节值,然后将其转换为无符号整数就可以了。

于 2013-10-27T20:46:27.830 回答
1
// QUESTION HERE: Should we cast before the assignment? I.e.:
//uint32_t result = (uint32_t)( (uint64_t)a*b/c );

这里不需要演员表。

将一个算术类型的值分配给不同算术类型的对象时,C 从不需要强制转换。所有算术类型之间都存在隐式转换。

现在请注意,某些编译器可能会发出警告。例如,如果右操作数是一个常量表达式并且它不能以左操作数的类型表示,则会 gcc发出警告。

于 2013-10-27T20:47:25.573 回答
0

6.3 转换:

几个运算符会自动将操作数值从一种类型转换为另一种类型。该子条款指定了这种隐式转换所需的结果,以及强制转换操作(显式转换)产生的结果。

6.5.16.1 简单赋值:

在简单赋值 (=) 中,右操作数的值被转换为赋值表达式的类型,并替换存储在左操作数指定的对象中的值。

于 2013-10-27T21:15:06.010 回答