Приклад програми

 

Приклад програми, що виводить на екран привітання:

# include <stdio.h>

int main (void)

{printf ("Hello, World! \ N");

return 0;}

5. Основні керуючі конструкції мови С

Умовний оператор if ...else.

 

if (умова)

оператор1

else

оператор2

 

Якщо умова істинна, то виконуватися перший оператор, інакше другий. Якщо в умові відпрацьовують кілька операторів, то вони поміщаються фігурні дужки. Друга частина (else) може опускатися якщо нам не потрібно обробляти помилкове умова. Допускається вкладення умовних операторів. При порівнянні на рівність необхідно пам'ятати, що a = b пишеться як a == b (подвійне одно, інакше ми отримаємо прісваеніе, тобто a приклад значення рівне b). Інші операції порівняння: більше (>), менше (<), не дорівнює (!=), логічна операція І (&&), логічна операція АБО (||).

 

Приклад (оператор - пошук мінімального з двох чисел)

 

printf ("Мінімальна зі значень% i і% i одно", a, b);

int a = 1;

int b = 2;

if (a <b)

printf ("% d ", a);

else

printf ("% d ", b);

if (a == b)

printf (" (обидва числа однакові) ");

printf (" \ n ");

 

Ітераційний цикл- цикл керований лічильником.

 

for (ініціалізація; умова; операція)

{оператори}

 

Перший параметр ініціалізує лічильник, другий - умова при істинності якого виконуються оператори, третій - операція виконується перед новою итерацией.

 

Приклад (обчислення факторіала числа):

printf (" обчислення факторіала \ n ");

const int N = 5;

int i, f = 1;

for (i = 1; i <= N; i + +)

{f*= i;

printf ("% d! =% d \ n ", i,f);}

 

В якості операції в прикладі використовується постфіксній форма інтремірованія (збільшення змінної на 1). Цикл повторюється до тих пір, поки i менше або дорівнює N. Операція f *= i (прісваеніе з множенням) еквівалентна формі f = а * i.

 

Цикл з передумовою- цикл керований умовою.

 

while (умова)

{оператори}

 

Цикл виконується поки умова істинна (умова перевіряється на початку).

Приклад (обчислення суми чисел):

 

printf ("обчислення суми чисел \ n");

i = 0;

f = 0;

while (i <5)

{f+ = + + i;

printf ("S (% d) =% d \ n ", i,f);}

 

Операція f + = + + i еквівалентна двом операторам i++; f = f + i;

Цикл з постусловіем- цикл керований умовою.

 

do

{оператори}

while (умова)

 

Цикл виконується поки умова істинна (умова перевіряється в кінці, тобто тіло циклу випольняется принаймні один раз).

 

Приклад (обчислення квадратів);:

 

printf ("обчислення квадратів \ n");

i = 0;

do

{f= i * i;

printf ("% d ^ 2 =% d \ n", i, f);

i + +;}

while (f <25);

 

Оператор виборуswitch.

 

switch (вираз)

{case константа_1: оператори; break;

...

case константа_n: оператори; break;

default: оператори;

break;}

 

Оператор switch обчислює вираз і переходить до першого збігається значенням після case. Далі виконуються оператори цього блоку і за командою break відбувається вихід зі структури. Якщо ні одне зі значень не збігається з константами з case, то виконуються оператори блоку default. Відзначимо, що константи в case блоці визначаються на етапі компіляції, тому вони не можуть містити змінних і функцій.

 

Приклад.

 

Int a = 2, b = 5;

...

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

{switch(i)

{case0: c = a + b; break;

case 1: c = a - b; break;

case 2: c = a * b; break;

case 3: c = (float) a / b; break;

default: c = 0; break;}

printf ("Результат: i =% i, c =% f \ n", i,

c);}

 

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

 

Оператори break і continue.

Використання оператора break ми вже бачили на прикладі структури switch. Оператор break - це вихід з циклу чи конструкції switch.

Приклад (цикл по i від 0 до 4, але при i = 2 відбувається вихід з циклу):

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

{if(i == 2) break;

printf ("Індекс: i = % i \ n ", i);}

 

Оператор continue - перехід на кінець циклу (тобто пропуск всіх операторів від continue до кінця структури циклу).

Приклад (цикл по i від 0 до 4, але при i = 2 відбувається перехід на кінець циклу):

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

