- •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 Динамічне виділення пам'яті
10. Структури, об’єднання, перерахування
7.1 Структури
Структура– це сукупність логічно зв’язаних даних різних типів.
При визначенні структури створюється новий тип, на основі простих і (або) похідних типів.
Синтаксис визначення структури:
struct <назва структури>
{
<опис елементів>
};
де назва структури - це імя типу структури;
опис елементів – програмний блок, де приволиться визначення елементів.
Визначення структури може не містити імені. Такі структури називаються анонімними.
Змінні типу структури називають об’єктом структури. Склад цих об’єктів визначатиметься при оголошенні. Для виділення пам’яті під обєкт структури необхідно оголосити змінну типу структури.
Синтаксис оголошення змінної типу структури:
struct <назва структури> < ім’я змінної>;
де ім’я змінної- це ідентифікатор, який використовується для доступу до обєкту стуктури;
назва структури– імя типу структури.
Приклад 1.Створення структури.
struct lab
{
int num;
char* name;
}; /* визначення структурного типу з іменем lab*/
/* … */
int main(void)
{
/* … */
struct lab Lаb_10;/* створення об’єкту Lab_10 типу структури
lab.*/
/* … */
return 0;
}
Можна одночасно визначати структурний тип і описувати за допомогою нього структуру:
Приклад 2. Оголошення об’єкту зразу після створення структури.
struct gr /* ім’я структурного типу*/
{
short int day; /* елемент структури*/
int month,year; /* однотипні елементи структури*/
} date; /* ім’я структурної змінної*/
Елементи структури називають полями (day, month, year). Поля можуть бути будь-якого базового чи похідного типу, наприклад, масивом, покажчиком, об’єднанням або іншою структурою.
Для звернення до полів структури використовуються уточнені іменачерез операцію вибору: “крапка” (“.”) при зверненні через ім’я структури і операцію непрямого доступу “->” при зверненні через покажчик.
Приклад 3. Присвоєння полям структури деяких значень.
date.day=10; /*звернення до поля day через об’єкт date */
struct gr *ptrdate=&date; /* створення покажчика ptrdate на об’єкт date */
ptrdate->year=2012; /*Ініціалізація поля year через покажчик на об'єкт ptrdate */
Введення/виведення структур виконується поелементно.
Приклад 4.Введення даних в поле day структури date.
scanf(“%i”, &date.day);
Структури одного типу можна копіювати. Структури, пам’ять під які виділяється на етапі компіляції, можна ініціалізувати, перераховуючи значення їх елементів.
Приклад 5.Ініціалізація полів структури Lab_10.
struct gr date = {1, 2, 3}.
Можна створювати масиви структур.
Приклад 6.Створення масиву структур.
/* структура для опису дати*/
structdate
{
intday, month, year;
};
/* … */
intmain(void)
{
/* … */
structdate d[5]={{1,3,1980},{5,1,1990},{1,1,2002}};
/* масив з 5-ти структур типу date , кожна з
яких складається з 3-х елементів типу int,
яким надаються початкові значення*/
/* … */
return 0;
}
Приклад 7.Написати програму, яка зчитуватиме дані про студентів, і видаватиме інформацію про них за введеною фамілією. Приклад структури наведений у таблиці 7.1.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
structSpysok
{
char PIB[20]; /* прізвище студента*/
char Grup[10]; /* назва групи*/
intOt[3]; /*3 оцінки*/
floatS_Bal; /* середній бал*/
} *vid; /* покажчик на структуру*/
voidVvid(int nom, Spysok *vid)
{
printf("\n Vvedit vidomosti \n %i", (nom+1));
printf("\n PIB - ");
scanf("%s", vid->PIB);
printf(" Nomer Gr - ");
scanf("%s", vid->Grup);
floats=0;
for(inti=0; i<3; i++)
{
printf("\n Otsinki - ");
scanf("%i", &vid->Ot[i]);
s+=vid->Ot[i];
}
vid->S_Bal=s/3;
}
intmain(void)
{
structSpysok Stud[50];
inti, N;
charLitera;
printf ("\n Vvedit kilkist studentiv u grupi < 50 ");
scanf("%i", &N);
for(i=0; i<N; i++)
Vvid(i, &Stud[i]);
printf("\n Spysok studentiv");
for(i=0;i<N;i++)
printf("\n %s \n %s \n %f", Stud[i].PIB,
Stud[i].Grup, Stud[i].S_Bal);
printf("\n Poshuk vidomostey pro studentiv za
pershoyu literoyu prizvyscha\n");
scanf("%c", &Litera);
if(islower(Litera))
toupper(Litera);
printf("\n Vidomosti pro Students:");
int kod_p = 0;
for(i=0; i<N; i++)
if(Stud[i].PIB[0]==Litera)
{
kod_p = 1;
printf("\n %s \n %s \n %f", Stud[i].PIB,
Stud[i].Grup, Stud[i].S_Bal);
}
if(kod_p==0)
printf(" Takyx nemae!");
system("PAUSE");
return 0;
}
Результат роботи програми:
Таблиця 7.1 – Структура з даними про студентів (Приклад 6).
Назва |
Індекси | |||||||||||
0 |
1 |
2 |
3 | |||||||||
Stud.PIB |
Філіпчук |
Олєйнікова |
Білоус |
Подольський | ||||||||
Stud.Grup |
1СІ-10 |
1СІ-10 |
1СІ-10 |
1СІ-10 | ||||||||
Stud.Ot |
5 |
5 |
4 |
4 |
5 |
5 |
5 |
5 |
5 |
5 |
4 |
5 |
Stud.S_Bal |
4.66 |
4.66 |
5 |
4.66 |
Stud[0].PIB=”Філіпчук”
Stud[3].S_Bal=4.66
Stud[0].Ot[2]=4 (тому що рахуючи з 0, 2-га оцінка Філіпчук - 4)
Так само можна звертатись до кожного символу рядкових полів:
Stud[0].PIB[2]=’л’
Stud[1].Grup[3]=’-’
Перевизначення структур в межах однієї області видимості не дозволяються, за виключенням випадку коли перевизначення здійснюється в різних програмних блоках. У випадку визначення структури у окремому програмному блоці, область видимості цього визначення закінчується з закінченням програмного блоку, в якому міститься це визначення.
Приклад 8.Області видимості визначень структур.
struct st /* Глобально-видиме визначення */
{
intivar;
charpstr[8];
};
voidfunc(void)
{
struct st;/* Визначення, яке видиме тільки в межах
функції func */
{
int ivar;
char pstr[8];
float fvar;
};
/* ... */
}
/* ... */
Код, наведений у прикладі 8 є коректним. Але слід застерегти від подібного роду перевизначень, що суттєво ускладнюють розуміння і супроводження програм, написаних у такому стилі.
Для економії памяті в структурах дозволено визначати бітові поля. При використанні бітових полів збільшується час доступу до даних, що зберігаються в цих полях.
Бітове поле – це число, що займає деякий набір бітів і напряму не може бути адресоване процесором. Синтаксис визначення полів і доступу до них базується на синтаксисі структур.
Приклад 9.Визначення бітових полів.
struct pol
{
unsigned charR:2;
unsigned charG:3;
unsigned charB:3;
} color;
Рисунок *.* Розташування бітових полів у памяті
У прикладі 8 розглятуто варіант визначення структури pol, що містить бітові поля. Число, наступне за двокрапкою у описі елементу структури, задає ширину бітового поля. Зображення образу об’єкту color, який має тип pol у памяті представлено на рисунку *.*.
Приклад 10.Робота з бітовими полями.
#include <stdio.h>
#include <stdlib.h>
structpol
{
unsigned charR:2;
unsigned charG:3;
unsigned charB:3;
};
intmain (void)
{
structpol color;
color.R = 3;
color.G = 6;
color.B = 3;
printf("R=%d\nG=%d\nB=%d\n", color.R, color.G, color.B);
system("pause");
return 0;
}
Результат роботи програми: