В C — переменная, увеличенная внутри цикла, не сохраняет значение CS50

Я новичок в C и у меня есть этот код:

#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>


int main(int argc, string argv[])
{
    string s = get_string("Enter string: ");
    int measure = 0;
    for(int i = 0; i < strlen(s);i++)
    {
        if(isalpha(s[i])==0)
        {
            measure++;
        }

    }
    printf("Measure is now %i\n", measure);
}

Если я помещу свой printf внутрь цикла, я увижу правильное инкрементирование меры, но он вернется к нулю, когда у меня будет мой printf после завершения цикла. Я считаю, что это проблема области действия, но я понимаю, что переменная, в данном случае мера, объявленная вне цикла, имеет область действия основной функции и поэтому может быть изменена в циклах for и while. Я думаю, что это неправильно, и я не уверен, как получить значение в рамках цикла, переданного обратно в основную функцию.

Редактировать: я оставляю этот пост таким, каким он был изначально, поэтому комментарии ниже имеют смысл. @MaroBonelli заставил меня заметить, что я запутался между двумя окнами, а printf внутри цикла в этом коде фактически не печатал значения.


person Michael    schedule 21.07.2019    source источник
comment
То, что вы говорите, не имеет смысла. Значение не будет волшебным образом сброшено до 0, если вы каким-то образом не сбросите его явно. Если вы имели в виду подсчет буквенных символов, то проверка if (isalpha(s[i]) == 0) неверна, она должна быть прямо противоположной: if (isalpha(s[i])).   -  person Marco Bonelli    schedule 21.07.2019
comment
Ваш опубликованный код не отображает поведение. measure будет увеличено. Я подозреваю, что в вашем реальном коде measure затенено, будучи объявленным в двух разных областях. Добавьте -Wshadow в строку компиляции (gcc/clang) из /W3 (VS/cl.exe) и посмотрите, выдаются ли какие-либо предупреждения.   -  person David C. Rankin    schedule 21.07.2019
comment
@MarcoBonelli хороший улов на isalpha(s[i])==0 - пронесся прямо мимо этого.   -  person David C. Rankin    schedule 21.07.2019
comment
@MarcoBonelli Да, вы правы. Я работал в двух окнах, и мой printf был в цикле только с if(isalpha(s[i]) и printf вне цикла, который у меня был if(isalpha(s[i])==0). В качестве стороны вопрос, я думал, что if(isalpha(s[i]) будет эквивалентно if (isalpha(s[i])==1) но это, похоже, не так. Не будут ли оба проверять логическое значение правда?   -  person Michael    schedule 21.07.2019
comment
@Michael прочитал руководство по функции (man isalpha): ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ: возвращаемые значения не равны нулю, если символ c попадает в тестируемый класс, и ноль, если нет.. Он только говорит, что возвращаемое значение будет отличным от нуля, поэтому вы не можете заранее предполагать какое-либо конкретное значение. Он может быть даже отрицательным.   -  person Marco Bonelli    schedule 21.07.2019
comment
@MarcoBonelli Спасибо за это. Я все еще привыкаю к ​​справочным страницам, и некоторые из их терминов все еще довольно загадочны для меня. Я прочитал это как 0 для false и 1 для true. Когда я меняю код на if(isalpha(s[i])!=0) он отлично работает. Я знаю, что if(isalpha(s[i]) , вероятно, более синтаксически правильный, но пока я учусь, я пытаюсь быть явным в своем коде, пока я разбираюсь в вещах. Пожалуйста, оставьте свой комментарий или что-то подобное как ответ, чтобы я мог отметить его правильно Еще раз спасибо!   -  person Michael    schedule 21.07.2019
comment
@Майкл, как пожелаешь.   -  person Marco Bonelli    schedule 21.07.2019


Ответы (1)


Перевод моего комментария в ответ:

Значение НЕ будет сброшено до 0, если вы каким-то образом не сбросите его явно. Если вы хотели подсчитать буквенные символы, то эта проверка неверна:

if (isalpha(s[i]) == 0) 

Должно быть с точностью до наоборот:

if (isalpha(s[i]))
// or
if (isalpha(s[i]) != 0)

Со страницы руководства для isalpha:

ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ

Возвращаемые значения не равны нулю, если символ c попадает в проверяемый класс, и нулю, если нет.

person Marco Bonelli    schedule 21.07.2019