МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ
Національний університет «Львівська політехніка»
Кафедра «Телекомунікації»
Методичні вказівки до лабораторних робіт з дисципліни
«Інформатика телекомунікаційних систем та мереж, ч.IІ»
для студентів базового напряму 6.0924
«Телекомунікації»
Затверджено
на засіданні кафедри «Телекомунікації»
Національного університету
«Львівська політехніка»,
протокол №___ від______2009 р.
Львів 2009
№1
«Загальна структура програми мовою С. Вивчення та використання функцій уведення та виведення даних.
МЕТА РОБОТИ: дослідити структуру програми на мові С і використання функцій уведення та виведення даних.
Попередні відомості
Програма на мові С складається з однієї або більше функцій і хоча б одна з них повинна називатися main( ). Опис функції складається з заголовку та тіла. Заголовок у свою чергу містить директиви препроцесора типу #include і.т.д, що під’єднують бібліотечні файли та специфікують перетворення тексту програми перед компіляцією; а також ім’я функції. Ознакою імені функції служать круглі дужки. Тіло функції поміщається в фігурні дужки та є набором операторів (команд), кожен із яких закінчується символом “ ; “- крапка з комою. Елементом програми є коментар - частина тексту програми для пояснення окремих операторів, що входять до її складу. Коментар не впливає на виконання операторів і записується таким чином: // текст коментарю або так: /* текст коментарю*/ . В першому випадку коментар має бути єдиним у рядку або в кінці рядка. Другий спосіб дозволяє записувати коментар будь-де в тексті програми не розриваючи лексем.
Оголошення змінної задає ім’я та атрибути змінної. Визначення змінної крім задання імені та її атрибутів приводить до виділення для неї пам’яті.
Програма може містити довільне число директив, вказівок компілятору, оголошень та визначень. Їх синтаксис розглядатиметься нижче. Порядок появи цих елементів у програмі є важливий. Загальна структура програми мовою С має вигляд.
Заголовок
#include < назва бібліотечного файлу> // директива препроцесора 1
......
#include < назва бібліотечного файлу> // директива препроцесора N
......... // інші директиви препроцесора
main ( )
Тіло
{
<оголошення змінних>
< оператор 1 >
...........
< оператор N >
}
В наступному прикладі приведена проста програма.
#include <stdio.h> // ця інструкція препроцесора вказує компілятору, що необхідно під’єднати
// інформацію, що міститься в файлі stdio.h
main() // визначення головної функції
{
int z; // оголошення змінних
int w;
int x=1; // присвоєння змінним їх значеня
int y=2;
z=y+x; // виконувані оператори
w=y-x;
}
У приведеній програмі значення змінних вводяться за допомогою операції присвоєння, що є не зовсім зручним, особливо коли змінних багато. Таке введення даних також вимагає наявності початкового тексту програми та його компіляції при кожній їх зміні. Результат обчислення (змінні z i w) взагалі не візуалізується. Для здійснення цього необхідно застосувати засоби взаємодії з програмою – функції printf() і scanf(). Це не єдині функції, якими можна користуватися для введення і виведення даних з допомогою програм на мові С, але вони найбільш універсальні. Вказані функції не входять в опис мови С і реалізація операцій уведення-виведення покладається на розробників компілятора, що дає можливість більш ефективно організовувати їх на конкретних машинах.
Функції printf() і scanf() працюють подібно - кожна використовує “керуючий рядок” і “список аргументів”.
Функція printf(). Інструкції, що передаються функції printf(), якщо необхідно надрукувати деяку змінну, залежать від типу змінної. Наприклад, при виведенні на друк цілого числа застосовується формат %d, а при виведенні символа %с. В таблиці 1 перечислені всі формати, що вказуються при звертанні до функції printf (). Кожному формату відповідає тип внведеної з їх допомогою інформації. Слід зазначити, що останні чотири формати застосовуються досить рідко.
Таблиця 1.
Формат
Тип інформації, що виводиться
%d
Десяткове ціле число
%c
Один символ
%s
Рядок символів
%e
Число з плаваючою точкою, експонентний запис
%f
Число з плаваючою точкою, десятковий запис
%g
Використовується замість записів %f або %e, якщо він коротший.
%u
Десяткове ціле число без знаку
%o
Вісімкове ціле число без знаку
%x
Шістнадцяткове ціле число без знаку
Використання функції printf ().
/* друк різноманітної інформації*/
#define PI 3.14159
# include <stdio.h>
main()
{
int a =5;
float b=23. 5;
int c=31000;
printf(“ %d метрів тканини коштувало %f гривень.\n”, a,b);
printf(“Значення числа pi рівне %f.\n”, PI);
printf(“ IBM сумісні комп’ютери набули широкого розповсюдження.\n)”;
printf(“ %c%d\n”, ‘$’, c);
}
Результат роботи програми:
5 метрів тканини коштувало 23.500000 гривень.
Значення числа pi рівне 3.14159.
IBM сумісні комп’ютери набули широкого розповсюдження.
$31000
Формат, що вказується при зверненні до функції printf() має наступний вигляд:
Printf(Керуючий рядок, аргумент1, аргумент2, ....,);
Аргумент1, аргумент2 і т.д. – це друковані параметри, які можуть бути змінними, константами або навіть виразами, що обчислюються спочатку, перед виведенням на друк.
Керуючий рядок – рядок символів, що показує як повинні бути надруковані параметри. Наприклад у операторі printf(“ %d метрів тканини коштувало %f гривень.\n”, a,c); керуючим рядком служить фраза в лапках (враховуючи попередні зауваження, це – рядок символів), а а і b аргументи або в даному випадку значення двох змінних.
У рядку програми printf(“Значення числа pi рівне %f.\n”, PI); список аргументів містить тільки один елемент – символічну константу PI.
В керуючому рядку міститься інформація двох різних видів: символи, що друкуються текстуально; ідентифікатори даних, що називаються також “специфікаціями перетворення”.
Кожному аргументу із списку, що слідує за керуючим рядком, повинна відповідати одна специфікація перетворення.
Якщо необхідно надрукувати яку-небудь фразу, то необхідності використовувати спефікацію перетворення немає. Тому такий оператор є коректний:
printf(“ IBM сумісні комп’ютери набули широкого розповсюдження.\n)”;
Зауважимо, що в операторі printf(“ %c%d\n”, ‘$’, c); перший аргумент із друкованого списку є символьною константою, а не змінною.
В функції printf() є можливість дещо розширити основне визначення специфікації перетворення, помістивши модифікатори між знаком % і символом, що визначає тип перетворення. В таблиці 2 подано список цих символів. При використанні одночасно декількох модифікаторів вони повинні бути вказані в тому порядку, в якому перечислені в таблиці.
Модифікатор
Значення
––
Аргумент буде друкуватися з лівої позиції заданої ширини. Друк аргументів закінчується в правій крайній позиції поля.
Приклад: %–10d
Рядок цифр
Задає мінімальну ширину поля. Більше поле буде використовуватися, якщо друковане число або рядок не вміщуються в початковому полі.
Приклад: %4d
Рядок цифр
Визначає точність: для типів даних із плаваючою точкою - число друкованих цифр праворуч від десяткової точки; для символьних рядків максимальне число друкованих символів.
Приклад: %4.21 (дві десяткові цифри для поля шириною в чотири символи)
L
Відповідний елемент даних має тип long, а не int.
Приклад: %ld
Розглянемо приклади роботи модифікаторів ширини поля на друк цілого числа.
main()
{
printf(“/%d/n”, 557);
printf(“/%2d/n”, 557);
printf(“/%10d/n”, 557);
printf(“/%–10d/n”, 557);
}
Програма надрукує наступне:
/557/
/557/
/ 557/
/557 /
Розглянемо приклади форматів, що відповідають даним з плаваючою точкою.
main()
{
printf(“/%f/\n”, 6543,21);
printf(“/%e/\n”, 6543,21);
printf(“/%4,2f/\n”, 6543,21);
printf(“/%3.1f/\n”, 6543,21);
printf(“/%10.3f/\n”, 6543,21);
printf(“/%10.3e/\n”, 6543,21);
}
Програма надрукує наступне:
/6543.210000/
/6.543210е+03/
/6543.21/
/6543.2/
/ 6543.210/
/ 6.543е+03/
Розглянемо застосування функції printf() для роботи із рядками.
#define riadok “Чудова погода”
main()
{
printf(“/%2s/\n”, riadok);
printf(“/%15.s/\n”, riadok);
printf(“/%15.5s/\n”, riadok);
printf(“/%–15.5s/\n”, riadok);
}
Програма надрукує наступне:
/ Чудова погода/
/ /
/ Чудова /
/ Чудова /
Розглянемо застосування функції printf() для перетворення даних.
main()
{
printf(“%d\n”, 557);
printf(“%o\n”, 557);
printf(“%x\n”, 557);
printf(“%d\n”, –557);
printf(“%u\n”, –557);
}
Програма надрукує наступне:
557
1055
22d
–557
64979
Розглянемо застосування функції printf() для знаходження коду символів таблиці ASCII. Оператор printf(“%c%d\n”, ‘B’,’B’); надрукує наступне B66.
B – це буква, 66 – десятковий код ASCII символа B. Для отримання вісімкового коду ASCII символя B слід застосувати специфікацію %o, a шістнадцяткового %x.
Функція scanf(). Подібно до функції printf() для функції scanf() вказуються керуючий рядок і слідуючий за нею список аргументів. Основна відмінність цих двох функцій полягає в особливостях даного списку. Функція printf() використовує імена змінних, константи та вирази, тоді як функція scanf() – тільки вказівники на змінні. Якщо необхідно ввести деяке значення та присвоїти його змінній одного з основних типів, то перед іменем змінної необхідно написати символ &. Якщо необхідно ввести значення рядкової змінної, використовувати символ & необов”язково.
Робота функції. Виконувана програма зупиняється і система переходить у режим очікування введення даного. В цей час монітор комп’ютера темний і миготить курсор. Користувач набирає на клавіатурі значення змінної та натискає клавішу вводу Enter. В результаті виконання цієї функції змінній буде присвоєно певне значення, що введене з клавіатури. Для кращого розуміння функціонування створюваної програми перед функцієї введення даних варто застосовувати функцію виведення на монітор, зокрема printf().
Розглянемо програму, що демонструє використання фунцій printf() і scanf().
#include<stdio.h>
#include<conio.h>
main()
{
int vik;
char name[30];
clrscr();
printf("Vash vik?\n");
scanf("%d",&vik);
printf("Uvedit vashe imja\n");
scanf("%s",name);
printf("Pryvit %s jakomu %d rokiv",name,vik);
}
Функція scanf() використовує практично той самий набір символів специфікації перетворення , що й функція printf(). Головні відмінності для функції scanf() наступні:
Відсутня специфікація %g.
Cпецифікації %f I %e еквівалентні. Обидві специфікації допускають наявність (або відсутність) знаку, рядка цифр із десятковою точкою або без неї і поля показника степені.
Для читання цілих чисел типу short застосовується специфікація %h.
Функції getchar() і putchar()
Функція getchar() отримує один символ, що поступає з пульта термінала і передає його програмі, що виконується в даний момент. Функція putchar() отримує один символ, що поступає з програми та пересилає його для виведення на екран.
Функція getchar() аргументів не має, тобто при її виклику в круглих дужках не поміщається жодна величина. Вона отримує черговий поступаючий символ і сама повертає його значення виконуваній програмі.
Функція putchar() має один аргумент. При її виклику необхідно в дужках вказати символ, який необхідно вивести на друк. Аргументом може бути одиночний символ (включаючи знаки, що представляються керуючими послідовностями, змінна або функція значенням якої є один символ. Зразки звертання до фунції putchar():
putchar(‘S’); – символьна константа, що поміщена в апострофи
putchar(‘\n’);
putchar(‘\007’);
putchar(ch); – змінна типу char
putchar(getchar());
Наступна програма демонструє виведення на друк групи символів із припиненням роботи програми при введенні певного символу.
#include<stdio.h>
#include<conio.h>
#define STOP '*'
main()
{
char ch;
clrscr();
ch=getchar();
m1: if( ch !=STOP)
{
putchar(ch);
ch=getchar(); goto m1; } }
ЗАВДАННЯ.
1. Виконати усі приклади, що наведені в теоретичних відомостях.
2. У звіті зазаначити формати, що використовуються функціями printf() і scanf().
3. Створиит програму, в якій задати числа, що оголошені як типи int, float, char, long та вивчити вплив модифікаторів специфікації перетворення для функції printf().
Надрукувати в рядок 10 будь-яких символів таблиці ASCII та відповідні їм коди в десятковій, вісімковій, шістнадцятковій системах.
Створити програму для розв’язання задачі купівлі товарів за формулою - вартість купівлі дорівнює: ціна товару помножена кількість. Знайти суму купівлі при номенклатурі товарів не менше 5. Вхідні дані задавати: а). під час оголошення змінних, б). введенням із клавіатури використовуючи функцію scanf(). Результати оформити у вигляді таблиці.
Створити програму обчислення довжини кола та площі круга за радіусом, який задавати введеням із клавіатури.
Створити програму обчислення коренів квадратного рівняння. Задачу виконати у вигляді діалогу з уведенням набору коефіцієнтів за допомогою клавіатури.
Модифікувати програму виведення на друк групи символів із застосуванням функцій getchar() і putchar() так, щоб символом припиненням роботи програми при уведенні був звуковий сигнал - функція sound(частота).
Обчислити периметр трикутника, його площу та радіус вписаного кола за заданими координатами його вершин А(1; 1), B(2k; 2k-1), C(-2k; k+2), де к – номер варіанта.
Формули для обчислення:
відстань між точками :
;
півпериметр трикутника: , де а, b, c сторони трикутника;
площа трикутника: ;
радіус вписаного кола:
Контрольні запитання.
Структура програми на мови С.
Ідеологія організації операцій уведення-виведення в мові С.
Синтаксис функцій printf() і scanf().
Основні типи форматів при звертанні до функцій printf() і scanf().
Модифікатори форматів при звертанні до функцій printf() і scanf().
Відмінності при застосуванні функцій printf() і scanf().
Застосування функцій getchar() і putchar().
№2
«Арифметичні операції та вирази мови С».
МЕТА РОБОТИ: Навчитися принципам створення математичних виразів при складанні програм для виконання обчислень за допомогою різних операцій мови програмування С.
Попередні відомості.
Мова С була розроблена в процесі створення операційної системи UNIX, тому можна зрозуміти, які принципові можливості в ній реалізовані: це максимальна гнучкість при діалоговому режимі роботи комп’ютера, представлення повідомлень системи і користувача в максимально простій і зрозумілій формі і, водночас, спроможність вибору адекватної реакції в найскладніших ситуаціях. Мова Сі поєднує в собі можливості прямої адресації і побітових операцій, як в Ассемблері, з використанням великої кількості (декілька сотен) функцій найвищого рівня. При використанні бібліотеки графічних функцій мова С отримала практично необмежені можливості для розробки діалогових програмних засобів.
Проте, мова С має суттєвий недолік з точки зору потреб розробки радіотехнічних задач: тут недостатньо розвинені операції арифметики, зокрема, повністю відсутня комплексна арифметика, і ії імітація призводить до генерування недостаньо ефективних кодів, що значно збільшує потреби часу при проведенні значних за обсягом математичних обчислень. Фірма Microsoft розробила власну версію мови С з інтерфейсом подібним до мови ФОРТРАН, найбільш пристосованою для математичних розрахунків і генеруючою найефективніші машинні коди. Паралельно на фірмі Borland велась розробка іншої версії мови С, перші варіанти якої мали назву “TurboC", а пізніші - "Borland C", "C++", причому в версіях "C++" комплексну арифметику реалізують за допомогою класу об’єкта.
Сервісна оболонка мови C призначена для розробки та відладки програм і включає в себе засоби роботи з файлами, їх редагування, запуску виконуваних файлів, а також різноманітні режими компіляції і збірки виконуваного модуля, розвинуті засоби відлагоджування програми - детальну діагностику помилок, можливість виконання по кроках з переглядом проміжних результатів, можливість просліджувати вміст певних змінних тощо.
Як відомо, розробка програми на мові С проводиться в декілька етапів: створення вихідного файлу, який записано за правилами мови С, його компіляція в об’єктний код за допомогою компілятора C, збірка об’єктних модулів і створення виконуваного файлу за допомогою програми LINK, відладка виконуваної програми шляхом дослідження її роботи на певних кроках (за допомогою опцій покрокового виконання). При цьому, як правило, необхідно декілька проходжень усіх етапів з редагуванням вихідного тексту.
Оскільки на персональному комп'ютері прийнята файлова система, на кожному етапі розробки сворюється відповідний файл:
name.c - вихідний текст;
name.prj - вихідний файл проекту;
name.obj - об'єктний код програмного модуля;
name.exe - виконуваний файл.
Слід розрізняти ім'я файлу та ім'я програмної одиниці. Оскільки файл - це просто поіменована область пам’яті на диску, в ньому може бути записана довільна інформація, в тому числі і програма. В мові С розрізняється головна програмна одиниця, з якої обов’язково починається кожна програма, вона називається main, включає до себе послідовність виконуваних операторів та може містити звертання до стандартних функцій та функцій користувача, визначених окремо. Кожна функція ідентифікується певним іменем, а її вихідний текст (якщо потрібна його компіляція) може бути розміщений як в окремому файлі, так і в тому ж файлі, що містить main-програму. Якщо всі програмні одиниці (main-програма та всі включені до неї функції) розміщені в одному вихідному файлі, компілятору достатньо вказати ім’я цього файлу. Якщо ж які-небудь частини програми розміщені в окремих файлах, використовується файл проекту для того, щоб повідомити компілятору повний список файлів, що підлягають компіляції (знову ж таки, кожен з цих файлів може містити вихідний текст більше, ніж однієї програмної одиниці). Вибір розміщення програмних одиниць у файлах проводиться як з міркувань зручності, так і з метою підвищення ефективності роботи програми. На початковому етапі вивчення програмування зручніше зупинитися на розміщенні main-програми та визначень включених до неї функцій (їх вихідних текстів) в одному файлі.
Компілятор створює об’єктний код, як правило, з нерозв’язаними зовнішними зв’язками (якщо в програмі є звертання до стандартних або раніше створених функцій). Програма LINK відповідає за збірку всіх об’єктних модулів, що використовуються в даній програмі, розв’язує зовнішні зв’язки, створює машинний код програми в цілому, тобто модуль, готовий до виконання, і записує його в файл з розширенням ".exe". На етапі збірки можливе підключення файлів, які містять об'єктні коди (мають розширення ".obj") з файлу проекту програми.
Можливості роботи на різних етапах відладки програми відображені в лінійці головного меню:
FILE - операції з файлами;
EDIT - вікно редагування вихідного тексту;
RUN - режими запуску виконуваних модулів;
COMPILE - режими компіляції вихідних модулів;
PROJECT - робота з файлом проекту;
OPTIONS - режими роботи і оточення оболонки;
DEBUG - режими відлагоджування виконуваної програми;
BREAK/WATCH - вставка примусових зупинок у виконанні програми,
визначення біжучих значень змінних.
Елементарною коміркою машинної пам’яті є біт. Біт – це елемент інформації, який може приймати значення 1 або 0. Фізично це означає наявність або відсутність електричного струму в певній ділянці електричного кола. Такий спосіб представлення елементу інформації пристосований для двійкової системи числення, яка використовується в ЕОМ. Група з восьми біт утворює байт. В одному байті можна записати беззнакове ціле число від 0 до 255 (256 - восьмий степінь числа 2) або знакове від 0 до 127. Звичайно одного байту недостатньо для запису більш складних даних, тому з двох (або чотирьох) байт утворюється машинне слово - вектор бітів, який розглядається апаратною частиною ЕОМ як єдине ціле. Число бітів у слові називається довжиною слова, залежить від апаратної реалізації комп’ютера і, як правило, буває довжиною 16 або 32 біти. Пам’ять обчислювальної машини поділяється логічно на слова. Слово має довжину, достатню для роміщення в ньому команди або цілого числа.
Всі дані, якими оперує мова С, підрозділяються на типи. Кожен тип даних має свій спосіб запису в пам’ яті ЕОМ, і, отже, займає чітко визначену ділянку. Компілятор мови С вимагає попереднього визначення типів абсолютно всіх даних, які використовуються в програмі, для того, щоб визначити спосіб і місце розміщення їх у пам’яті. При не дотриманні цих вимог робота компілятора припиняється.
Коли в програмі застосовуються ідентифікатори змінних величин, перед їх використанням обов'язково повинний бути опис типу кожної змінної, наприклад:
char ch;
int count = 1;
char* name = "Bob";
float f;
double df[20];
Дані розрізняються числові та текстові. Згадане вище однобайтне представлення цілого числа може бути використане як за прямим призначенням, так і для ідентифікації коду символа текстових даних. Існують стандартні (ASCII, а ткож декілька альтернативних) таблиці символів, які містять 256 цілих кодів, що відповідають найбільш поширеним текстовим символам. Можна вважати, що текстові дані представляються в пам'яті посимвольно послідовністю цілих однобайтових чисел. Таким чином, в мові "Сі" визначаються дані типу «char», які мають довжину 1 байт і можуть містити беззнакове ціле число від 0 до 255 (або від 0 до 127 зі знаком) або символьний код з таблиці..
Більшість цілих чисел в залежності від своєї величини та від апаратної реалізації ЕОМ можуть мати тип:
char - 1 байт; (символьний);
int - 2 байти;
long int - 4 байти.
Беззнакові цілі представляються модифікаціями типів «unsigned».:
unsigned char;
unsigned short int;
unsigned int;
unsigned long int.
Причиною того, що в мові С існує декілька цілих типів даних, є спроба надати можливість скористатися характерними особливостями апаратного забезпечення. На багатьох комп’ютерах між різновидами основних типів існують великі розбіжності в необхідній пам’яті, часу доступу до пам'яті та часу обчислень. Знаючи ці особливості, можна вибирти найбільш ефективний тип для певної змінної.
Для представлення чисел з плаваючою точкою існують два типи:
float - займають 4 байти;
double - 8 байт.
Число з плаваючою точкою кодується як знак, мантиса і ступінь. На кожну з цих частин виділяється певна кількість біт (в залежності від апаратної реалізації). Для підвищення точності обчислень використовується тип «double». Всі константи розглядаються як числа з подвійною точністю, всі математичні операції над нецілими числами виконуються з подвійною точністю, автоматично відбувається перетворення до вищого типу операндів, якщо вони мають різні типи, після чого здійснюється перетворення до типу, що оголошений для результуючої змінної.
В мові С існує спеціальний оператор «sizeof» для знаходження розміру об’єкта або певного типу. Це дає можливість для конкретної ЕОМ шляхом звертання з’ясувати точні розміри (в байтах), що займають числа якогось типу:
sizeof(int), sizeof(char), sizeof(double).
Програмісту надається можливість здійснювати примусове, пряме перетворення типів шляхом запису ідентифікатора типу перед іменем змінної, яка перетворюється, наприклад:
(float) a;
(double) f;
(int) f;
float r = float(1);
Крім того, основні типи можна довільно комбінувати в присвоєннях та виразах. При цьому здійснюється неявне перетворення типів за певними правилами, значення перетворюються так, щоб не було втрати інформації.
Їснують випадки, в яких інформація може втрачатися або спотворюватися, наприклад, при присвоєнні значення змінної одного типу змінній другого типу, яке представлене меншою кількістю біт:
int i1 = 256+255;
char ch = i1; // ch == 255, більшого не буває!
int i2 = ch; // i2 == ?
В мові С існують декілька неосновних типів даних:
* - вказівники;
& - посилання;
[] - масив (вектор);
() - функція;
struct - структура;
union - об'єднання;
enum - перелік,
а також необмежена кількість похідних типів, утворених їх комбінаціями (наприклад, широко використовуються масиви вказівників, масиви структур, вказівники на функції і т.ін.).
Арифметичні операції над числами в мові С записуються за синтаксисом, що звичний для всіх. Прте слід пам’ятати, що існує погодження про пріоритет виконання арифметичних операцій. За пріоритетом можна виділити такі групи (всередині груп пріоритет однаковий, кожна подальша група має нижчий пріоритет):
___________________________________________
1 sizeof розмір об’єкта (виразу)
sizeof розмір типу
___________________________________________
2 ++ приріст на 1 після
++ приріст на 1 до
-- зменшення на 1 після
-- зменшення на 1 до
- унарний мінус
+ унарний плюс
___________________________________________
3 * множення
/ ділення
% остача цілочисельного дідення (по модулю)
___________________________________________
4 + додавання
- віднімання
___________________________________________
5 = просте присвоєння
*= помножити та присвоїти
/= поділити та присвоїти
%= взяти по модулю та присвоїти
+= додати та присвоїти
-= відняти та присвоїти
___________________________________________
Тут приведений неповний перелік груп і операцій в них.
Коли із запису арифметичного виразу неясна послідовність виконуваних операцій, слід застосовувати запис у дужках.
Унарні операції та операції присвоєння правоасоціативні, всі решта - лівоасоціативні. Це означає, що, наприклад:
a = b = c те саме, що a = (b = c),
a + b + c те саме, що (a + b) + c, а
*p++ це *(p++), а не (*p)++.
При діленні додатніх цілих чисел заокруглення здійснюється в сторону 0, але якщо хоч один з операндів від’ємний, то форма заокруглення машинно-залежна. Тут завжди істинне, що :
(a/b)*b + a%b дорівнює a (якщо b не дорівнює 0).
ЗАВДАННЯ.
N1.
Відкрити вікно редагування нового файлу.
Набрати текст програми PRAISE.C.
Запустити компіляцію програми.
Знайти всі помилки в синтаксисі.
Записати вихідний файл у власний директорій.
Створити виконуваний файл.
Прослідкувати покрокове виконання.
Виконати пряме виконання програми.
Виконати корекцію тексту: підставити замість ідентифікатора PRAISE його значення.
Відладити та запустити нову версію програми.
// Вихідний текст програми PRAISE.C.
#define PRAISE "О, яке чудове iм'я!"
#include <stdio.h>
#include <string.h>
main()
{ char name[50];
printf("Як Вас звати?\n");
scanf ("%s",name);
printf("Привiт, %s. %s\n",name,PRAISE);
printf("Ваше iм'я складається з %d лiтер i ",
"займає %d комiрок пам'ятi.\n",
strlen(name),sizeof name);
printf("Вiтальна фраза складається з %d лiтер',
strlen (PRAISE));
printf(" i займає %d комiрок пам'ятi.\n",
sizeof PRAISE); }
N2. Здійснити виконання програми VALUES.C:
#include <stdio.h>
#include <conio.h>
main()
{
printf("Числа типу int займають %d байт.\n",sizeof(int));
printf("Числа типу char займають %d байт.\n",sizeof(char));
printf("Числа типу float займають %d байт.\n",sizeof(float));
printf("Числа типу double займають %d байт.\n",siezof(double));
getch();
}
N3. Створити і виконати програми дослідження властивостей арифметичних
операцій з різними типами величин.
// Префіксний та постфіксний
// інкремент ++ і декремент --
#include <stdio.h>
#include <conio.h>
void main()
{ int n = 1;
printf("n=%d \n",n);
// n++;
printf("prefix: ++n=%d\n",++n);
printf("postfix: n++=%d\n",n++);
printf("after-postfix: n=%d\n",n);
// n--;
printf("prefix: --n=%d\n",--n);
printf("postfix: n--=%d\n",n--);
printf("after-postfix: n=%d\n",n);
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{ int a, b=3;
float c;
c = b%2 + (a = ++b/2) + 1.1;
printf("a=%d,c=%4.1f\n",a,c);
/*a=2,c=3.1*/
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{
float x=1.4, y=2.0;
int z;
z = x/2*7 + y/4 - 1;
printf("z=%d\n",--z);/*z=3*/
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{
int x=2,z;
float y = 2.1;
z = x++*y + y/x*3;
printf("x=%d z=%d\n",x,z);/*z=7*/
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{
float x = 1.1, y = 0, z;
int a;
z = (a=x++)*y + 3*x;
printf("z=%4.1f\n",z); /*z=3.3*/
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{
int x = 2,z;
float y;
z = 0.5*(y = 2.3*x) + x++/3*y;
printf("z=%d\n",z); /*z=2*/
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{
int x,y = 3;
float z;
z = 1.1*(x = ++y/2.) + 0.3*x;
printf("z=%4.1f\n",z); /*z=2.8*/
getch();
}
Контрольні запитання.
Призначення та структура програми, написаної мовою C.
Різновиди типів величин.
Що таке константи і змінні?
Показати способи введення констант, представлених в різних системах числення.
Правила запису декларацій змінних.
Особливості цілочисельної арифметики.
Порядок виконання операцій.
Особливості операцій інкремента і декремента.
Операції присвоєння.
Пояснити зміст і обгрунтувати результати виконаних прикладів.
№3.
«Інструкції розгалуження в програмах мовою С».
МЕТА РОБОТИ: дослідити властивості інструкцій розгалуження алгоритмів програм, складених мовою програмування С.
Попередні відомості.
Розгалуження в програмах організовують за допомогою груп операторів: вибору (умовний оператор if і переключатель switch); переходу, що виконують безумовну передачу керування керування ( goto – безумовний перехід, continue – завершення текучої ітерації циклу, break – вихід із циклу, або переключателя, return – повернення з функції.
Умовний оператор має скорочену форму:
if (вираз-умова) оператор;
де в якості виразу умови можуть використовуватися – арифметичний вираз, відношення і логічний вираз. Оператор, що знаходиться в умові виконується тільки у випадку істинності, тобто при ненульовому значенні виразу умови.
Приклад: if ( x < 0 && x> -10) x=-x;
Крім скороченої форми існує повна форма умовного оператора:
if (вираз-умова)
оператор_1;
else
оператор_2;
Тут у випадку істинності виразу-умови виконується тільки оператор_1, при нульовому значенні виразу-умови виконується тільки оператор_2.
Приклад:
if (x>0)
b=x;
else
b=-x;
Оператор у скороченому варіанті оператора if, оператор_1і оператор_2 в повному операторі if можуть бути як окремими, так і складовими операторами.
Дозволяються вкладені багаторівневі конструкції типу (if – else if – else … if – else). Ркомендується використовувати дужки для точного визначення послідовності.
Оператори можуть бути складеними, тобто представляти собою групу операторів, тоді ця група повинна бути обмежена фігурними дужками.
Оператор goto реалізує безумовний перехід на помічену інструкцію:
goto мітка;
Мітка повинна бути розташована всередині поточної функції. Мітка може стояти перед будь-яким оператором і мати вид:
ідентифікатор:
Частіше ідентифікатор мітки вибирають і записують вликими літерами. Мітка використовується тільки як об’єкт переходу для goto.
Оператор switch є основним засобом, коли необхідно організувати мультирозгалуження. Його синтаксис:
switch (вираз)
{ case константа_1 : оператори_1;
case константа_2 : оператори_2;
default: оператори;
}
У цьому оператрі використовуються три службових слова: switch, case, default. Перше з них ідентифікує властиво оператор-перемикач. Службове слово case з наступною константою є в деякій мірі міткою. Константи можуть бути цілими, або символьними і всі повинні бути різними (щоб різними були мітки). Службове слово default також означає окрему мітку. При виконанні оператора обчислюється вираз записаний після switch, і його значення послідовно порівнюється з константами, що поміщені слідом за case. При першому ж співпадінні виконуються оператори помічені даною міткою. Якщо виконувані оператори не передбачають жодного переходу (тобто серед них немає операторів goto, return, exit, break), то далі виконуються оператори всіх наступних варіантів, поки не з’явиться оператор переходу або не закінчиться переключатель.
Оператори, що слідують за default виконуються, якщо значення виразу в дужках після switch не співпало з жодною константою після case. Мітка default може бути відсутньою в перемикачі. У цьому випадку при неспівпадінні значень виразу з константами перемикачне виконує жодних дій. Уточнимо, що default і case не є мітками в звичайному сенсі. До них неможливо перейти за допомогою оператора goto.
Оператор Break:
Синтаксис:
break;
викликає завершення найменшого охоплюючого оператора while, do, for або switсh; керування передається на оператор, який слідує за завершеним.
ЗАВДАННЯ
1. Виконати програму, яка ілюструє розгалуження умовними операторами:
#include <stdio.h>
#include <conio.h>
void main()
{int a=2,b=0,c=1;
printf("\n\n");
if(a > 0 && b < -3) c = b*b/a; printf("c=%d\n",c); /*c=1*/
a = ++c/a + a%c;
b+= c*c;
if(a < b || a < 0) {c *= a; printf("c=%d\n",c);} /*c=2*/
else if (c++ == 2) printf("c=%d\n",c);
if(b < a && a == 2) c = 2*a +1;
else { c = (b--) + a; a = 0; }
printf("c=%d\n",c); /*c=5*/
a = b = 2;
if(c >= 3) if(a < 0 || a > c) c = 0;
else { a = 1; c = 7; printf("c=%d\n",c); } /*c=7*/
if(c > 0 && c < 10) {if(a > 0) printf("c=%d\n",c++);} /*c=7*/
else c = 10;
if(c <= 5) if((a = b + 1) > 2) c %= 2;
printf("c=%d\n",c); /*c=8*/
a = 3; b = -1;
if(b > 0) c = 1;
else if(b < -10) { c = -1; printf("c=%d\n",c); }
else if( b <= -3 ) c = 2;
else c = b*b + 10; printf("c=%d\n",c); /*c=11*/
getch();
}
2. Виконати програму:
/* Виводить запрошення "Продовжуєте (Так/Ні)" та інтерпретує відповідь користувача, ілюструючи використання циклу do-while та перемикача switch.
Повернення:
YES (0), якщо вибір - Так;
NO (1), якщо вибір - Ні ;
ESC (2), якщо натиснено Esc */
#include <stdio.h> /* прототип функції puts(), putchar() */
#include <bios.h> /* прототип функції bioskey() */
#define YES 0
#define NO 1
#define ESC 27
int main(void)
{
char ch;
puts("Продовжуєте (Так/Ні). Esc - відмовитися від вибору");
do
{
ch = bioskey(0);
switch(ch) {
case 'т': case 'Т':
case 'n': case 'N':
puts("Так");
return(YES);
case 'н': case 'Н':
case 'y': case 'Y':
puts("Ні");
return(NO);
case ESC:
break;
default:
putchar('\a');
}
}
while(ch != ESC);
puts("Відміна вибору");
return(ESC);
}
3. Виконати програму «калькулятор», в якій вводяться: перше число, знак арифметичної операції, друге число. Програма розпізнає знак арифметичної операції та виконує її, після чого друкує результат.
#include <stdio.h>
#include <conio.h>
#include <string.h>
void main()
{
char *expr,op;
float a,b,res;
printf("\nEnter expression:");
scanf("%f%c%f",&a,&op,&b);
switch (op)
{ case '-': res = a-b; break;
case '+': res = a+b; break;
case '*': res = a*b; break;
case '/': res = a/b; break;
default: res = 0; printf("\n illegal operation\n"); break;
}
printf("=%f\n",res);
getch();
}
Контрольні запитання.
Призначення оператора безумовного розгалуження, формат мітки.
Конструкція оператора умовниого розгалуження if.
Конструкція оператора умовного розгалуження іf – else.
Що таке складений оператор?
Як організувати багаторівневі розгалуження?
Призначення перемикача.
Які властивості виразу, за яким працює перемикач?
Призначення оператора Break.
Призначення оператора Default.
Список рекомендованої літератури.
Керниган, Ритчи. Программирование на С. М. – 1984, 1990.
Березин А.К., Березина В.И. Программирование на С и С++. М. – 1996.
Бочков С.О. Субботин Д.М. Язык программирования Си для персонального комп’ютера. М.- Диалог-1990.
Подбельский В.В. Фомин С.С. Прграммирование на языке Си. М.-Финансы и статистика. – 2002.