Чарс действительно плохо в современной C? - PullRequest
0 голосов
/ 30 марта 2020

Я делаю C упражнение по программированию, но у меня есть некоторые проблемы с объявлениями. Я прочитал, что не должен использовать char тип объявления, но я должен использовать int (в соответствии с https://matt.sh/howto-c я не должен использовать ни один из них). Рабочий код с нежелательным char :

#include <stdio.h>
#include <stdint.h>

int main (void)
{

int hour_12, min;
char ch, ch2;

printf("What time is it? (in xx:xx PM format): ");
scanf("%d:%d %c%c", &hour_12, &min, &ch, &ch2);

printf("%c%c\n", ch, ch2); /* just a checkpoint */

if (ch == 'P' && ch2 == 'M' || ch == 'p' && ch2 == 'p'){
    if (hour_12 != 12){
        printf("Hour_12: %d:%d %c%c\n", hour_12, min, ch, ch2);
        printf("Hour_24: %d:%d\n", hour_12 + 12, min);
    }
    else{
        printf("Hour_12: %d:%d %c%c\n", hour_12, min, ch, ch2);
        printf("Hour_24: %d:%d\n", hour_12, min);
    }
}
return 0;
}

Задача № 1:

при использовании ' int ch, ch2 ;» Программа игнорирует проверку в строке 15:

if (ch == 'P' && ch2 == 'M' || ch == 'p' && ch2 == 'p'){  […]  }

, и результат просто 'PM' из:

printf("%c%c\n", ch, ch2); /* just a checkpoint */

Задача № 2:

при использовании ' uint8_t ch, ch2; ' программа не назначит указанный номер самой первой «% d» → «час_12» из строки 11:

scanf("%d:%d %c%c", &hour_12, &min, &ch, &ch2);

, а «час_12» всегда равен 0:

PM

Hour_12: 0:11 PM

Hour_24: 12: 11

Есть ли способ решить эту проблему без char ? Или, может быть, char совсем не плохо? Я хотел бы изучить хорошие практики программирования, но, кажется, очень трудно найти современные книги. У меня есть KN King, второе издание C, но я испытал некоторое неопределенное поведение программы, по крайней мере, дважды, когда следовал этому. Я использую G CC версия 10.0.1 20200325 (Red Hat 10.0.1-0.10).

С уважением.

1 Ответ

1 голос
/ 30 марта 2020

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

почему?

Тот, кто делает такое заявление, должен

  • убедительно
  • тестируемый
  • подробный

объяснение этого вопроса. Я не читал ссылку, поэтому не знаю точного обоснования, но если вы найдете его убедительным, отредактируйте свой вопрос, добавьте обоснование и дайте мне знать об этом.

Теперь, если вы убеждены что char действительно плохо , тогда ваш следующий вопрос должен быть

в каком случае это символ плохой?

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

Ваши критерии

if (ch == 'P' && ch2 == 'M' || ch == 'p' && ch2 == 'p'){  […]  }

не игнорируются. Это просто ложь в том случае, если вы упомянули. Задайте себе правильные вопросы еще раз:

Что я хочу добиться этого кода? Могу ли я перевести приведенное выше условие в обычный вопрос на английском языке?

Что ж, ответ должен быть либо сильным «нет», либо слабым «да». Сильное «нет», если вы этого не понимаете. Слабое «да», если вы понимаете или думаете, что понимаете это сейчас. Попробуем сформулировать утверждение простыми словами:

Если ch - это «P», а ch2 - это «M» или ch - это «p», а ch2 - «p».

Обратите внимание, что без или это утверждение всегда будет ложным, поскольку противоречащие значения проверяются по ch2. Итак, давайте посмотрим, что приоритет оператора здесь. Глядя здесь: https://en.cppreference.com/w/c/language/operator_precedence

вы видите, что логическое И имеет приоритет 11, а логическое ИЛИ имеет приоритет 12. Давайте сделаем это явным, чтобы избежать необходимости думать о приоритетах операторов :

if ((ch == 'P' && ch2 == 'M') || (ch == 'p' && ch2 == 'p')){  […]  }

Как мы можем сформулировать это в виде простых слов:

ch - «P» и ch2 - «M», или оба они - «p».

Итак, вам нужно проверить, каковы фактические значения ваших переменных. В случае с char это работает, если я не ошибаюсь. В противном случае вам необходимо проверить, что представляют собой значения, и сравнить их с соответствующим представлением типа данных символов. Это нелогично, если вы не выработаете четкое представление.

...