Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Мова програмування С.docx
Скачиваний:
3
Добавлен:
01.05.2025
Размер:
489.95 Кб
Скачать

2.4 Оголошення

Усі змінні потрібно оголосити до їхнього використання, хоч деякі оголошення можна зробити непрямо, через зміст. Оголошення вказує тип і містить список з однієї або більше змінних цього типу, як, наприклад

int lower, upper, step;

char c, line[1000];

Змінні можна розподілити поміж оголошень у будь-який спосіб; списки вище так само можна було б записати як

int lower;

int upper;

int step;

char c;

char line[1000];

Остання форма забирає більше місця, але вигідна тим, що дозволяє додати коментар до кожного оголошення, для пізніших змін.

Змінну можна також ініціювати (надати їй початкового значення) під час її оголошення. Якщо за назвою слідує знак рівності та вираз, цей вираз служитиме ініціалізатором, як, скажімо

char esc = '\\';

int i = 0;

int limit = MAXLINE+1;

float eps = 1.0e-5;

Якщо змінна не є автоматичною, ініціалізація відбудеться тільки один раз, за задумом — до того як програма почне своє виконання, але ініціалізатор має бути сталим виразом. Явно ініційована автоматична змінна, започатковується кожного разу при входженні у функцію або блок коду де вона знаходиться; ініціалізатор може складатися з будь-якого виразу. Зовнішні та статичні змінні, поза вибором, ініціалізуються до нуля. Автоматичні змінні, які не мають явного ініціалізатора, отримають невизначене значення (тобто непотріб).

Для вказівки того, що значення змінної не змінюватиметься, до оголошення можна додати класифікатор const. У випадку масивів, класифікатор const вказує на те, що елементи масиву залишатимуться незмінними.

const double e = 2.71828182845905;

const char msg[] = "warning: ";

Оголошення з const можуть також вживатися з масивами в якості аргументів, щоб вказати на те, що функція, скажімо, не змінює масиву:

int strlen(const char[]);

Якщо відбудеться спроба змінити значення змінної типу const, результат такої дії залежатиме від реалізації.

2.5 Арифметичні операції

Арифметичними операми з двома операндами є +, -, *, / і оператор коефіцієнту %. Поділ цілих відкидає дробову частину. Вираз

x % y

повертає залишок поділу x на y, і нуль, якщо ділення відбудеться без залишку. Наприклад, рік буде високосним, якщо він кратний 4, але не 100, за винятком того, що роки кратні 400 — теж високосні. Таким чином

if ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)

printf("%d is a leap year\n", year);

else

printf("%d is not a leap year\n", year);

Оператор % неможливо застосувати із float та double. Напрямок округлення у випадку / і знак результату % є машинозалежним для від'ємних чисел, так само як дії у випадку втрати значності або переповнення. Оператори + та - рівні за пріоритетом, але мають менший пріоритет ніж *, / і %, які в свою чергу, поступаються унарним + та -. Арифметичні оператори діють з ліва на право.

Таблиця 2.1, у кінці цього розділу, підводить підсумок пріоритетів і асоціативності (спрягання) всіх операторів.

2.6 Реляційні та логічні оператори

Реляційними операторами є

> >= < <=

Вони всі мають однаковий пріоритет. Трохи нижче за пріоритетом знаходяться оператори рівності:

== !=

Реляційні оператори наділені меншим пріоритетом за арифметичні, тож вираз на зразок i < lim-1 розглядатиметься як i < (lim-1), як і очікувалось.

Цікавішими є логічні оператори && та ||. Вирази, поєднані && або ||, оцінюються з ліва на право, і їхня оцінка закінчується, як тільки виявлено істинність чи хибність результату. Більшість програм C покладаються на ці властивості. Ось, наприклад, цикл функції вводу, яку ми написали у Розділі 1:

for (i=0; i < lim-1 && (c=getchar()) != '\n' && c != EOF; ++i)

s[i] = c;

Перед тим як прочитати новий знак, необхідно перевірити, чи є місце для його збереження в масиві s, тож треба спочатку дізнатися, чи i < lim-1. Якщо ця перевірка зазнає невдачі, нам не слід продовжувати далі, і читати наступний знак.

Так само, було би недоцільно перевіряти c на предмет EOF (кінця файла), якщо до цього не викликано getchar; саме тому виклик і присвоєння мають відбутися до перевірки символу, збереженого в c.

Пріоритет && є більшим за ||, але обидва поступаються релятивним операторам і операторам рівності, тож вирази на зразок

i < lim-1 && (c=getchar()) != '\n' && c != EOF

не вимагають додаткових дужок. Але оскільки пріоритет != переважає оператор присвоєння =, дужки обов'язкові у випадку

(c=getchar()) != '\n'

для того, щоб добитися бажаного результату - спочатку, присвоєння значення c, а потім, порівняння його з '\n'.

За визначенням, числове значення релятивного або логічного виразу дорівнює 1, якщо співвідношення істинне, і 0 — якщо хибне.

Унарний оператор заперечення ! перетворює ненульовий операнд на 0 (нуль) і, навпаки, нульовий операнд на 1 (одиницю). Поширеним є застосуванням ! в конструкціях на зразок

if (!valid)

замість

if (valid == 0)

Важко узагальнити, яка з цих форм є кращою. Конструкції на кшталт !valid легко читаються («if not valid» — «якщо не дійсне»), але складніші вирази буває важко зрозуміти.

Вправа 2-2. Напишіть цикл, еквівалентний наведеному вище, але без використання && або ||.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]