
- •Київський національний університет імені Тараса Шевченка
- •Гриф надано Міністерством освіти і науки України (лист № 1.4/18-г-1523 від 20.09.07)
- •Основи алгоритмізації
- •1.1. Поняття алгоритму
- •1.2. Класифікація внутрішніх структур алгоритмів
- •1. Ввести а,b.
- •3. Вивести значення s.
- •4. Кінець.
- •6. Закінчити роботу.
- •1. Ввести число n.
- •6. Перехід до п.3.
- •7. Друк к.
- •8. Кінець.
- •1.3. Складність алгоритмів
- •1.4. Складність задач
- •Завдання для самостійної роботи
- •Форма Бекуса – Наура
- •Завдання для самостійної роботи
- •Void main(){
- •3.2. Структура с-програми
- •3.3. Описувачі
- •3.4. Основні операції мови с
- •If(!inword)
- •Void main()
- •Int rozmir;
- •3.5. Оператори мови с
- •3.5.1. Прості оператори
- •3.5.2. Умовний оператор
- •3.5.3. Оператор циклу for
- •3.5.4. Оператори do-while, while
- •3.5.5. Оператор continue
- •3.5.6. Оператор-перемикач switch
- •3.5.7. Оператор break
- •3.5.8. Оператор goto
- •If(error(I,j,k)) goto exit;
- •3.5.9. Оператор return
- •3.6. Директиви препроцесору та вказівки компілятору
- •3.6.1. Директива препроцесору #define
- •1. Макровизначення:
- •3.6.3. Директива #include
- •3.6.4. Директиви умовної компіляції #if, #elif, #else, #endif
- •3.6.5. Директива #line
- •If(!cond)
- •3.7. Описувачі з модифікаторами
- •3.7.1. Моделі пам'яті
- •3.7.2. Модифікатори типу доступу в пам'яті
- •Int huge*near X;
- •3.7.3. Модифікатори const, volatile, cdecl, pascal, interrupt
- •Volatile int t;
- •Void interrupt timer()
- •Void wait(int interval)
- •Завдання для самостійної роботи
- •Принципи типізації даних
- •4.1. Прості типи даних
- •4.2. Похідні типи
- •4.3. Еквівалентність типів
- •4.4. Успадкування атрибутів
- •4.5. Перераховні типи
- •4.6. Логічні типи
- •4.7. Символьні типи
- •4.8. Числові типи
- •4.9. Структурні типи даних
- •4.9.1. Масиви
- •4.9.2. Структури
- •Int year;
- •4.10. Деякі особливості типів даних c
- •4.10.1. Базові типи даних
- •4.10.2. Перетворення типів
- •Int atoi(char s[]) /*char* s*/
- •4.10.3. Засіб typedef
- •Int curs;
- •4.10.4. Покажчики та масиви
- •Void * p;
- •Int array[12];
- •Void f(int a[])
- •Int f(char * s)
- •Наведемо деякі приклади розв'язання задач.
- •Int shift; /*відступ*/
- •Int count[n]; /*кількість монет даного типу (коефіцієнти ai)*/
- •Int coin;
- •Int sum; /*монета, яку міняємо*/
- •Int maxcoin; /*індекс по масиву cost[] монети максимальної вартості, допустимої при даному розміні.*/
- •If(count[I])
- •If(maxcoin)
- •Int* ctranspon (int *a,int n,int m)
- •Void dobutok(int* a, int* b, int** c, int n, int m)
- •Int n,m,I,size;
- •Int main()
- •4.10.5. Структури та об'єднання
- •Розглянемо деякі приклади розв'язання задач.
- •Int hashfunc(key); int eqkey(key, key);
- •Void freeval(val); void setval(val, val);
- •Void freekey(key); void setkey(key, key);
- •Int hashfunc(key key){
- •Val val; /*значення*/
- •Void set(key key, val val){
- •Void printcell(struct cell *ptr){
- •Void main(void)
- •Завдання для самостійної роботи
- •Зображення чисел у комп'ютері
- •Int main(void)
- •5.1. Системи числення
- •5.2. Правила переведення чисел з однієї системи числення в іншу
- •5.3. Правило визначення точності зображення
- •5.4. Двійкова арифметика
- •5.4.1. Додавання двійкових чисел
- •5.4.2. Зображення від'ємних чисел
- •XXXXXXXX 00000001 00000000.
- •5.4.3. Віднімання двійкових чисел
- •5.4.4. Множення двійкових чисел
- •5.4.5. Ділення двійкових чисел
- •5.5. Ознака переповнення розрядної сітки при арифметичних операціях
- •5.6. Зображення цілих чисел
- •5.7. Зображення дійсних чисел
- •5.8. Керування машинним зображенням чисел та особливості виконання арифметичних операцій
- •Завдання для самостійної роботи
- •Реалізація концепції структурного програмування
- •6.1. Оголошення та визначення функцій
- •Int d;} people;
- •6.2. Формальні та фактичні параметри
- •Void swap(int a,int b)
- •Void swap(int a,int*b)
- •6.3. Функції зі змінною кількістю параметрів
- •Void sum(char *msg,...)
- •6.5. Параметри функції main
- •6.6. Лiтернi покажчики та функцiї
- •Void strcpy(char*s,char*t)
- •Void f(void)
- •6.8. Класи пам'яті
- •Розглянемо деякі приклади розв'язання задач.
- •I, power(2,I),power(-3,I));
- •Void main() { choturukyt b; tochka *a; float s; long n,in; srand(time(null));
- •6.9. Введення–виведення с. Файли та потоки
- •6.9.1. Функції введення–виведення верхнього рівня
- •6.9.2. Функції введення–виведення консольного термінала та порту
- •Int main(void)
- •6.9.3. Функції введення–виведення нижнього рівня
- •Int main(void)
- •Int handle;
- •Розглянемо приклади розв'язання задач.
- •Void main(void)
- •Void main(argc,argv)
- •If(c& masks[I])
- •If (цей рядок довший за найдовший з попередніх)
- •Int max; /*максимальна довжина*/
- •Int len; /*довжиною цього рядка*/
- •Int nwords; /*кількість слів у рядку*/
- •If(!*s) /*рядок закінчився*/
- •Int ctr; /*кількість входжень слова*/
- •If(!strcmp(word,w[I].Wrd)){
- •If(alert){
- •Void main() { float X,y,z,t,s; int I,j,flag,n,k; m1: clrscr();
- •InitBase (void){
- •Int key, /*новий ключ*/
- •InitBase();
- •Завдання для самостійної роботи
- •7.1. Елементи концепції обєктно-орієнтованого програмування
- •Int year;
- •Int year;
- •7.3. Опис протоколу класу
- •7.4.1. Коментарі
- •7.4.2. Прототипи функцій
- •Void f();
- •7.4.5. Перевантаження функцій
- •Int Name (int first)
- •Int Name (unsigned first)
- •Int Name (int first,char*second)
- •7.4.6. Значення формальних параметрів за умовчанням
- •7.4.7. Посилання й покажчики
- •Void increment(int& X)
- •Int anotherint;
- •7.4.10. Покажчик на void
- •Void*void_ptr;
- •Void swap(void*&item1,void*&item2)
- •7.4.11. Зв'язування зі збереженням типів
- •7.4.12. Про структури та об'єднання
- •7.5. Функції-члени класу
- •X *this;
- •Int year;
- •7.6. Конструктори та деструктори
- •7.6.1. Поняття про конструктори
- •Int*data;
- •Int size;
- •7.6.3. Конструктор копіювання
- •Int data[large];
- •Inline Large1 Large1::fast(const Large1 & b)
- •7.7. Глобальні та локальні об'єкти
- •Void main(void)
- •7.8. Статична пам'ять і класи
- •Int statpol::I;
- •Vоid draw()
- •Int large;
- •Int bigwant;
- •Void f() {
- •Void g(int a)
- •7.9. Успадкування
- •7.9.1. Синтаксична реалізація успадкування
- •7.9.2. Правила доступу до полів даних
- •Void f(void)
- •Void g(void){}//...}
- •7.9.3. Конструктори та деструктори в похідних класах
- •7.9.4. Використання заміщуючих функцій-членів
- •Void Display (void); //замiщувальна функцiя
- •Void Region::Display(void)
- •Void Display(void);};
- •Void Population::Display(void)
- •7.9.5. Похідні класи й покажчики
- •7.9.6. Ієрархія типів
- •XyValue(int_x,int_y):X(_x),y(_y)
- •XyData(int_x,int_y)
- •7.9.7. Множинне успадкування
- •Void SetLoc(int_x,int_y);};
- •Int data;
- •7.10. Віртуальні функції та класи
- •7.10.1. Віртуальні функції
- •Int value;
- •Virtual int GetValue();
- •Int Value::GetValue(){return value;}
- •7.10.2. Чисті віртуальні функції. Абстрактні класи
- •Virtual void f1(void);
- •Virtual void f2(void);//...}
- •Int index;
- •7.10.3. Віртуальні деструктори
- •7.10.4. Посилання як засіб для реалізації поліморфізму
- •7.10.5. Дещо про механізм віртуальних функцій
- •Virtual int method1(float r);
- •Int data;
- •Void func(void){//тіло}};
- •Virtual public CocaCola {
- •Int size;
- •Void ShowValue(void)
- •Void ShowValues(void);};
- •Void Two::ShowValues(void)
- •7.11.2. Дружні функції
- •Void Show(One &c1,Two &c2)
- •Void Show(One &c1);
- •Void Two::Show(One &c1)
- •7.12. Перевантаження операцій
- •7.12.1. Загальний підхід
- •Void main()
- •7.12.2. Перетворення типів
- •X::operator т();
- •7.12.3. Перевантаження операції індексування масиву
- •Int znach;
- •7.12.4. Перевантаження операції виклику функції
- •Int operator()(void);
- •Int FuncClass::operator()(void)
- •Vidnosh*vec;
- •7.12.5. Перевантаження операції доступу до члена класу
- •7.12.6. Перевантаження операцій інкремента й декремента
- •Int index;
- •Void*operator new(size_t)
- •Void*operator new(size_t);
- •8.1. Функціональні шаблони
- •8.1.1. Визначення й використання шаблонів функцій
- •Void func(t t)
- •Int main(void)
- •8.1.2. Перевантаження шаблонів функції
- •Int main(void)
- •8.1.3. Cпецiалiзованi функцiї шаблона
- •Int main(void){
- •8.2. Шаблони класів
- •8.2.1. Визначення шаблонів класу
- •Void push(t t);
- •Int numitems;
- •8.2.2. Константи й типи як параметри шаблона
- •8.2.3. Використання шаблонних класів
- •Int main(void)
- •8.2.4. Спеціалізація шаблонів класу
- •Void add(t item);
- •Int main(void)
- •IArray.Add(i1);
- •Int main(void)
- •IList.Add(i1);
- •Завдання для самостійної роботи
- •Автоматна технологія програмування
- •If(!stop)printf("не входити");
- •Завдання для самостійної роботи
- •Список літератури
- •Передмова 3
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);
}}