{if(i == 2) continue;

printf ("Індекс: i =% i \ n ", i);}

 

6. Індівідуальні завдання

 

1. Написати програму, яка виводить на екран трикутник із символів '*' виду:

*

**

***

****

Висота (довжина сторони) задається з клавіатури.

 

2. Написати програму, яка виводить на екран трикутник із символів '*' виду:

*

***

*****

*******

Висота задається з клавіатури.

3. Ввести з клавіатури матрицю A(5,5) і вектор X(5). Обчислити добуток матриці на вектор.

4. Ввести з клавіатури матрицю B(4,5). Знайти стовпець із максимальною сумою елементів.

5. Ввести з клавіатури два масиви по 10 елементів кожний. Знайти суму елементів масивів з однаковими індексами.

6. Для матриці визначити яких елементів більше: позитивних або негативних.

7. Для квадратної матриці знайти суму елементів, що перебуває вище головної діагоналі.

8. Ввести з клавіатури два масиви по 10 елементів кожний. Знайти суму елементів масивів зі зворотніми індексами.

9. Для матриці підрахувати кількість позитивних та негативних елементів.

10. Для квадратної матриці знайти суму елементів, що перебуває нижче головної діагоналі.

11. Для квадратної матриці знайти суму елементів, що перебуває на головної діагоналі.

12. Преобразовати квадратну матрицю, введену з клавіатури в матрицю з нулями на головній діагоналі.

13. Для матриці, введеної з клавіатури знайти суму всіх елементів.

14. Для матриці, введеної з клавіатури знайти суму всіх позитивних елементів.

15. Для матриці, введеної з клавіатури знайти суму всіх негативних елементів.

 

Лабораторна робота № 2. Автоматизація пакетних завдань

 

Мета:Оволодіння технологією розробки складних програм у системі UNIX. Знайомство з поняттям автоматизації компіляції. Оволодіння навичками багатомодульної компіляції та створення make файлів.

 

Завдання для самостійної підготовки:

Вивчити:

− принципи створення багатомодульної програми;

− призначення утіліти make;

− принципи побудови make файлу;

 

Методичні вказівки

 

1. Компіляція багатомодульною програми

Нехай програма prog складається з пари файлів коду main.c і supp.c й що у кожному з них файлу заголовків defs.h. Відповідно, для створення prog необхідно з пар (main.c defs.h) і (supp.c defs.h) створити об'єктні файли main.o і supp.o, а потім злінкувати їх у prog.

 

gcc-c main.c defs.h ---- main.o

gcc-c supp.c defs.h ---- supp.o

gcc-o prog main.о supp.о

 

Можна поєднати два етапи обробки - компіляцію і компонування - в один загальний етап за допомогою команди:

gcc-o prog main.с supp.с

У результаті отримали виконуваний файл prog.

 

2. Автоматизація пакетних завдань

MAKE - утиліта, яка автоматизує процес перетворення файлів з однієї форми в іншу і застосовувана для складання програмних проектів.

 

Принципи побудови make-файлу

Всю інформацію про проект make черпає з файлу Makefile, який зазвичай знаходиться в тому ж каталозі, що і вихідні файли проекту. При запуску програма make читає Makefile і, інтерпретуючи його вміст, робить необхідні дії. Файл з описом проекту являє собою текстовий файл, де описані відносини між файлами проекту, і дії, які необхідно виконати для його складання.

Найпростіший Makefile складається із синтаксичних конструкцій всього двох типів:правил та макроозначень.

 

У загальному вигляді правило виглядає так:

<m_1> <m_2> ... <m_n> : <r_1> <r_2> ... <r_n>

<команда_1>

<команда_2>

...

<команда_n>

Де m - мета , r – залежність.

Мета- це бажаний результат, спосіб досягнення якого описаний в правилі.

Опис мети складається з двох частин: заголовка і реалізації.

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

Ім'я мети може бути

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

progr: main.o mod1.o mod2.o

gcc –o progr main.o mod1.o mod2.o

- ім'ям деякого дії (псевдометаабо абтрактна). У такому випадку правило описує, яким чином здійснюється вказане діяння.

Clean:

rm *.o progr

Список залежностей - це якісь "вихідні дані", необхідні для досягнення зазначеної в правилі мети. Залежно від типу цілі залежність являє собою список файлів або імен дій. Для виконання мети файли повинні бути попередньо створені, а дії виконані.

