// - "Talk to me like I'm a 3 year old!" Programming Lessons -
//
// $Author: Ben Humphrey digiben@gametutorials.com
//
// $Program: Strings
//
// $Description: Ask/Answers questions with strings.
//
// $Date: 6/5/00
//
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
#include <windows.h>
#include <stdio.h> // Мы подключаем этот файл, чтобы использовать функцию printf(), и т.д.
#include <string.h> // Мы подключаем этот файл, чтобы использовать strcmp() (сравнивает строки)
void main() // Начало программы
{ // Начало функции main
char szAnswer[25] = {0};
/* Так мы объявляем строку. Если бы мы не поставили бы в конце [25], это был бы просто символ.
Нам не понадобилось бы [25], если бы мы запрашивали только 'y' или 'n'. Но, так как мы
хотим, чтобы пользователь ввел больше одного символа, мы ставим [количество символов] после
имени переменной. Еще раз, переменная это имя, указывающая на место в памяти. Вместо того,
чтобы называть все 0X034F683C, проще использовать понятные нам имена. Как например, имя "szAnswer"
должно сказать нам, что эта переменная - строка символов, которая будет содержать ответ.
Программный код иногда трудно читать, но чем легче он читаем, тем лучше, особенно если его
будут читать другие люди. Даже если и не будут, вы сами иногда будете возвращаться к нему и
просматривать его сами. Поверьте мне, вы забываете то, что вы делаете, и если вы не будете
коментировать ваши программы и использовать значимые имена переменных, вы БУДЕТЕ забывать.
Есть еще кое-что интересное в этой строке - " = {0}".
Так мы инициализируем строку. Если не сделать этого, при распечатке строка будет выглядеть
примерно так: "IIIIIIIIIIIIIIIIIIIIIIIIIIIII8be" (25 символов мусора). */
printf("Do you like programming yet? ");
// Вывод на экран вопроса ("Вам все еще нравится программировать?")
scanf("%s", szAnswer);
/* Так как мы читаем строку, мы должны использовать "%s". Передаем szAnswer чтобы хранить ответ.
Дальше идет выражение, на которое следует обратить внимание.
strcmp() означает "сравнить строки". Эта функция сравнивает 2 строки. Если вы просто проверяете, равны ли
строки, неважно, в каком порядке вы их передаете в функцию. Я обычно передаю первой переменную. Функция
strcmp() возвращает "0" (ноль) если строки идентичны. Это следует объяснить.
Строка "strcmp(szAnswer, "yes") == 0" вызывает функцию strcmp(), которая проверяет каждый символ в каждой
строке, чтобы убедиться в их идентичности. Если проверка показывает, что они действительно идентичны,
функция strcmp() возвращает ноль. Это означает, что код как бы заменяется и выглядит вот так: "0 == 0".
Если строки не идентичны, strcmp() возвращает отрицательное или положительное число, в зависимости от
того, была ли строка слева больше или меньше чем строка справа. Но в большинстве случаев мы проверяем
равенство нулю. Продолжаем... Обратите внимание на использование скобок "( strcmp(szAnswer, "yes") == 0)".
Я добавил еще пару скобок, потому что мы проводим еще одну проверку в том же самом выражении "if".
Вы не обязаны это делать, но это улучшает читаемость кода. Если вы не знакомы с тем, как работают
скобки, вот пример: (5 * 2) / 10 = 1. Первым выполнится умножение, и мы получим 10 / 10, что дает в
результате 1.
Как я и говорил, вам не обязательно использовать скобки, потому что компьютер знает порядок действий,
но так будет понятней человеку, который не знает. Если вы сомневаетесь, используйте скобки.
Итак, мы проверяем, ввел ли пользователь "yes" в нижнем регистре. Затем, в том же выражении IF мы
проверяем, ввел ли пользователь "Yes" с буквой "Y" в верхнем регистре. При использовании оператора ИЛИ (||),
только одному из условий необходимо быть истинным, для того чтобы выполнился код внутри выражения IF. */
if( ( strcmp(szAnswer, "yes") == 0) || ( strcmp(szAnswer, "Yes") == 0) )
{ // Если пользователь ввел "yes" или "Yes" , напечатать:
printf("Good for you! It's fun isn't it?\n"); // ("Молодец! Не правда ли это здорово?")
}
else // Если пользователь не ввел "yes" или "Yes":
{
printf("Don't worry, if it seems frustrating now, it will become more clear.\n");
}
// ("Не волнуйтесь, если сейчас все кажется трудным, потом все станет понятней")
printf("Do you like programming yet? "); // Сделаем то же самое по другому.
rewind( stdin );
/* Поскольку мы используем scanf() (далеко не самую лучшую функцию), нам нужно очистить буфер,
который содержит данные ввода с клавиатуры - то что пользователь вводил до этого.
Это делает функция rewind(). "stdin" означает "стандартный ввод" - буфер, в котором хранится
введенные с клавиатуры данные. */
scanf("%s", szAnswer); // Снова считываем ответ.
/* Второй способ проверить, что ввел пользователь, заключается в следующем.
Нужно проверить первый введенный символ. Этот способ позволяет пользователю
быть менее формальным. Например, можно будет ввести "yah sure!" или "yup!" или "yah, what ever..."
и это все будет интерпретироваться как "yes".
Прежде чем разобрать, как это работает, позвольте мне объяснить, как работают строки.
Строка представляет собой последовательность символов, верно? И всегда можно разбить
строку на отдельные символы. Именно так компьютер и обрабатывает строки - в виде набора
ячеек, в которые помещаются символы. Это называется "массив". Можно также создать и числовой
массив.
Возьмем для примера слово "Hello". Строка будет распределена так: "H" в нулевой ячейке,
"e" в первой ячейке, "l" во второй, "l" в третьей, "o" в четвертой. Именно так - массив начинается
с нулевой ячейки. Но мы забыли последнюю ячейку. У ВСЕХ строк есть завершающая ячейка с символом '\0'.
Это нулевой завершающий символ (NULL terminator). Он дает компилятору понять, где конец строки.
Позвольте объяснить, зачем это нужно. Мы создали в начале строку из 25 символов, верно? И если мы
хотим напечатать на экран то, что введено пользователем, без нулевого завершающего символа это
выглядело бы вот так (например, введено "yes"): "Your answer was yes ."
Видите? Как компьютер узнает когда остановиться? Нам нужна строка "Your answer was yes." Нам
не нужны дополнительные пробелы. Кстати, я выбрал количество символов [25], потому что это наиболее
подходяще, если мы захотим ввести что-нибудь, больше чем "yes" или "no"... иначе нам хватило бы
всего [3] или даже 1, если мы проверяем только первый введенный символ. */
if( szAnswer[0] == 'y' || szAnswer[0] == 'Y' )
{ // Если первым символом введено 'y' или 'Y'
printf("Good for you! It's fun isn't it?\n");
}
else // Если введено что-либо еще
{
printf("Don't worry, if it seems frustrating now, it will become more clear.\n");
}
/* Вот что происходит, если введено "yes".
szAnswer[0] == 'y' , szAnswer[1] == 'e', szAnswer[2] == 's'
Нулевая ячейка - 'y', ячейка 1 - 'e' , ячейка 2 - 's'.
Помните, что ячейки начинаются с нулевой, и поэтому нам нужно проверить равен ли символ в нулевой ячейке
'y' или 'Y'.
Вот так записывается обращение к массиву:
" <variableName>[index] то есть szName[3] == '\0' если szName is "Ben" "
Вы не можете сделать такую проверку: if(szName == "Ben"). Это не будет работать.
Если szName это массив, это все равно что сказать if(szName[0] == "Ben")
Обычная переменная - это одномерный массив, т.е. по умолчанию - <name>[0].
Даже числа, такие как "num". num[0] = 2; это то же самое, что и num = 2;
Просто обычно ноль не пишется, потому что и так понятно, что имеется в виду. */
} // Конец функции main
// © 2001 GameTutorials
// Перевод © 2004 Евгений Казеко
// www.gamecoder.kazeko.com
// evgeniy@kazeko.com
|