Підручник з мови програмування D. Частина 4

Четверта частина перекладу D Programming Language Tutorial Ali Çehreli.

Інші частини:


Змінні
Конкретні поняття, які представлені в програмі, називаються змінними. Значення зразок температура повітря або більш складний об'єкт, як двигун машини, можуть бути змінними у програмі.

Кожна змінна має певний тип і певне значення. Більшість змінних також мають імена, але деякі є анонімними.

В якості прикладу змінної ми можемо розглядати концепцію числа учнів в школі. Так як число студентів є цілим числом, 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 учнів.


Вправи
  • Визначте дві змінні для виводу «Я обміняв 20 євро за курсом 2.11». Для значення з плаваючою точкою використовуйте double.

    … рішення<--!
    import std.stdio;

    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("Привіт world!".);
}


Вправи

  • Переконайтеся, що stdout.write працює також, як write.
    … рішення
    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. Це допомагає програмам виявляти, чи була інформація введена в одній або декількох рядках.

Хоча це іноді корисно, такі специфічні коди в більшості випадків не важливі для програми і повинні бути видалені з тексту. Інакше вони блокують enter і не дають читати інші дані.

Для демонстрації проблеми, давайте читати також кількість викладачів з потоку вводу:

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, символ Табуляції і інші, звані пробельными символами.

У загальному випадку можна використовувати " %s" для будь-яких даних, які читаються з потоку вводу. Програма вище працює як очікується з наступними змінами:

// ...
    readf(" %s"., &studentCount);
// ...
    readf(" %s"., &teacherCount);
// ...


Висновок:
Скільки присутній учнів? 100
Скільки присутній викладачів? 20
Зрозумів: Присутній 100 учнів та 20 викладачів.


Додаткова інформація
  • Рядки, які починаються з // позначають однорядкові коментарі. Щоб написати багаторядковий коментар, укладайте рядка мітки /* та */.

    Щоб закоментувати інші коментарі, використовуйте/++/:

        /+
         // Однорядковий коментар
     
         /*
           Коментар, що займає
           кілька рядків
          */
     
          Блок коментаря, що включає в себе  коментарі
         +/
  • Більшість прогалин у вихідному коді не мають значення. Є гарною практикою писати довгі вирази на декількох рядках або додавати додаткові пробіли, щоб зробити код більш читабельним. Тим не менше, до тих пір, поки дотримуються правила синтаксису мови, програми можуть бути написані без будь-яких додаткових пробілів:

    import std.stdio;void main(){writeln("Важко читаемо!".);}
    Важко читати код, в якому стільки ж пропусків, скільки в цьому.


Вправи
  • Введіть числові символи, коли програма очікує цілочисельне значення і поспостерігайте, як програма працює некоректно.
    … рішенняКоли символи не можуть бути перетворені у бажаний тип, stdin переводиться в стан непридатне до використання. Наприклад, введення «abc», коли очікується int, зробить stdin непридатним до використання.


Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.