【问题标题】:Why do I need to typecast all of the values here?为什么我需要在这里对所有值进行类型转换?
【发布时间】:2017-09-28 15:27:38
【问题描述】:

我正在用 C 编写一个非常基本的程序(C 新手,所以只是掌握了一些东西)并且我正在努力使用 TypeCasting。

这是一个简单的计算程序,可让您输入两个数字并决定要对它们做什么(加、减、除和乘)。显然,并非所有数字都可以被所有其他数字整除,因此在我的除法部分的 switch 语句中,我试图将 int 类型转换为浮点数。

根据要求,我的变量声明在这里:

    int inputOne, inputTwo, calculatedValue = 0;
char calcType;
char restart = 'n';

我已经通过对所有值进行类型转换来实现它,但这是我之前尝试过的:

        case 'd': case 'D':
        calculatedValue = inputOne / inputTwo;
        printf("%s%d%s%d%s%1.2f", "The value of ", inputOne, " divided by ", inputTwo, " is equal to ", (float)calculatedValue);
        printf("\nPlease note: This is only accurate to two decimal places.");
        break;

这只会返回没有任何小数位的 4。然后我想可能是因为计算仍然是 int 的,所以我把它改成了这样:

        case 'd': case 'D':
        (float)calculatedValue = inputOne / inputTwo;
        printf("%s%d%s%d%s%1.2f", "The value of ", inputOne, " divided by ", inputTwo, " is equal to ", (float)calculatedValue);
        printf("\nPlease note: This is only accurate to two decimal places.");
        break;

但这只会返回 1082130432.00。不知道这个数字是从哪里来的。

我用这个解决了这个问题:

        case 'd': case 'D':
        printf("%s%d%s%d%s%1.2f", "The value of ", inputOne, " divided by ", inputTwo, " is equal to ", (float)calculatedValue = (float)inputOne / (float)inputTwo);
        printf("\nPlease note: This is only accurate to two decimal places.");
        break;

因为它在 switch 语句中,所以我可以通过使用浮点数而不是原始整数来解决问题,但是我已经完成了这段代码来尝试更好地理解类型转换,并且认为它可以在没有的情况下工作必须对所有内容进行类型转换。任何人都可以发光吗?我的讲师在 printf 中使用了类型转换,并且效果很好。在他的示例中,他试图找出学生的平均年龄,他这样做是这样的:

printf("\nAverage age: %1.2f", (cAge1 + cAge2 + cAge3) / (float)cNumStudents);

希望这是有道理的,对于一个简单的问题这么长感到抱歉,我只是想了解为什么我必须对所有内容进行类型转换(正如我的讲师所说,您只需要将其转换为一个值)。

干杯

编辑:

我刚刚尝试了以下,但它返回 0.00,而不是答案。

calculatedValue = (float)inputOne / inputTwo;
        printf("%s%d%s%d%s%1.2f", "The value of ", inputOne, " divided by ", inputTwo, " is equal to ", calculatedValue);
        printf("\nPlease note: This is only accurate to two decimal places.");
        break;

【问题讨论】:

  • 不是答案,但请注意(float)something = somethingnot valid in the standard C
  • 缺少变量声明。请出示minimal reproducible example。您确定 inputOneinputTwo 包含您期望的值吗?
  • 答案完全取决于inputOneinputTwo 的声明方式。他们是int,还是double,还是什么?
  • 作为一般规则(尤其是如果您不确定自己在做什么),您应该避免大多数类型转换,因为它们通常不是解决问题的正确方法,而且它们可以往往使事情变得更糟,或隐藏真正的问题。但是(作为该一般规则的一个例外),如果您有两个 int 变量,并且您想将它们相除以产生浮点结果,您肯定需要将其中至少一个转换为 (double) (或者可能是(float))。
  • 如果 calculatedValue 是一个 int,您可以使用 %1.2f 打印它。

标签: c


【解决方案1】:

你的问题是分裂本身。

将两个ints 相除会产生另一个int。因为是int,所以不可能有小数。

int 转换为float 不能神奇地重新引入它从未有过的小数。

您需要将任一操作数转换为float,这样除法本身就不会产生int。您不需要任何其他演员表。

【讨论】:

  • 他们还需要确保 calculatedValue 实际上被声明为浮点数或双精度数。
  • 嗨。我刚刚将更改后的代码添加到原始帖子中,但它不起作用。这是因为计算的值无论如何都设置为 int 吗?只是想了解如何在这种情况下正确使用类型转换。
  • @MitchellWelch 如果calculatedValue 被声明为int,那么您将永远无法获得浮点结果。您确实需要向我们展示您的变量是如何声明的;它使一切变得不同。
  • @SteveSummit 我不同意。检查我在原始帖子中的第四个代码 sn-p。我还在顶部添加了变量。
  • @MitchellWelch 您可以不同意所有您想要的,但您使用的代码是您不理解的,这里也没有其他人可以解释。如果你不同意那些试图解释我们可以理解的代码的人,那么我不确定我们来这里是为了什么。我再说一遍,如果你正在做一个除法并将结果分配给int calculatedValue,你永远不会在 C 中得到浮点结果。如果你有兴趣在 C 中得到浮点结果,我可以告诉你怎么做,但它会涉及到 calculatedResult 的不同声明。
【解决方案2】:
int inputOne, inputTwo;
calculatedValue = (float)inputOne / inputTwo;

强制转换不是需要 - 有替代方案,但它使用 以确保使用浮点数学而不是整数数学计算除法。

但这只是需要审查的一步:calculatedValue 的类型是什么?如果这也是int,则float 商将转换回int。然后FP部门就没有用了。

int calculatedValue  = (float)inputOne / inputTwo; // poor code

