Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Бичков - Основи сучасного програмування.doc
Скачиваний:
76
Добавлен:
07.03.2016
Размер:
2.67 Mб
Скачать

3.5.8. Оператор goto

Синтаксис:

goto<мітка>

<мітка>:<оператор>

Передає керування на мітку. Міткою може бути будь-який ідентифікатор. Якщо потрібно вийти з кількох циклів за великого рівня вкладеності (більше 2), єдина можливість – це оператор goto. Можна ввійти за допомогою goto у блок, тіло циклу, оператор switch. Наприклад:

for(i=0;i<100;i++)

for(j=0;j<100;j++)

for(k=0;k<100;k++)

If(error(I,j,k)) goto exit;

exit:;

У цьому фрагменті у випадку, коли значення деякої функції error виявиться ненульовим, переривається виконання всіх циклів, і керування передається на мітку exit, за якою стоїть порожній оператор.

3.5.9. Оператор return

Синтаксис: return<константний вираз> Повертає керування у викличну функцію. Розглянемо функції main():

main()

{

… …

return 0;}

Функція main() за умовчанням має повертати значення типу int. Тому в тілі цієї функції міститься оператор return. Загалом, будь-яка функція, що має тип результату, відмінний від void, має містити оператор return. Значення, що повертається оператором return, на практиці часто використовується для видачі певної інформації. Наприклад, якщо функція відпрацювала нормально, то можна повернути нуль.

3.6. Директиви препроцесору та вказівки компілятору

Препроцесор – це програма, яка здійснює обробку тексту на нульовій фазі компіляції. Компілятор мови С сам викликає препроцесор, хоча він може бути викликаний й автономно. Директиви препроцесору широко використовуються для підключення файлів, керування процесом компіляції програми, унеможливлення недопустимих перевизначень тощо. Цей механізм розроблений з метою зменшення залежності С-програми від архітектури комп'ютера та версії операційної системи. Використовуються такі директиви препроцесору:

#define, #include, #if, #elif, #else, #endif, #ifdef, #ifndef, #error, #line

3.6.1. Директива препроцесору #define

Директива #define використовується для заміни ключових слів, констант, операторів осмисленими ідентифікаторами. Існують два види директиви #define:

1. Макровизначення:

#define<ідентифікатор1><ідентифікатор2>

За наявності відповідної директиви відбувається тривіальна текстова заміна першого ідентифікатора другим у випадку, коли перший становить окрему лексему. Після визначення деякого ідентифікатора він знову може входити до інших директив #define:

#define WIDTH 180

#define LENGS (WIDTH+10)

Макровизначення й макропідстановки прийнято записувати у верхньому регістрі. Після інтерпретації однієї макропідстановки препроцесор переходить послідовно до наступної інтерпретації. Це приводить до того, що директива #define x x не зациклює препроцесор. Директива #define може бути розміщена у будь-якій частині програми. Область дії відповідної директиви – від точки визначення до кінця файла. У директиві #define допускається перенесення текстового рядка:

#define якщо студен\

ти РЕГІ не будуть уважно слухати викладача на парі,\

то вони можуть не зрозуміти важливої деталі.

За допомогою #define можна керувати регістровими змінними:

#define REG1 register

#define REG2 register

#define REG3

REG1 int i;

REG2 int j;

REG3 int k;

Тут REG3 компілятор ігнорує.

2. Макроси (макропідстановки)

#define<ідентифікатор1>(<список параметрів>)<текст>

Текст у цьому випадку може містити ідентифікатори, розташовані у списку параметрів. Наприклад:

#define ADD(x,y)((x)+(y));

#define MAX(x,y)((x)>(y))?(x):(y)

int i;

i=ADD(5,4)*3//це еквівалентно ((5)+(4))*3

i=ADD(b-3,6)*c//це еквівалентно ((b-3)+(6))*c

Визначимо функцію ADD в описаному вище фрагменті так:

#define ADD(x,y)x+y

У відповідному рядку отримаємо 5 + 4 * 3, тобто за відсутності дужок можна не досягти бажаного результату внаслідок пріоритету операцій. Отже, макропідстановки (макроси) у деякому розумінні є аналогами функцій, але між ними існує суттєва відмінність. Оскільки макроси – це звичайні текстові підстановки, то в місце їх виклику вставляється відповідний текст, тому вони працюють швидше за функції. Адже в точці виклику функції відбувається генерація виклику, засилання формальних параметрів (фактичних), повернення у точку виклику після роботи функції – усі ці дії вимагають часу. Однак використання макросів значно збільшує текст самої програми.

З використанням директиви #define можна здійснити конкатенацію текстових елементів, тобто утворити нові ідентифікатори. У директиві #define конкатенація здійснюється синтаксично з використанням ##:

#define concat(x,y)x##y

concat (x,3)=5;//еквівалентно x3=5

Наприклад:

#define AB'стандарт'

#define A'відхилення від'

#define B'стандарту'

char*s=concat(A,B);

printf("s=%s',s);

У цьому фрагменті надрукується "відхилення від стандарту". У макросах спочатку відбувається підстановка замість формальних параметрів їх фактичних значень, а потім виконується послідовність дій, описаних у макросі. Тому надрукується не 'стандарт', а "відхилення від стандарту".

Використання формального параметра, перед яким стоїть значок #<параметр>, приводить до його перетворення на текстовий рядок 'параметр'. Припустимо, що нам необхідно вивести на екран значення деякого параметра макросу у формі "параметр"=<значення>. Наведемо фрагмент програми:

#define write(x)

printf(#x'=%d\n',x)

int a=5,b=3,c=2;

write(a); /*надрукується a=5*/

write(b); /*надрукується b=3*/

write(c); /*надрукується c=2*/

Спочатку конструкція #x перетворюється на текстовий рядок #x->'x', послідовність двох текстових рядків у функції printf сприймається як один:

printf("x"=%d\n',x)

printf("x=%d\n',x)

3.6.2. Директива #undef [<ім’я>]

Директива #undef [<ім'я>] відмінює дію макровизначення чи мак­ропідстановки, ім'я може бути відсутнім. Така директива не є помил­кою у більшості компіляторів. Не вважається помилкою також використання імені, яке раніше не було визначене. У випадку використання макросів параметри можуть бути опущені. Наприклад:

#define ADD(x,y)(x)+(y)

#define width 80

main()

{printf ("проба\n');

int i=ADD(5,4);

printf("i=%d\n',i);

#undef ADD

{float i=ADD(3.5,4);

}}