【问题标题】:How to output a float product of int multipliers?如何输出整数乘法器的浮点乘积?
【发布时间】:2011-05-09 04:50:59
【问题描述】:

我正在尝试计算一个数字的指数。当我以 int 执行所有操作时,我得到正确的结果,但输出必须是浮点数,当我尝试在 printf() 中使用 %f 进行转换时,我得到 0,当我使用 %d 时,我得到正确的结果。我无法更改程序的 main() 部分,我只能更改 *powerArgs() 函数。程序输入为3、5。

完全公开,这是学校作业的一部分。我不是要完整的代码。我将不胜感激一个更一般的答案,告诉我我忘记了什么,可能我应该更多地研究哪些领域来自己找到答案。

#include <stdio.h>
#include <stdlib.h>

int *powerArgs(int *pA, int *pB);

/* MAIN */
int main(int argc, char **argv)
{

    if (argc != 3)
    {
       printf("?Invalid number of arguments\n");
       system("pause");
       exit(1);
    }

    int parmA = atoi(argv[1]);
    int parmB = atoi(argv[2]);
    int idx;

/* Part C: Raise parmA to the power of parmB.  Return pointer to the result */    
/*         Reset the original values after we print the result */
    printf("%d raised to the %d power is %0.1f\n", parmA, parmB, *powerArgs(&parmA, &parmB));

    printf("\n");  

    system("pause");
    exit(0);
}

int *powerArgs(int *pA, int *pB)
{
      int idx, result = *pA;

      for (idx = 1; idx < *pB; idx++)
      {
          result *= *pA;
      }

      return &result;
}      

【问题讨论】:

  • 不,不,不。您不能将 指针powerArgs 返回到 resultresult 是该函数中的 局部变量。一旦函数退出,它就不存在了。您必须返回一个 int(或 float)value.
  • 我实际上有不同的评论:即使在作业中,也不要命名任何 parmA、parmB 或其变体。相反,将变量命名为基数和指数。以后阅读您的代码的人(包括您在内)会发现,如果他们不必继续查看 parmA 是基数还是指数,并看到您在某些时候没有交换它们,那么阅读起来会容易得多。
  • 我没有用 parmA 和 parmB 写部分。 main()部分是老师给的,我们必须编写被调用的函数来返回预期的结果输出如show。这就是为什么我不能只输出为 int。但我很欣赏这一点,我通常有更具描述性的变量名称,例如 interation、base、product。
  • 当今编程设计中最大的问题之一是糟糕的接口。这是一个伟大的例子。绝对没有理由(不,甚至没有性能)将引用或指针作为输入,更糟糕的是,返回一个指针。它所做的只是使代码比它需要的更复杂。错误隐藏在复杂性中。
  • @mcabral: "The homework tag...is now discouraged," 但是,@cyotee,请(一如既往)遵循general guidelines:说明任何特殊限制,展示您迄今为止尝试过的内容,并询问具体是什么令人困惑你。 (你在这里做得很好。)

标签: c type-conversion printf


【解决方案1】:

首先,您的int *powerArgs(int *pA, int *pB) 函数返回一个局部变量的地址,这会导致未定义的行为。请改用以下内容:

int powerArgs(int *pA, int *pB)
{
  int idx, result = *pA;

  for (idx = 1; idx < *pB; idx++)
  {
      result *= *pA;
  }

  return result;
}

接下来,如果你想转换为float,你不应该在调用printf()时这样做,而是将值转换为float在调用之前像这样:

printf("%d raised to the %d power is %0.1f\n", parmA, parmB, (float)powerArgs(&parmA, &parmB));

【讨论】:

  • ITYM (float) powerArgs(&amp;parmA, &amp;parmB);
  • 感谢您的帮助。这确实澄清了我对如何正确执行此操作的理解。但是作业说我们不能编辑 main()。我们只能根据调用方式构建函数以产生所需的输出。我希望我可以重写以使其更明智,但我不能。
【解决方案2】:

floatint 在 C 中自动转换 - 您可以将其中一个分配给另一个,唯一需要注意的是,如果您将太大的浮点数分配给 int,那么您会得到未定义的行为(或者可能是未指定的结果,我忘记了。无论哪种方式都不好)。

所以,您的 powerArgs 函数可以是:

float powerArgs(float a, int b) {
    // do some stuff and return a value
}

然后您可以将其称为powerArgs(parmA, parmB),即使parmA 是一个int。

编辑:如果你不能改变调用参数,你可以这样做

float powerArgs(int *a, int *b) {
    float base = *a;
    int exponent = *b;
    ...
}

如果你的教授真的给你设置了函数调用*powerArgs(int *a, int *b)的代码,那么你的教授就是个威胁。求幂函数应该将一个指针返回到一个浮点数,这并没有什么世俗的理由。您可以使用一个丑陋的解决方法:

float *powerArgs(int *a, int *b) {
    static float result;
    ...
    result = /* the result of the calculation */;
    return &result;
}

问题在于,所有对powerArgs 的调用共享同一个对象resultstatic 阻止它在通话结束时停止存在,但从长远来看,共享会带来问题。这样做不是好习惯,但它可能是解决您遇到的问题的最佳方法。

C++ 偷偷摸摸的解决方案:

struct FloatWrapper {
    float value;
    float operator*() {
        return value;
    }
    FloatWrapper(float f) : value(f) {}
};

FloatWrapper powerArgs(int *a, int *b) {
    ...
    float result = /* whatever */;
    ...
    return result;
}

这会按值返回 FloatWrapper 类的对象,并且 FloatWrapper 会重载 * 运算符。这意味着*powerArgs(...) 的计算结果是函数应该首先按值返回的浮点数, 不需要指向任何特殊存储位置的指针。

顺便说一下,你可能想检查一下parmB 为 0 时你的函数做了什么。

【讨论】:

  • 非常感谢。我看到我在错误的时间处理了类型转换。您的示例显示了我可以成功处理它的不同方法。感谢您不只是建议我更改函数调用,因为我不能。
  • @cyotee:如果您有兴趣,我刚刚想到了一个 C++ 解决方案,它允许以*powerArgs 进行调用,没有任何共享数据,也不会泄漏内存。我会发布它,但如果你只学习 C,而不是 C++,请忽略它......
【解决方案3】:

当一个函数终止时,它的所有局部变量都不再存在(并且它们的地址指向垃圾)。为了取悦你的老师,他提出了那个非常尴尬的界面,你必须想办法在函数存在后让对象保持活动状态。

您至少有 3 个选项:
a) 重用其中一个输入参数
b) 使用全局变量
c) 使用静态变量

选项a)

int *powerArgs(int *pA, int *pB) {
    /* calculate */
    *pA = CALCULATED_VALUE;
    return pA;
}

选项 b)

int global_power;

int *powerArgs(int *pA, int *pB) {
    /* calculate */
    global_power = CALCULATED_VALUE;
    return &global_power;
}

选项 c)

int *powerArgs(int *pA, int *pB) {
    static int static_power;
    /* calculate */
    static_power = CALCULATED_VALUE;
    return &static_power;
}

这些“解决方案”都不好;最不坏的是选项 c)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-25
    • 1970-01-01
    • 2014-02-14
    • 2021-06-15
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多