数组值在C中突然改变

时间:2018-07-23 23:41:58

标签: c arrays

我正在制作一个具有全局数组的程序。在将值分配给数组并打印它们的函数中,一切都很好。但是,当我尝试在另一个函数中使用这些数组时,它们的值突然之间就不同了。

    int *numeros;
    char *operadores;
    int num, num_operadores;

void crearArray() {

    int i;

    printf("How many numbers?\n");
    scanf("%d", &num);

    numeros = (int*)calloc(num, sizeof(int));
    operadores = (char*)calloc(num - 1, sizeof(char));
    num_operadores = num - 1;

    num += (num - 1);

    for (i = 0; i < num; i++) {

        if(i % 2 == 0 || i == 0) {
            printf("\t\nEnter a number: ");
            scanf("%d", &numeros[i]);
        }
        else {
            fflush(stdin);
            printf("\t\nEnter an operator: ");
            scanf("%c", &operadores[i]);
        }

    }

    printf("Array: ");

    for (i = 0; i < num; i++) {

        if(i % 2 == 0 || i == 0)
            printf("%d ", numeros[i]);

        else
            printf("%c ", operadores[i]);

    }

}


void crearArbol() {

    int i;

    printf("\n\nArrays:\n\t Numbers: ");

    for(i = 0; i < num_operadores + 1; i++)
        printf("\n\t\t Numeros[%d]: %d ", i, numeros[i]);

    printf("\n\t Operators: ");

    for(i = 0; i < num_operadores; i++)
        printf("\n\t\t Operadores[%d]: %c ", i, operadores[i]);

}

int main() {
    crearArray();

    crearArbol();

    return 0;
}

当然,打印数组并不是crearArbol的主要目的,但目前那里什么也没有,但我似乎无法弄清楚其变化的原因。

示例输出:

  

多少个数字?

     

3

     

输入数字:1

     

输入运算符:*

     

输入数字:2

     

输入操作员:/

     

输入数字:3

     

数组:1 * 2/3(从第一个函数crearArray打印的数组)

     

数组:   数字:

     

Numeros [0]:1

     

Numeros [1]:0

     

Numeros [2]:2

     

操作员:

     

Operadores [0]:

     

Operadores [1]:*(来自第二个函数crearArbol的打印数组值)

在此先感谢您的帮助!

3 个答案:

答案 0 :(得分:2)

您正在数组的边界之外写和读。您正在使用i依次索引numeros然后索引operadores,但这意味着i总是两倍于任何一个数组。您需要将i除以2才能将其转换为可用索引。

num += (num - 1);

for (i = 0; i < num; i++) {

    if(i % 2 == 0 || i == 0) {
        printf("\t\nEnter a number: ");
        scanf("%d", &numeros[i / 2]);
    }
    else {
        fflush(stdin);
        printf("\t\nEnter an operator: ");
        scanf("%c", &operadores[i / 2]);
    }

}

不是将num加倍,然后根据i是否可被两个整除来交替访问两个数组,我将保持num不变,而是在每个循环中访问两个数组迭代。

for (i = 0; i < num; i++) {

    printf("\t\nEnter a number: ");
    scanf("%d", &numeros[i]);

    if (i < num - 1)
        fflush(stdin);
        printf("\t\nEnter an operator: ");
        scanf("%c", &operadores[i]);
    }

}

答案 1 :(得分:2)

此行为的原因是您没有将项目读入数组的正确索引中:只有numeros的索引0、2、4,...具有有效数据,而索引1、3 oepradores中的,5,...具有运算符。剩余的索引为零,因为您分配了calloc

第一个功能通过打印与读取的索引相同的索引来掩盖此问题,而第二个功能通过打印“直接”索引来揭示此问题。

很明显,读取部分是一个问题,因为它超出了分配数组的末尾(未定义的行为)。您可以通过修改读取循环以一次读取数字和运算符的方式来解决此问题:

// Do not increment num
for (i = 0; i < num; i++) {
    printf("\t\nEnter a number: ");
    scanf("%d", &numeros[i]);
    if (i == num-1) {
        break; // Last number comes with no operator
    }
    fflush(stdin);
    printf("\t\nEnter an operator: ");
    scanf("%c", &operadores[i]);
}

显然,您还需要修改crearArray的打印代码以匹配crearArbol的打印代码。

答案 2 :(得分:0)

分别,精神上的错误试图将两个单独的数组视为一个单独的数组。查找结构数组的示例。在单独的数组上使用单独的索引变量? 关于复合条件的建议:使用(())而不是依赖先例规则。 我真的不知道您在输入流中使用fflush。这也指出了错误检查的不足。
通常,了解如何从调试器中转储数据。作为调试思路的来源,请保存代码,然后修改并查看会发生什么...