改为使用浮点 (FP) 类型

float calculatedValue  = (float)inputOne / inputTwo; // better

由于calculatedValue,作为float,转换为double 用于打印,请考虑将double 数学用于所有典型的FP 操作,并保留float 用于空间/速度的选择使用。

double calculatedValue  = (double)inputOne / inputTwo; // better yet
printf("%.2f", calculatedValue);

一般来说,避免强制转换。它倾向于隐藏问题。替代品:

double calculatedValue  = 1.0 * inputOne / inputTwo;
// or 
double calculatedValue  = inputOne;
calculatedValue /= inputTwo;

注意%1.2f" 中的1 没有任何作用。 1 是打印数字的指定最小宽度,并且数字始终打印出至少 1 个字符。由于".2" 部分,%1.2f" 将始终打印出至少 4 个字符。 考虑%.2f"

【讨论】:

  • 完美,很好的答案,谢谢。 calvulatedValue、inputOne 和 inputTwo 都声明为 int。您能解释一下为什么以下方法有效吗?是因为它将 int 类型转换为浮点数以及操作数吗? printf("%s%d%s%d%s%1.2f", "", inputOne, "除以", inputTwo, "等于", (float)calculatedValue = (float)inputOne / ( float)inputTwo);
  • @MitchellWelch (float)calculatedValue = ... 中的 (float)calculatedValue 不是有效的 C 代码。也许您正在使用一些带有语言扩展的 C 编译器,或者可能是另一种语言(C++?IDK)
  • @MitchellWelch 请注意,当我们得到答案的结尾时,chux 假设caluclatedValuefloatdouble。如果calculatedValueint,则此解决方案将不起作用
  • @SteveSummit 没有盲目假设。这个答案讨论了整数和 FP caluclatedValue 的影响。
  • 我的编译器是安装了 C++ 的 Visual Studio Basic,但我们将文件重命名为 .c 而不是 .cpp。也许这就是我的困惑?
【解决方案3】:

您必须决定是为整数值还是浮点值编写计算器。

如果您正在编写整数值计算器,则不需要任何类型转换。当你写

calculatedValue = inputOne / inputTwo;

您将得到一个整数结果,余数被丢弃,但这对于仅整数计算器来说是合适的结果。

如果您想要一个浮点值计算器,最好将inputOneinputTwocalculatedResult 声明为double。在这种情况下,您仍然不需要任何演员表,因为现在,当您编写时

calculatedValue  = inputOne / inputTwo;

你会得到浮点除法和浮点结果。

正如其他人所解释的那样,如果出于某种原因您将 inputOneinputTwo 作为整数,但您想要一个浮点结果,则必须将 calculatedResult 声明为 double,然后编写

calculatedResult = (doiuble)inputOne / inputTwo;

你也问过这条线

printf("%s%d%s%d%s%1.2f", "The value of ", inputOne, " divided by ", inputTwo, " is equal to ", (float)calculatedValue = (float)inputOne / (float)inputTwo);

并声称它以某种方式起作用。但这不是C,所以我们无法解释。 (您使用的是什么编译器?)在 C 中,表达式

(float)calculatedValue = (float)inputOne / (float)inputTwo

是非法的,因为左边

(float)calculatedValue

是一个右值,不可赋值。

【讨论】:

  • 啊,可能是这样(如果我使用了错误的编译器,很抱歉造成混淆,实际上是使用大学告诉我使用的编译器)。我的编译器是安装了 C++ 的 Visual Studio Basic,但我们将文件重命名为 .c 而不是 .cpp。也许这就是我的困惑?
  • 我刚刚注意到你说它是一个右值,这意味着它是不可赋值的……但是它是可赋值的,因为我可以给它赋值。如果我将其声明更改为 float 而不是 int,那么这将可以在没有类型转换的情况下分配。
  • @MitchellWelch 我告诉你它是不可分配的在 C 中。说它是可分配的,因为您可以分配给它,就像说您可以从加油站偷钱,因为您尝试过一次并侥幸成功。您的编译器有扩展(它们都有),这意味着它正在编译 Visual Studio sorta-C,而不是标准的可移植 C。如果您想在 C 中解决问题,我们可以为您提供帮助。如果您想继续使用(float)calculatedValue = something,或者想了解它的工作原理,我们不能。
【解决方案4】:

你的程序有问题的部分归结为:

int inputOne = 10, inputTwo = 3, calculatedValue;
calculatedValue = inputOne / inputTwo;

calculatedValue 是一个int,因此它不能有小数部分。所以这里calculatedValue在除法之后包含3

现在,如果您使用printf("%f", (float)calculatedValue) 打印它,您将得到3.000000 的输出,因为(float) 转换只会将calculatedValue (=3) 中的整数值转换为float (=3.0 )。

为了获得预期的结果,您可能需要这样做:

int inputOne = 10, inputTwo = 3;
float calculatedValue;
calculatedValue = inputOne / inputTwo;

calculatedValue 将再次包含3.0 而不是预期的3.33333。 现在这里的问题是表达式inputOne / inputTwo 是一个int,其值为3(请记住,inputOneinputTwo 都是ints),所以基本上你仍然分配int!将3 的值赋值给float 变量calculatedValue

为了得到预期的结果,你可以这样做:

float inputOne = 10, float = 3;
float calculatedValue;
calculatedValue = inputOne / inputTwo;

所有变量的类型都是 float,表达式 inputOne / inputTwo 将是 floatcalculatedValue 最终将包含 3.33333。

int inputOne = 10, float = 3;
float calculatedValue;
calculatedValue = (float)inputOne / inputTwo;

这里的表达式(float)inputOne / inputTwo 是浮点类型(我们将float 除以int),你会再次得到预期的结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多