Реалізація - це дії, які необхідно виконати для відновлення або досягнення мети. Всі команди починаються з обов'язкового символу табуляції.

 

Приклад Make-файла для компіляції програми prog:

 

prog: main.o supp.o

gcc -o prog main.o

main.o supp.o supp.o : defs.h

У наведеному прикладі можна помітити ряд особливостей: в імені другої мети вказані два файли і для цієї ж мети не вказана команда компіляції, крім того, ніде явно не вказана залежність об'єктних файлів від "*. c"-файлів. Справа в тому, що команда make має вбудовані правила для отримання файлів з певними суфіксами. Так, для цілі - об'єктного файлу (суфікс ". O") при виявленні відповідного файлу з суфіксом ". C", буде викликаний компілятор "сс-с" із зазначенням у параметрах цього ". C"-файла і всіх файлів - залежностей. Більш того, в цьому випадку явно не зазначені ". C"-файли make самостійно внесе до списку залежностей і буде реагувати їх зміну так само, як і для явно зазначених залежностей.

 

Макроозначення має вигляд "ЗМІННА = ЗНАЧЕННЯ".

ЗНАЧЕННЯ може бути довільної послідовністю символів, включаючи пробіли і звернення до значень уже визначених змінних.

Звернення до значення змінної виглядає як $ (ЗМІННА)

 

Приклад 1: (змінні можуть бути макросами або текстом)

var1 = one

var2 = $(var1) two

var1 = three

all:

@ echo $(var2)

Приклад 2:

OB = main.o supp.o

prog: $(OB)

cc -o prog $(OB)

$(OB): defs.h

Автоматичні змінні - це змінні зі спеціальними іменами, які "автоматично" приймають певні значення перед виконанням описаних у правилі команд. Автоматичні змінні можна використовувати для "спрощення" записи правил.

$@ - Ім'я мети оброблюваного правила

$< - Ім'я першої залежності оброблюваного правила

$^ - Список всіх залежностей оброблюваного правила

 

Таке, наприклад, правило:

progr: main.o mod1.o

main.o mod1.o mod2.ogccmod2.o-oprogr

 

з використанням автоматичних змінних можна записати наступним чином:

 

progr: main.o mod1.o mod2.o

gcc $^ -o $ @

 

Якщо мета старше об'єктних файлів, то ніяких дій проводиться не буде - make вважає, що все вже зроблено.

У разі створення об'єктних файлів $< - посилання на вихідні файли

.co:

gcc -c $<

Говорить про те, що об'єктні файли залежать від відповідних вихідних файлів. Кожна зміна файлу з вихідним текстом буде викликати його перекомпіляцію.

 

Приклад.

Розглянемо make-файл

progr: main.o mod1.o mod2.o

gcc $^ -o $ @

main.o: main.c

gcc -c $^

mod1.o: mod1.c

gcc -c $^

mod2.o : mod2.c

gcc -c $^

З використанням шаблонних правил, цей приклад можна переписати так:

progr: main.o mod1.o mod2.o

gcc $^ -o $@

.co:

gcc -c $^

Внесення додаткових рядків.

Тепер припустимо, що до проекту додався другий заголовний файл supp.h, який включається тільки в mod2.c. Тоді Makefile збільшиться ще на один рядок:

mod2.o: supp.h

Таким чином, один цільовий файл може вказуватися у кількох цілях. При цьому повний список залежностей для файлу буде складено зі списків залежностей всіх цілей, в яких він бере участь, однак створення файлу буде здійснюватися тільки один раз.

 

Додаткові можливості.

Крім компіляції, Makefile може використовуватися і для виконання інших допоміжних дій, безпосередньо не пов'язаних зі створенням будь-яких файлів. До таких дій відноситься очищення проекту від всіх результатів компіляції, або виклик процедури інсталяції проекту в системі.

Для виконання подібних дій у Makefile можуть бути вказані додаткові цілі, звернення до яких буде здійснюватися зазначенням їхніх імен аргументом виклику make (наприклад, "make install") . Подібні допоміжні цілі носять назву фальшивих,що пов'язано з відсутністю в проекті файлів, відповідних їх іменами.

Команда make install інсталює програму в систему, поміщаючи її виконуваний файл у будь-який каталог.