【问题标题】:Loop counter not incrementing循环计数器不递增
【发布时间】:2016-12-05 13:37:08
【问题描述】:

下面的函数aquire_marks被设计用来取5个用户输入的数字,并将它们存储在marks中。运行时,for循环按预期运行一次j=0,然后按预期运行j=1,但随后j永远不会增加到2,并停留在1,使函数处于无限状态环形。如果将循环放在main 内,则不会发生此问题,但如果可能的话,我更愿意将它放在单独的函数中。有什么线索吗?

#include<stdio.h>

void aquire_marks(char marks[], char names[][11]){ // 11 - max name length + 1
    char j, mark;

    for(j=0; j<5; j++){
        printf("Enter mark for %s: ", names[j]);
        scanf("%d", &mark);
    }
}

int main() {
    char names[5][11] = {"a", "b", "c", "d", "e"};
    char marks[5];

    aquire_marks(marks, names);
}

【问题讨论】:

  • 为什么 j 是 char 然后在循环中用作索引?
  • scanf("%c", &amp;mark);?那不是char吗?或者应该是int
  • 你通过了marks[] 但忽略了它。
  • %d 想要int。您正在传递char,因此scanfj 变量覆盖到堆栈中...
  • 是的:使用自然大小int,除非有充分的理由不这样做。

标签: c arrays loops


【解决方案1】:

您已将mark 声明为char,但在scanf 调用中您使用的是d 转换说明符,它期望其对应的参数具有int * 类型,而不是char * .使用错误的转换说明符会导致未定义的行为。

我将推测markj 在内存中是相邻的,并且在读取mark 的整数值的过程中(可以是2 到4 字节宽)的值j 正在被覆盖。

mark 是否应该代表一个数值(9075 等)?如果是这样,请将mark 的类型从char 更改为int

如果 mark 应该代表字母等级(AB 等),则将 scanf 调用更改为

scanf( " %c", &mark ); // note leading whitespace

【讨论】:

  • 不,我特别选择了 char,因为我只需要小于 128 的数字
  • @ACarter:最好使用int 并自己进行范围检查,但没关系。如果您想读取 numeric 值并将它们存储在 char 类型中,则使用 %hhd 而不是 %d 作为转换说明符,因此 scanf 将读取正确的字节数。
【解决方案2】:

您正在将 1 byte 变量 (char) 的地址传递给一个函数,该函数将威胁它作为 int 指针。

如果我们假设int4 bytes,则scanf 覆盖3 byte 靠近mark 变量的堆栈。

第一个大概是j

【讨论】:

    【解决方案3】:

    我会将 j 的声明更改为 int

    char mark;
    
    for(int j=0; j<5; j++){
        printf("Enter mark for %s: ", names[j]);
        scanf("%d", &mark);
    }
    

    【讨论】:

    • 这并没有解决真正的问题(甚至提到它)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-31
    • 2012-11-26
    相关资源
    最近更新 更多