- •2. Основні елементи мови с
- •3.1 Алфавіт мови програмування
- •3.2Лексеми
- •3.3Ключові слова
- •3.4Ідентифікатори
- •3.5 Класифікація типів даних
- •3.6 Літерали
- •3.7 Оператори
- •3.8 Коментарі
- •3.9 Директиви препроцесора
- •3.10 Організація програми
- •3. Операції та вирази
- •4.1 Загальні відомості
- •4.2 Арифметичні операції
- •4.3 Операції приведення типів
- •(Тип) ідентифікатор,
- •4.4 Операції присвоєння
- •4.5 Операції інкремента і декремента
- •4.6 Операції порівняння
- •4.7 Операції зсуву
- •4.8 Порозрядні операції
- •4.9 Логічні операції
- •4.10 Операція sizeof
- •Sizeof ( Вираз ),
- •4.11 Операція послідовного обчислення
- •4.12 Операція умови (?:)
- •Операнд-1 ? Операнд-2 : Операнд-3
- •4.13 Адресні операції
- •Тип * ім'я_покажчика;
- •4. Прості типи даних
- •5.1 Оголошення змінних
- •[ Модифікатори ] тип ім’я_змінної;
- •5.2 Час існування та область видимості змінних
- •5.3 Цілі типи даних
- •5.4 Дійсні типи даних
- •5. Оператори керування
- •5.1 Оператор розгалуження if
- •If ( Вираз ) true-оператор;
- •5.2 Оператор розгалуження if-else
- •If ( Вираз ) true-оператор; else false-оператор;
- •5.3 Оператор множинного розгалуження switch
- •5.4 Оператор циклу for
- •For ( Вираз 1 ; Вираз 2 ; Вираз 3 ) тіло циклу
- •5.5 Оператор циклу while
- •While ( Вираз ) тіло циклу
- •5.6 Оператор циклу do while
- •Тіло циклу while ( Вираз ) ;
- •5.7 Оператор break
- •5.8 Оператор continue
- •6 Введення та виведення даних
- •7.1 Функція виведення printf
- •Int printf( стрічка форматування, змінна1, змінна2, ... );
- •7.2Функція введення scanf
- •Int scanf (стрічка форматування, адреса змінної1, адреса змінної2, ... );
- •9.1 Введення та виведення у файл
- •7 Масиви
- •7.1 Загальні поняття
- •7.2 Одновимірні масиви
- •Тип даних ім’я змінної [n];
- •7.3 Багатовимірні масиви
- •6. Функції
- •6.1 Основні поняття
- •{Тіло функції}
- •6.2 Область видимості
- •6.3 Порожній тип void
- •6.4 Передача аргументів у функцію
- •6.5 Рекурсивні функції
- •6.6 Прототипи функцій
- •8. Рядки в с
- •4.1 Прототипи
- •4.2 Функції перетворення буферів
- •4.3 Функції перевірки літер
- •4.4 Рядок символів
- •4.5 Операції з рядками:
- •4.6 Символьні константи
- •9. Покажчики
- •5.1 Визначення та ініціалізація покажчиків
- •5.2 Визначення покажчиків:
- •5.3 Масиви
- •5.6 Копіювання рядка
- •5.7 Посилання та оператор &
- •5.9 Посилання в якості результатів функції
- •5.10 Покажчики на функцію
- •Тип_функціі (* імя_покажчика) (специфікація_параметрів);
- •5.11 Покажчики на void
- •5.12 Арифметика покажчиків
- •10. Структури, об’єднання, перерахування
- •7.1 Структури
- •7.2 Ключове слово typedef
- •7.3 Об’єднання
- •7.4Перераховуваний тип (Enum)
- •Enum dataType
- •Enum day
- •11 Динамічне виділення пам'яті
7.2 Ключове слово typedef
Ключове слово typedef призначено для введення синонімів до назв існуючих типів.
Синтаксис застосування typedef:
typedef <назва існуючого типу> <назва синоніму>;
Приклад 11.Оголошення та використання typedef.
typedef unsigned long intULINT;
typedef floatFLT;
typedef charSomeString[55];
ULINT b; /* еквівалентно unsigned long int b; */
SomeString str[10]; /* Масив із 10 покажчиків на масив з 55
елеметів типу char (еквівалентно char
str[10][55]) */
Синонімічні типи, введені за допомогою typedef, подібно до змінних, можуть мати обмежену область видимості, або бути глобальними.
Приклад 13.Області видимості типів, введених за допомогою typedef.
#include <stdio.h>
#include <stdlib.h>
typedef intcntr; /* тип cntr доступний для всієї подальшої
програми */
cntr f(void)
{
staticcntr count=0;
return++count;
}
intvizov(void)
{
typedef intchislo_viklikiv; /* тип chislo_viklikiv не
можна використовувати за межами vizov() */
chislo_viklikiv c;
while((c=f())<250);
returnc;
}
int main(void)
{
printf("Chislo viklikiv funkcii f(): %d\n",vizov());
system("PAUSE");
return 0;
}
Результат роботи програми:
Програма, приведена у прикладі 13ілюструє обмеженість область видимості типу chislo_viklikiv, який введено локально для конкретної функції. Використання цього типу за межами функції vizov приведе до помилки на етапі компіляції.
За допомогою typedef можна вводити необмежену кількість синонімів до єдиного типу, навіть коли області видимості синонімів перетинаються.
Але введення двох синонімів з однаковим ім’ям навіть до різних типів в одній області видимості призведе до генерації компілятором помилки. Виключення становить перевизначення синонімів в різних програмних блоках. У цьому випадку перевизначений синонім стає локальним для даного блоку і його дія закінчується по закінченню програмного блоку.
Приклад 14. Превизначення синонімів
void f(void)
{
typedef unsigned int ui;
/* ... */
{
/* ... */
typedef int ui;/* локальне пере визначення ui */
/* ... */
}
/* ... */
}
typedef дозволяє одночасно вводити декілька синонімів до одного типу. У цьому випадку синоніми записуються через кому. Допустимо замість імені типу при використанні typedef приводити саме визначення типу.
Приклад 15.Одночасне введення декількох синонімів та визначення типу всередині typedef
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long intDWORD;
typedef unsigned short intWORD;
typedef structtagBFHDR
{
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
} BFHDR, *PBFHDR;
intmain(void)
{
BFHDR bf;
BFHDR pbf = &bf;
pbf->bfType = 1;
bf.bfSize = 10;
printf(“%d\n”, pbf->bfSize + bf.bfType);
system(“PAUSE”);
return 0;
}
Результат роботи програми:
Код з прикладу 15 вводить у програму тип BFHDR, який є синонімом типу struct tagBFHDR та тип *PBFHDR, який є синонімом типу struct tagBFHDR*. Подальше використання введених синонімів нічим не відрізняється від використання типу-оригіналу, до якого ці синоніми були введені.
Слід застерегти від використання директиви препроцесора #define від використання в цілях подібних до typedef.
Приклад 16.Заміна typedef за допомогою директиви #define
#define char* PCHAR
typedef char* pchar;
voidf(void)
{
PCHAR pc1,pc2;/* УВАГА! Еквівалентно char* pc1,pc2; */
pchar pc3,pc4;/* Еквівалентно char *pc3,*pc4 */
/* … */
}
Припустимо нам необхідно об’явити чотири змінних типу вказівників на символ. На перший погляд ідентичні записи із прикладу 15на практиці призводять до дещо неочікуваних результатів. Із синтаксичної точки зору програма немає помилок і може бути успішно скомпільована, але за рахунок того що всі макропідстановки виконуються препроцесором ще до етапу компіляції і представляють собою просту заміну літералу PCHAR на char*, об’явлення змінної pc2 трактується компілятором як об’явлення змінної типу char.