
- •1 Основні елементи мови с
- •1.1 Алфавіт мови програмування
- •1.2 Лексеми
- •1.3 Ключові слова
- •1.4 Ідентифікатори
- •1.5 Класифікація типів даних
- •1.6 Літерали
- •1.7 Оператори
- •1.8 Коментарі
- •1.9 Директиви препроцесора
- •1.10 Організація програми
- •2 Операції та вирази
- •2.1 Загальні відомості
- •2.2 Арифметичні операції
- •2.3 Операції приведення типів
- •2.4 Операції присвоєння
- •2.5 Операції інкремента і декремента
- •2.6 Операції порівняння
- •2.7 Операції зсуву
- •2.8 Порозрядні операції
- •2.9 Логічні операції
- •2.10 Операція sizeof
- •2.11 Операція послідовного обчислення
- •2.12 Операція умови (?:)
- •2.13 Адресні операції
- •3 Прості типи даних
- •3.1 Оголошення змінних
- •3.2 Час існування та область видимості змінних
- •3.3 Цілі типи даних
- •3.4 Дійсні типи даних
- •4 Оператори керування
- •4.1 Оператор розгалуження if
- •4.2 Оператор розгалуження if-else
- •4.3 Оператор множинного розгалуження switch
- •4.4 Оператор циклу for
- •4.5 Оператор циклу while
- •4.6 Оператор циклу do while
- •4.7 Оператор break
- •4.8 Оператор continue
- •5 Функції
- •5.1 Основні поняття
- •5.2 Види виклику функцій
- •5.3 Область видимості
- •5.4 Порожній тип void
- •5.5 Передача аргументів у функцію
- •5.6 Рекурсивні функції
- •5.7 Прототипи функцій
- •6 Покажчики
- •6.1 Визначення та ініціалізація покажчиків
- •6.2 Визначення покажчиків
- •6.3 Масиви
- •6.4 Операції порівняння
- •6.5 Копіювання рядка
- •6.6 Покажчики на функцію
- •6.7 Покажчики на void
- •6.8 Арифметика покажчиків
- •7 Масиви
- •7.1 Загальні поняття
- •7.2 Одновимірні масиви
- •7.3 Багатовимірні масиви
- •8 Рядки в с
- •8.1 Рядки
- •8.2.Створення рядків
- •8.3 Прототипи
- •8.3 Функції перетворення буферів
- •8.4 Функції перевірки літер
- •8.5 Операції з рядками
- •9 Структури, об’єднання, перерахування
- •9.1 Структури
- •9.2 Бітові поля
- •9.3 Ключове слово typedef
- •9.4 Об’єднання
- •9.5 Перераховуваний тип
- •10 Введення та виведення даних
- •10.1 Функція виведення printf
- •10.2Функція введення scanf
- •10.3 Введення та виведення у файл
- •11 Динамічне виділення пам'яті
9 Структури, об’єднання, перерахування
9.1 Структури
Структура – це конструкція, що дозволяє об’єднувати в собі набір змінних різних типів.
Також під структурою розуміють сукупність логічно зв’язаних даних різних типів.
При визначенні структури створюється новий тип, на основі простих і (або) похідних типів.
Синтаксис визначення структури:
struct <назва структури>
{
<опис елементів>
};
де назва структури – це ім’я типу структури;
опис елементів – програмний блок, де приводиться визначення елементів.
Визначення структури може не містити імені. Такі структури називаються анонімними.
Змінні типу структури називають об’єктами структури. Для виділення пам’яті під об’єкт структури необхідно оголосити змінну типу структури.
Синтаксис оголошення змінної типу структури:
struct <назва структури> < ім’я змінної>;
де ім’я змінної – це ідентифікатор, який використовується для доступу до об’єкту структури;
назва структури – ім’я типу структури.
Приклад 9.1. Визначення структури та створення об’єкту структури.
struct lab
{
int num;
char* name;
}; /* визначення структурного типу з
іменем lab */
int main(void)
{
struct lab Lаb_10; /* створення об’єкту Lab_10 типу струк-
тури lab. */
return 0;
}
Можна одночасно визначати структурний тип і створити об’єкт даного типу:
Приклад 9.2. Оголошення об’єкту зразу після створення структури.
struct gr /* ім’я структурного типу */
{
short int day; /* елемент структури */
int month,year; /* однотипні елементи структури */
} date; /* ім’я структурної змінної */
Елементи структури називають полями (day, month, year). Поля можуть бути будь-якого базового чи похідного типу, наприклад, масивом, покажчиком, об’єднанням або іншою структурою.
При зверненні до полів структури використовуються операції прямого та непрямого доступу:
Операція прямого доступу “.” (крапка) пов'язує ім'я структури з полем структури:
Імя структури.поле
Операція непрямого доступу “->”(стрілка) пов’язує покажчик на структуру з полем структури :
Покажчик на структуру->поле.
Приклад 9.3. Застосування прямого та непрямого доступу.
date.day=10; /* звернення до поля day через
об’єкт date */
struct gr *ptrdate=&date; /* створення покажчика ptrdate
на об’єкт date */
ptrdate->year=2012; /* ініціалізація поля year через
покажчик на об'єкт ptrdate */
Введення/виведення даних у структуру виконується поелементно.
Приклад 9.4. Введення даних в поле day структури date.
scanf(“%i”, &date.day);
Структури одного типу можна копіювати. Структури, пам’ять під які виділяється на етапі компіляції, можна ініціалізувати, перераховуючи значення їх елементів.
Приклад 9.5. Ініціалізація полів структури gr.
struct gr date = {1, 2, 3}.
Приклад 9.6. Створення масиву структур.
struct date { /* структура для опису дати*/
int day, month, year;
};
int main(void)
{
struct date d[5]={{1,3,1980},{5,1,1990},{1,1,2002}};
/* масив з 5-ти структур типу date , кожна з
яких складається з 3-х елементів типу int,
яким надаються початкові значення*/
return 0;
}
Приклад 9.7. Написати програму, яка буде зчитувати дані про студентів, і виводити інформацію про них за введеним прізвищем. Приклад структури наведений у таблиці 9.1.
Таблиця 9.1 – Структура з даними про студентів
Назва |
Індекси |
|||||||||||
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 |
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
struct Spysok
{
char PIB[20]; /* прізвище студента*/
char Grup[10]; /* назва групи*/
int Ot[3]; /* 3 оцінки*/
float S_Bal; /* середній бал*/
} *vid; /* покажчик на структуру*/
void Vvid(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);
float s=0;
for(int i=0; i<3; i++)
{
printf("\n Otsinki – ");
scanf("%i", &vid->Ot[i]);
s+=vid->Ot[i];
}
vid->S_Bal=s/3;
}
int main(void)
{
struct Spysok Stud[50];
int i, N;
char Litera;
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;
}
Результат роботи програми:
Перевизначення структур в межах однієї області видимості не дозволяються, за виключенням випадку коли перевизначення здійснюється в різних програмних блоках. У випадку визначення структури у окремому програмному блоці, область видимості цього визначення закінчується з закінченням програмного блоку, в якому міститься це визначення.
Приклад 9.8. Області видимості визначень структур.
struct st /* Глобально-видиме визначення */
{
int ivar;
char pstr[8];
};
void func(void)
{
struct st; /* Визначення, яке видиме тільки в межах
функції func */
{
int ivar;
char pstr[8];
float fvar;
};
/* ... */
}
/* ... */
Код, наведений у прикладі 9.8 є коректним. Але слід застерегти від подібного роду перевизначень, що суттєво ускладнюють розуміння і супроводження програм, написаних у такому стилі.