【问题标题】:printf changing its value after it should have already been printedprintf 在它应该已经被打印之后改变它的值
【发布时间】:2012-10-09 07:57:57
【问题描述】:

所以我在这里有这段代码,它(现在)只是将 base1 数字转换为 base 10 数字

/**
 * This function is supposed to convert 'number' from base1 to a number in base2.
 * It isn't fully implemented yet, and I've only converted base1 to a base 10 number.
 */
void base1_base2(int base1, int base2, int number) {

    int num, place = 0;
    int rem = number;
    int i;
    for (i = 0; i < num_digits(number); i++) {

        int mod = rem % 10;
        rem = floor(rem / 10);

        int powerResult = pow(base1, place++);
        num = num + mod * powerResult;  
    }

    int base10_num = num;

    printf("The number %i(base%i) in base 10 is: %i\n", number, base1, base10_num);
}

这会计算出正确的 base10 数,即函数调用 base1_convert(2, 5, 100) 将返回 4,正如预期的那样:

The number 100(base2) in base 10 is: 4

当我在该函数的最后一个 printf 正下方添加这段代码时,问题就出现了:

int base2_num = 0;
printf("The number %i(base%i) is: %d\n", number, base1, base2_num);

如果加上上面的代码,它完全改变了第一个printf的结果,使其返回:

The number 100(base2) in base 10 is: 4196784.
The number 100(base2) is: 0

我一生都无法弄清楚为什么会发生这种情况。我猜它与一些指针有关,但我并没有真正使用过任何指针,而且我不知道为什么添加一个看似独立的变量 int base2_num = 0; 会改变这一切。

这是添加上述行后的完整修改代码。

void base1_base2(int base1, int base2, int number) {

    int num, place = 0;
    int rem = number;
    int i;
    for (i = 0; i < num_digits(number); i++) {

        int mod = rem % 10;
        rem = floor(rem / 10);

        int powerResult = pow(base1, place++);
        num = num + mod * powerResult;  
    }

    int base10_num = num;

    printf("The number %i(base%i) in base 10 is: %i\n", number, base1, base10_num);

    int base2_num = 0;
    printf("The number %i(base%i) is: %d\n", number, base1, base2_num);

    return;
} 

编辑:这是我使用的唯一其他函数,num_digits。它返回整数的位数。

int num_digits(int integer) {

    char int_string[100];
    int str_length;
    sprintf(int_string, "%i", integer);
    str_length = strlen(int_string);

    return str_length;
}

这里是我调用函数的地方:

int main() {
    printf("Hello World\n");
    base1_base2(2, 5, 100);

    return 0;
}

【问题讨论】:

  • 什么是base1 号码?
  • @gokcehan:“鸡抓痕”,就像我们以前所说的那样:位数就是值。
  • @Michael:提供sscce(简单、独立、可编译的示例)被认为是不好的方式。为了重现您的问题,我必须编写一个 main() 来为其提供数字,这就是我对帮助您失去兴趣的地方。
  • 在循环中,如果rembase1中,那么在抓位的时候把它当成十进制数就显得很奇怪了(与% 10等等)。
  • @Michael:点击我评论中的链接。它详细解释了它。要点:提供main()。包括所有必要的标头(在这种情况下,stdio、match、string)。应该可以复制、粘贴、编译您的示例并立即获得与您相同的结果。 (MWE,最小可行示例,是这个的另一个首字母缩写词。)

标签: c printf


【解决方案1】:

只是想写:

int num = 0, place = 0;

你一定会完成的。

这就是为什么我建议逐行声明一个变量。

【讨论】:

  • 看来我们赢了。你知道为什么添加int base2_num = 0; 似乎会导致这个问题实际弹出吗?在添加那行之前很好。
  • 因为在执行时更改输出二进制文件会导致内存中的位置发生变化,因此num 随机为零的运气较差。
  • @Michael:养成的一个好习惯是每行只声明一个变量。避免了几个问题。
  • 并避免混淆声明和声明。
【解决方案2】:

和你一样,我不明白这里发生了什么。

如果这是 1990 年,我会说您使用 32 位整数值,而 printf() 需要 16 位整数,但在这种情况下这不是真的:如果宽度不匹配,那么所有其他数字都是也错了。所以它会打印出来

The number 0(base100)

The number 100(base0)

取决于您平台的字节序。

由于问题不在您的代码中,它一定在其他地方。建议:

  1. 尝试摆脱num_digits()。请参阅下面的 cmets。

  2. 添加更多printf()s 以​​查看所有值如何变化

  3. 在调试器中运行代码

  4. 关闭编译器的所有优化标志。也许其中一个触发了错误。

  5. 启用编译器支持的所有警告标志。

一些cmets:

  1. num_digits(number) 是一个相当昂贵的函数;不要循环调用它(即 N 次)。而是将结果缓存在局部变量中。或者在rem 为0 时停止(即将for 循环替换为while(0 != rem))。

  2. base1 这个名字不好。请改用inputBase,因为它传达了意图。

  3. 不用floor();整数除法总是向下舍入。

【讨论】:

  • 1:谢谢你绝对是对的。我改变了那个。 2:再次正确,但这是为了学校作业,他们使用 base1,这就是我最初这样做的原因。仍然是一个好主意,所以我也改变了它。 3:第三次,谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-12
  • 2011-11-25
  • 2016-09-05
  • 1970-01-01
  • 2011-02-05
  • 2020-09-04
  • 2021-12-15
相关资源
最近更新 更多