- PVSM.RU - https://www.pvsm.ru -
Четвертая часть перевода D Programming Language Tutorial [1] от Ali Çehreli [2].
Другие части:
Конкретные понятия, которые представлены в программе, называются переменными. Значение вроде температура воздуха или более сложный объект, как двигатель машины, могут быть переменными в программе.
Каждая переменная имеет определенный тип и определенное значение. Большинство переменных также имеют имена, но некоторые являются анонимными.
В качестве примера переменной мы можем рассматривать концепцию числа учеников в школе. Так как число студентов является целым числом, int — подходящий тип, и studentCount будет достаточно описывающим именем.
Согласно синтаксическим правилам D переменная начинается с ее типа с последующим именем. Введение переменной в программу называется определением. Как только переменная определена, ее имя начинает представлять ее значение.
import std.stdio;
void main()
{
// Определение переменной; это определение
// указывает, что типом studentCount является int:
int studentCount;
// Название переменной становится ее значением:
writeln("Присутствует ", studentCount, " учеников.");
}
Вывод этой программы:
Присутствует 0 учеников
Как видно из этой строки, значение studentCount равно 0. Согласно таблице фундаментальных типов из прошлой главы: начальное значение int равно 0.
Заметьте, что строка studentCount не появляется в выводе. Другими словами, программа не выводит «Присутствует studentCount учеников».
Значения переменных изменяются с помощью оператора =. Оператор = присваивает новые значения переменным, и по этой причине и называется оператором присвоения:
import std.stdio;
void main()
{
int studentCount;
writeln("Присутствует ", studentCount, " учеников.");
// Присваивание значения 200 переменной studentCount:
studentCount = 200;
writeln("Теперь присутствует ", studentCount, " учеников.");
}
Присутствует 0 учеников.
Теперь присутствует 200 учеников.
Когда значение переменной известно в момент определения, значение переменной может быть присвоено одновременно с ее определением. Это важный принцип; это делает невозможным использование переменной до момента присвоения предназначенного ей значения:
import std.stdio;
void main()
{
// Одноврменное определение и присвоение значения:
int studentCount = 100;
writeln("Присутствует ", studentCount, " учеников.");
}
Присутствует 100 учеников.
void main()
{
int amount = 20;
double rate = 2.11;
writeln(«Я обменял », amount,
" евро по курсу ", rate);
}
-->
import std.stdio;
void main()
{
int amount = 20;
double rate = 2.11;
writeln("Я обменял ", amount,
" евро по курсу ", rate);
}
До этого момента весь напечатанный вывод наших программ появлялся в окне консоли. Хотя это на самом деле часто используется многими программами, на самом деле символы выводятся в стандартные потоки вывода.
Стандартный вывод основан на символах; все, что печатается, сначала конвертируется в символьное представление и потом последовательно отправляется на вывод как символы. Например, целочисленное значение 100, которое мы выводили в прошлой главе не посылается на вывод как значение 100, а как три символа 1, 0 и 0.
Аналогично то, что мы обычно воспринимаем как клавиатура, на самом деле является стандартным потоком ввода программы, и он также основан на символах. Информация всегда поступает как символы для конвертацию в данные. Для примера целочисленное значение 42 на самом деле приходит через стандартный ввод как символы 4 и 2.
Эти преобразования производятся автоматически.
Это понятие последовательных символов называется символьным потоком. Так как стандартный поток ввода и стандартный поток вывода подходят под это описание, они являются символьными потоками.
Названия стандартных потоков ввода и вывода в D — stdin и stdout соответственно.
Операции над этими потоками обычно требуют имя потока, точку и название операции; например stream.operation(). Так как stdin и stdout используются очень часто, по соглашению, стандартные операции над ними могут быть вызываны без необходимости указывания имени и точки, например operation().
writeln, которую мы использовали в предыдущих главах на самом деле является сокращением от stdout.writeln. Также write — сокращение от stdout.write. Соответственно программа «привет мир» может быть написана так:
import std.stdio;
void main()
{
stdout.writeln("Hello world!");
}
import std.stdio;
void main()
{
stdout.writeln(1, ",", 2);
}
Любые данные, которые были прочитаны программой, должны быть сперва сохранены в переменную. Например, программа, которая читает количество студентов из стандартного потока ввода, должна сохранить эту информацию в переменную. Типом этой конкретной переменной может быть int.
Как мы убедились в предыдущей главе, нет необходимости указывать stdout, когда выводим информацию, так как он предполагается. Далее, то, что выводится, указывается как аргумент. Поэтому write(studentCount) достаточно, чтобы вывести значение studentCount. Подведем итог:
поток: stdout
операция: write
данные: значение переменной studentCount
цель: обычно, окно терминала
Обратная операции write — readf; она читает из стандартного потока ввода. Буква «f» в имени взята от «formatted», так как то, что читает эта функция, должно быть всегда представлено в определенном формате.
Также в прошлой главе мы узнали, что стандартный поток ввода называется stdin.
В случае чтения один кусочек головоломки все еще отсутствует: куда сохранить данные. Подведем итоги:
поток: stdin
операция: readf
данные: некоторая информация
цель: ?
Расположение места, куда необходимо сохранить данные, указывается с помощью адреса переменной. Адресом переменной является точное положение в памяти компьютера, где хранится ее значение.
В D символ '&', напечатанный перед именем, является указанием адреса того, что представляет эта переменная. Например, адресом studentCount является &studentCount. Здесь, &studentCount может быть прочитано как «адрес studentCount», и это недостающий кусок, который заменяет знак вопроса выше:
поток: stdin
операция: readf
данные: некоторая информация
цель: расположение переменной studentCount
Набор символа & перед именем означает взятие адреса того, что представляет это имя. Это понятие является основой ссылок и указателей, которые мы увидим в следующих главах.
Я отложу объяснение одной особенности использования readf; сейчас, примем правило о том, что первым аргументом readf должна быть строка "%s":
readf("%s", &studentCount);
Заметка: Как я объясняю ниже, в большинстве случаев в строке также должен присутствовать пробел: " %s".
"%s" указывает, что данные должны быть автоматически преобразованы таким способом, который подходит под тип переменной. Например, когда символы '4' и '2' читаются в переменную типа int, они должны быть преобразованы в целочисленное значение 42.
Программа ниже просит пользователя ввести число учеников. Необходимо нажать клавишу Enter после окончания ввода:
import std.stdio;
void main()
{
write("Сколько присутствует учеников? ");
/*
* Объявление переменной, которая будет использована для
* хранения информации, которая читается из потока ввода
*/
int studentCount;
// Запись входных данных в эту переменную
readf("%s", &studentCount);
writeln("Понял: Присутствует ", studentCount, " учеников.");
}
Даже клавиша Enter, которую мы нажимаем после ввода данных, сохраняется как специальный код и помещается в поток stdin. Это помогает программам обнаруживать, была ли информация введена в одной или нескольких строчках.
Хотя это иногда полезно, такие специфические коды в большинстве случаев не важны для программы и должны быть удалены из ввода. Иначе они блокируют ввод и не дают читать другие данные.
Для демонстрации проблемы, давайте читать также число преподавателей из потока ввода:
import std.stdio;
void main()
{
write("Сколько присутствует учеников? ");
int studentCount;
readf("%s", &studentCount);
write("Сколько присутствует преподавателей? ");
int teacherCount;
readf("%s", &teacherCount);
writeln("Понял: Присутствует ", studentCount, " учеников",
" и", teacherCount, " преподавателей.");
}
К сожалению, теперь программа застряла при чтении второго int:
Сколько присутствует учеников? 100
Сколько присутствует преподавателей? 20
<- Программа зависает здесь
Хотя пользователь ввел число преподавателей равным 20, специальные коды, которые представляют клавишу Enter при чтении предыдущего значения 100, все еще находятся в потоке ввода и блокируют его. Символы, которые хранятся в потоке ввода аналогичны следующим:
100[EnterCode]20[EnterCode]
Первый символ [EnterCode] блокирует ввод.
Решением этой проблемы является добавление пробела перед %s для обозначения того, что код клавиши Enter, который может быть встречен перед чтением числа преподавателей, не важен: " %s". Пробелы в строке форматирования используются для чтения и игнорирования нуля или более невидимых символов, которые могут предшествовать вводу. Такие символы включают в себя: сам символ пробела, коды, которые представляют клавишу Enter, символ клавиши Tab и другие, называемые пробельными символами.
В общем случае можно использовать " %s" для любых данных, которые читаются из потока ввода. Программа выше работает как ожидается со следующими изменениями:
// ...
readf(" %s", &studentCount);
// ...
readf(" %s", &teacherCount);
// ...
Вывод:
Сколько присутствует учеников? 100
Сколько присутствует преподавателей? 20
Понял: Присутствует 100 учеников и 20 преподавателей.
Чтобы закомментировать другие комментарии, используйте /+ и +/:
/+
// Однострочный комментарий
/*
Комментарий, который занимает
несколько строк
*/
Блок комментария, который включает в себя другие комментарии
+/
import std.stdio;void main(){writeln("Тяжело читаемо!");}
Тяжело читать код, в котором столько же пробелов, сколько в этом.
Автор: NCrashed
Источник [9]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/programmirovanie/77912
Ссылки в тексте:
[1] D Programming Language Tutorial: http://ddili.org/ders/d.en/index.html
[2] Ali Çehreli: http://ddili.org/AliCehreli_resume.html
[3] Часть 1: http://habrahabr.ru/post/226071/
[4] Часть 2: http://habrahabr.ru/post/226565/
[5] Часть 3: http://habrahabr.ru/post/243595/#
[6] Переменные: #Variables
[7] Стандартные потоки ввода и вывода: #StandartIO
[8] Чтение из стандартного потока ввода: #ReadingStdInput
[9] Источник: http://habrahabr.ru/post/243687/
Нажмите здесь для печати.