繁体   English   中英

在 C 中通过重新引用传递的强制转换函数参数

[英]Cast function argument passed by rereference in C

我有以下功能。 它适用于short

void foo (short n, short * res)
{
  *res = n*2;
}

我想将结果存储在double变量中。 例如:

short in = 5;
double out = 0;
foo(in,&out);

但这样的结果是一些垃圾。 有没有办法在这种情况下强制转换这些类型,或者唯一的解决方案是使用一些类型为short临时变量?

如果你不能改变功能,那么我会做这样的事情:

short in = 5;
short tmp;
double out;
foo(in,&tmp);
out = tmp;

如果您经常这样做,请考虑像@einpoklum 在他的回答中所做的那样编写一个包装器,如下所示:

void foo_wrapper(short n, double *out)
{
    short tmp;
    foo(n, &tmp);
    out = tmp;
}

我想理论上可以通过铸造实现,但我建议反对它。 做错的风险很高,你可能会遇到难以追赶的错误,如果你进行显式转换,编译器不会给你警告。 我在这个答案中写了一篇关于演员的咆哮

在这种特殊情况下,请注意函数foo不知道结果类型。 所以你需要一个临时变量。 您可以通过使用out变量来摆脱它,因为它是带有一些强制转换的临时变量,但我强烈建议不要使用它!

short in = 5;
double out;
foo(in, (short*)&out);
out = *(short*)&out; // Evil! Avoid code like this!
printf("%f\n", out);

这适用于我的机器,但它确实违反了@chqrlie 在评论中所写的别名规则。 不要这样做!

@chqrlie 还编写了一种替代方法,没有额外的变量,也没有邪恶的铸造。 它有效,但是啊! 也不要这样做:

short in = 5; 
foo(in, &in); // No! Just don't!
out = in;     

当然,如果您需要原始值,它就行不通,但这很明显。 这里的主要缺陷是它很糟糕。 不要为了不同的目的重用变量只是为了摆脱临时变量。

除了@klutt 的有效答案之外,请记住,如果您多次这样做,将整个内容包装在一个函数中通常是个好主意:

int foo_d (short n, double * result)
{
  short result_inner;
  int retval = foo(n, &result_inner);
  *result = (double) result_inner;
    // Note to @Ans-lte: The explicit cast here isn't necessary,
    // the conversion will happen anyway.
  return retval;
}

使用强制转换是一个坏主意。

对于初学者来说,不清楚为什么要使用浮点类型而不是整数类型,例如intlong int

如果声明

*res = n*2;

可以为类型为short的对象产生溢出,那么您应该像这样重写函数

void foo (short n, int * res)
{
  *res = n * 2;
}

请注意,表达式n * 2的结果在您的原始函数中已经具有int类型。

如果问题与溢出无关,那么为什么不直接写

short res;

foo( n, &res );

double d = res;

或者你再次需要重写函数

void foo (short n, double * res)
{
  *res = n * 2.0;
}

但无论如何不要使用任何铸造。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM