Значение переменной сбрасывается внутри цикла в C - PullRequest
0 голосов
/ 21 мая 2018

У меня есть случай, в котором я должен определить, является ли число положительным, отрицательным или равным нулю, и подсчитать, сколько раз происходил каждый из этих случаев.Код, который я написал, выглядит следующим образом:

#include 
#include 
#include 

using namespace std;

int main(int argc, char *argv[])
{
    char opcion = 's';
    int positivos = 0;
    int negativos = 0;
    int ceros = 0;
    //int ceros2 = 0;
    int temporal;
    do{
        printf("Enter a number: ");
        scanf("%d",&temporal);
        if(temporal >= 0)
        {
            if(temporal==0)
            { 
                ceros ++;
            }
            else
            {
                positivos ++;
            }
        }

        if(temporal < 0)
        { 
            negativos ++;
        }
        printf("Do you want to enter another number? (s/n)");
        scanf("%s",&opcion);
    }
    while(opcion == 's' || opcion=='S');
    printf("you have %d possitive numbers \n",positivos);
    printf("you have %d negative numbers \n",negativos);
    printf("you have %d zero \n",ceros);
    return 0;
}

Если я выполню код как есть, число нулей всегда будет равно нулю, но если вы расшифруете строку 13 int ceros2 = 0; (моя логика была «давайтеобъявите другую инициализированную переменную и посмотрите, что произойдет "), тогда программа будет считать нули, как и ожидалось.Почему я должен объявить бесполезную переменную, чтобы программа подсчитала?

Что компилятор C делает с кодом, который не учитывает значение последней объявленной и инициализированной переменной, если вы не объявите новуюинициализированная переменная?

1 Ответ

0 голосов
/ 21 мая 2018

Вы просите scanf() прочитать строку C, которая, если пользователь вводит символ, будет содержать как этот символ, так и нулевой терминатор.Вы предоставили хранилище только для одного персонажа.Итак, нулевой терминатор не подходит, но где-то хранится.Как это происходит, он забивает другие данные, которые находятся рядом с opcion в стеке, и это ваша переменная ceros.

Объявление другой переменной реорганизовало расположение данных в стеке именяет то, что становится засоренным, так что вы этого не замечаете.Тем не менее, запись по-прежнему выходит за границы.

Вы можете использовать строку формата "%c" для чтения одного символа.

...