
- •Міністерство освіти і науки україни Національний університет «Львівська політехніка» Кафедра «Телекомунікації»
- •Попередні відомості
- •Заголовок
- •Результат роботи програми:
- •Розглянемо приклади роботи модифікаторів ширини поля на друк цілого числа.
- •Контрольні запитання.
- •Попередні відомості.
- •Завдання.
- •Контрольні запитання.
- •Попередні відомості.
- •Завдання
- •Контрольні запитання.
- •Список рекомендованої літератури.
Контрольні запитання.
Структура програми на мови С.
Ідеологія організації операцій уведення-виведення в мові С.
Синтаксис функцій 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).