Первая страница
Наша команда
Контакты
О нас

    Головна сторінка



Та програмування

Та програмування




Сторінка6/11
Дата конвертації10.03.2017
Розмір2.35 Mb.
1   2   3   4   5   6   7   8   9   10   11
активації)

cprintf(" Dii ");

Актива́ція - збудження чогось, наприклад, молекул, атомів; перехід молекули з неактивного стану в стан з енергією, достатньою для здійснення хімічної реакції, наприклад, механохімічна активація .

- пишемо Dii

break;
case 3: (активне Poshyk)

textcolor(0);

- встановлюємо чорний колір шрифта

textbackground(7);

- встановлюємо яскраво-сірий фон

gotoxy(8,1);

- переходимо до мітки з координатами (8,1)

cprintf(" Dii ");

- пишемо Dii

textcolor(0);

- встановлюємо чорний колір шрифта

textbackground(2);



- встановлюємо зелений фон

cprintf(" Powyk ");

- пишемо Poshyk

break;
case 4: (активне Help )

textcolor(0);

- встановлюємо чорний колір шрифта

textbackground(7);

- встановлюємо яскраво-сірий фон

gotoxy(14,1);

- переходимо до мітки з координатами (14,1)

cprintf(" Powyk ");

- пишемо Poshyk

textcolor(0);

- встановлюємо чорний колір шрифта

textbackground(2);

- встановлюємо зелений фон

cprintf(" Help ");

- пишемо Help

break;

default: (активне File)



MIndex=MinMIndex;

textcolor(0);

- встановлюємо чорний колір шрифта

textbackground(2);

- встановлюємо зелений фон

gotoxy(2,1);

- переходимо до мітки з координатами (2,1)

cprintf(" File ");

- пишемо File

gotoxy(22,1);

- переходимо до мітки з координатами (22,1)

textcolor(0);



  • встановлюємо чорний колір шрифта

textbackground(7);

- встановлюємо яскраво-сірий фон

cprintf(" Help ");



  • пишемо Help

break;//default

}// end switch(MIndex)

break;//end ch = 77


Для організації руху вправо (код клавіші 75) використовується програмний код, аналогічний описаному вище:


case 75:

MIndex--;

switch (MIndex)

{

case 1:



textcolor(0);

textbackground(7);

gotoxy(8,1);

cprintf(" Dii ");


/*Edit*/

textcolor(0);

textbackground(2);

gotoxy(2,1);

cprintf(" File ");

break;
case 2:

textcolor(0);

textbackground(7);

gotoxy(14,1);

cprintf(" Powyk ");


/*Search*/

textcolor(0);

textbackground(2);

gotoxy(8,1);

cprintf(" Dii ");
/*Edit*/

break;
case 3:

textcolor(0);

textbackground(7);

gotoxy(22,1);

cprintf(" Help ");

textcolor(0);

textbackground(2);

gotoxy(14,1);

cprintf(" Powyk ");


/*Search*/

break;


default:

MIndex=MaxMIndex;

textcolor(0);

textbackground(7);

gotoxy(2,1);

cprintf(" File ");

textcolor(0);

textbackground(2);

gotoxy(22,1);

cprintf(" Help ");

break;//default

}// end switch(MIndex)

break;//end 75
case 13: // if enter press

PMIndex = 1;

switch (MIndex)

{

case 1: podmenu1(); break;



case 2: podmenu2(); break;

case 3: podmenu3(); break;

case 4: podmenu4(); break;

}// end switch(MIndex) for Podmenu

break; // 80 Down

case 27: // Esc

exit(1);

} //end switch(ch)

} //end while(1==1)

}// end main()


3.5 Контрольні запитання


  1. Які стандартні бібліотеки необхідно підключити при створенні багатоієрархічного меню?

  2. Які параметри повинна мати функція, що рисує вікна у меню?

  3. Як нарисувати вікно з подвійною рамкою?

  4. Як в поточному вікні здійснити відкриття ще одного вікна?

  5. За допомогою яких функцій встановлюється колір тексту та колір фону?

  6. Як створити рядок головного меню програми?

  7. Як організувати переміщення клавішами по основних пунктах меню?

  8. Як створити підменю?

  9. Як реалізувати рух по підменю?

  10. Як здійснити вихід з підменю?

  11. Як здійснити вихід з головного меню?

3.6 Практикум з програмування


  1. Написати фрагмент програми для створення вікна за заданими координатами.

  2. Написати фрагмент програми для створення вікна з подвійною рамкою.

  3. Написати фрагмент програми, в якому б задавалася кількість пунктів меню.

  4. Розробити фрагмент програми, яка б створювала рядок горизонтального меню.

  5. Написати фрагмент програми, який би дозволяв здійснювати рух по пунктах головного меню.

  6. Написати фрагмент програми для створення вікна висхідного меню.

  7. Написати фрагмент програми для здійснення руху по пунктах підменю.

4 ОСОБЛИВОСТІ ПОБУДОВИ ГРАФІКА ФУНКЦІЇ
АЛГОРИТМІЧНОЮ МОВОЮ С

4.1 Загальні відомості
Побудова на екрані дисплея графіка функції– це цікава алгоритмічна задача, розв’язання якої починається з табулювання функції (тобто представлення функції за заданими точками). Метою такого подання даних є отримання рисунка потрібного розміру, що відображає тенденції змінни функції.
Тенденція і тенденційність (від лат. tendo - направляю, прагну) - можливість тих чи інших подій розвиватися в даному напрямку.
Такий рисунок зручно використовувати у публікаціях, технічній документації, презентаціях тощо.

Професійний програмний продукт повинен не просто відображати графік функції на відрізку , а також дозволяти користувачу виконувати різні перетворення над графіком. До операцій перетворення можна віднести:



    1. паралельний перенос осей координат;

    2. зміна масштабів по осях координат;

    3. зміна орієнтації осей координат;

    4. перетворення абсолютних величин на графіку.
      Абсолютний (від лат. absolutus) - безумовний, необмежений, повний, безвідносний.
      Масштаб, мірило (від нім. Maß - міра, і нім. Stab - палка) - відношення розмірів об'єкта, виконаних без спотворень, до інших номінальних значень. Масштаб це число, що може бути більше 1, якщо розміри об'єкту ненадійні, креслення дрібних деталей) - це називають масштабом збільшення, або менше 1 (плани будинків, топографічні та географічні карти, карти зоряного неба) - масштаб зменшення.
      Документа́ція - сукупність офіційно визнаних, взаємопов'язаних та складених у визначеній формі документів, які містять передбачувану інформацію про виріб, процес або діяльність даного підприємства. Відповідно до області застосування Документа́цій поділяється на бухгалтерську, конструкторську, нормативну, технічну, товарну, тощо.
      Абсолютна величина чи модуль - у математиці, величина, значення або число незалежно від знака. Абсолютна величина числа n записується |x| (іноді - Abs(x) ) і визначається як додатній квадратний корінь з x².


В цьому розділі посібника розглядається приклад програми мовою С для побудови графіка функції заданого вигляду.
Програма починається з підключення стандартних бібліотек:

#include

#include

#include

#include

#include


void graf(float*,float*,int) – це функція, за допомогою якої будемо рисувати графік функції двох змінних. В заголовку функції float* – вказівник на масив x, float* – вказівник на масив y, int – кількість точок в цьому масиві.

void graf(float*,float*,int);

void Tablycia(float*,float*,int,int) – це функція, за допомогою якої будуємо таблицю залежності функції х від у (float* – вказівник на масив x, float* – вказівник на масив y, int, int – номери елементів х і у, перший і останній).

void Tablycia(float*,float*,int,int);

int MAX(float*,int) – це функція для знаходження максимального числа х або у.

int MIN(float*,int) – це функція для знаходження мінімального числа х або у.


Головна програма:

void main()

{

clrscr();



kol – кількість точок масиву

int kol=1;



*x – вказівник на масив х, *y – вказівник на масив у, xo – початкова точка, xn – кінцева точка, kr – крок

float *x,*y, xo, xn, kr;


Вводимо початкові, кінцеві значення та крок:

printf("Xo="); scanf("%f",&xo);

printf("Xn="); scanf("%f",&xn);

printf("Krok="); scanf("%f",&kr);

Це виглядає так:







Умова if(fmod(xn-xo,kr)==0) перевіряє чи (xn-xo) з кроком kr=0

if(fmod(xn-xo,kr)==0)

якщо так, то kol=(xn-xo)/kr;

якщо ні, то else kol=(xn-xo)/kr 1;
Виділяємо пам’ять під два масиви: х і у

x=(float*)calloc(kol,sizeof(float));

y=(float*)calloc(kol,sizeof(float));

і – номер елемента масива

int i=0;
Вираз while(iі менше за кількість точок

while(i
Вираз x[i]=xo i*kr; означає: формуємо масив х

{

x[i]=xo i*kr;



//y[i]=cos(x[i]);

//y[i]=sin(x[i])

//y[i]=tan(x[i]); функції, які необхідно побудувати

//y[i]=log(x[i]);

//y[i]=cos(x[i])*exp((-1)*x[i]);

i – додаємо крок

i ;

}

graf(x,y,kol); – викликаємо функцію рисування графіка



graf(x,y,kol);
Звільняємо пам’ять х і у:

free(x);


free(y);

closegraph();

}
Нижче на рисунках 4.1 – 4.3 показано, як за допомогою запропонованої програми будуть виглядати певні функції. Функція y[i]=cos(x[i]) буде мати вигляд, наведений на рисунку 4.1.

Рисунок 4.1 – Рисування графіка cos(x)
Функція y[i]=sin(x[i]) буде мати вигляд, наведений на рисунку 4.2.

Рисунок 4.2 – Рисування графіка sin(x)

Функція y[i]=tan(x[i]) буде мати вигляд, наведений на рисунку 4.3.



Рисунок 4.3 – Рисування графіка tan(x)


Заголовок функції void graf(), де *xmas – масив значень точек по осі х, *ymas – масив значень точок по осі у, kill – кількість точок, має вигляд:
void graf(float *xmas,float *ymas,int kill)
4.2 Ініціалізація графіки
Для ініціалізації графіки можна використати стандартний набір операторів:

{

int gdriver = DETECT, gmode, errorcode;



initgraph(&gdriver, &gmode, "");

errorcode = graphresult();

if (errorcode != grOk)

{

printf("Graphics error: %s\n",



grapherrormsg(errorcode));

printf("Press any key to halt:");

getch();

exit(1); }

cleardevice(); – очищуємо екран

cleardevice();

setcolor(4); – задаємо колір вікна (4 – червоний)

setcolor(4);

outtextxy(270,2,"Grafik funkcii"); – виводимо з координатами х=270 та у=2 напис "Grafik funkcii"

outtextxy(270,2,"Grafik funkcii");


4.3 Введення даних
Для організації введення даних можна використати такі змінні:

q – змінна, якій присвоюється індекс масива;
Індекс (лат. index від indico - вказую, subscript) - число, букви або інша комбінація символів, що вказує місце елемента в сукупності або характеризує стан деякої системи (список, реєстр, покажчик). символ, який зв'язаний з іменем множини для визначення конкретної підмножини або її елементу; вираз, що вказує номер елементу масива; список, покажчик, перелік будь-чого; реквізит, що дозволяє забезпечити оперативний довідково-інформаційний пошук документа, його схоронність і контроль виконання; цифровий показник послідовних змін у розвитку будь-якого економічного явища: обсягу виробництва роздрібних цін реальної заробітної плати тощо.

char *xmax – максимальне х ,



*xmin – мінімальне х,

*ymax – максимальне у,

*ymin – мінімальне у,

*kiln – кількість точок;

int q;


float xmin, ymin, xmax, ymax;

Вираз q=MIN(xmas,kill) означає повернення номера найменшого елемента х.

xmin=xmas[q]; – присвоєння хmin значення найменшого x.

xmin=xmas[q];


Вираз q=MIN(ymas,kill); означає повернення номера найменшого елемента у.

ymin=ymas[q]; – присвоєння ymin значення найменшого y.

ymin=ymas[q];
Вираз q=MAX(xmas,kill); означає повернення номера найбільшого елемента х.

xmax=xmas[q]; – присвоєння хmax значення найбільшого x.


Вираз q=MAX(ymas,kill); означає повернення номера найбільшого елемента у.

ymax=ymas[q]; – присвоєння ymax значення найбільшого y.

setcolor(4); – задаємо колір поточного вікна.

setcolor(4);

setfillstyle (1,8); – задаємо тип та колір вікна відповідно.

bar (80,380,330,460); – рисуємо прямокутник з координатами по х: (80-380) та по у (380-460).

setcolor(14); - задаємо колір поточного вікна

setfillstyle (1,7); - задаємо тип та колір поточного вікна відповідно.


Рисуємо прямокутник:

rectangle(76,376,334,464);


Далі аналогічно будуємо ще 3 прямокутники:

setcolor(10);

Анало́гія - (грец. αναλογια - «відповідність») - подібність, схожість у цілому відмінних предметів, явищ за певними властивостями, ознаками або відношеннями.

rectangle(73,373,337,467);

setcolor(11);

rectangle(70,370,340,470);

setcolor(13);

rectangle(67,367,343,473);

setcolor(14);

setfillstyle(1,7);

rectangle(80,380,330,460);


В результаті отримуємо вікно для рисування графіка у вигляді, наведеному на рисунку 4.4.

Рисунок 4.4 – Рисування вікна
Вираз sprintf(x_min,"%4.1f",xmin); означає, що перетворюємо змінну xmin типу float у змінну x_min типу char.

За допомогою функції outtextxy(210,400,"X_min="); виводимо по координатах поточного вікна (210,400) надпис X_min=.

За допомогою outtextxy(260,400,"х_min="); виводимо по координатах поточного вікна (260,400) значення мінімального х (х_min=).

В результаті отримуємо вікно для виведення на екран інформації про фунцію, графік якої будується, у вигляді, наведеному на рисунку 4.5.


Рисунок 4.5 – Рисування вікна min-max без значень


Далі виконуємо аналогічні дії для визначення мінімальних значень х та у, а також для максимального у та визначимо N – кількості точок, необхідних для побудови графіка. Фрагмент програми, що дозволяє отримати таку інформацію, має вигляд:
sprintf(y_min,"%4.1f",ymin);

outtextxy(210,420,"Y_min=");

outtextxy(260,420,y_min);

sprintf(x_max,"%4.1f",xmax);

outtextxy(100,400,"X_max=");

outtextxy(150,400,x_max);

sprintf(y_max,"%4.1f",ymax);

outtextxy(100,420,"Y_max=");

outtextxy(150,420,y_max);

sprintf(kiln,"]",kill);

outtextxy(175,440,"N=");

outtextxy(175,440,kiln);


В результаті отримуємо вікно з інформацією про мінімальні та максимальні значення функції, що досліджується, у вигляді, показаному на рисунку 4.6.

Рисунок 4.6 – Рисування вікна min-max зі значеннями
4.4 Алгоритм побудови графіка табличної функції
//**************VIKNO GRAFIKA*******************

1. Задаємо стиль функцією setfillstyle (1,8), тобто поточний тип ліній (1 – суцільний) та колір (8 – темно-синій).

2. Рисуємо вікно з координатами по х (40,380) та у (80,320)

bar (40,80,380,320);

3. Задаємо поточний колір прямокутника (рамки) – 14 (жовтий) оператором setcolor(14);

4. Задаємо стиль функцією setfillstyle (1,7);, тобто поточний тип ліній (1 – суцільний) та колір (7 – сірий).

5. Рисуємо прямокутник (рамку) з координатами по х (40,380) та у(80,320) за допомогою функції rectangle(40,80,380,320).

6. Виконуємо аналогічні операції, тільки з іншими координатами та різними кольорами (12 – яскраво-червоний, 10 – яскраво-зелений, 11 – яскраво-блакитний) за допомогою операторів:


setcolor(12);

rectangle(27,67,393,333);

setcolor(10);

rectangle(30,70,390,330);

setcolor(11);

rectangle(33,73,387,327);

setcolor(13);

rectangle(36,76,384,324);

}

7. Встановлюємо поточний колір (в даному випадку – це колір осей та розмітки осей) оператором setcolor (YELLOW).



8. За допомогою функції line(х1,у1,х2,у2); будуємо осі, стрілочки, та розмітку осей, де х1, у1 – початкові координати по х і у відповідно; х2, у2 – кінцеві координати по х і у відповідно. Для цього можна використати такий набір операторів:
//вертикальна ось

line(210,100,210,300);


//стрілочка

line(210,100,205,110);

line(215,110,210,100);
//горизонтальна ось

line(50,210,370,210);


//стрілочка

line(370,210,360,205);

line(360,215,370,210);
В результаті отримуємо вікно для рисування графіка з осями х та у у вигляді, наведеному на рисунку 4.7.

Рисунок 4.7 – Рисування осей x i y


9. Для розмітки осей можна використати такий набір операторів:
//вертикальна розмітка осей

{setcolor(14);

line(207,130,213,130);

line(207,140,213,140);

line(207,150,213,150);

line(207,160,213,160);

line(207,170,213,170);

line(207,180,213,180);

line(207,190,213,190);

line(207,200,213,200);

line(207,220,213,220);

line(207,220,213,220);

line(207,230,213,230);

line(207,240,213,240);

line(207,250,213,250);

line(207,260,213,260);

line(207,270,213,270);

line(207,280,213,280);


//вертикальна розмітка осей

setcolor(14);

line(60,207,60,213);

line(70,207,70,213);

line(80,207,80,213);

line(90,207,90,213);

line(100,207,100,213);

line(110,207,110,213);

line(120,207,120,213);

line(130,207,130,213);

line(140,207,140,213);

line(150,207,150,213);

line(160,207,160,213);

line(170,207,170,213);

line(180,207,180,213);

line(190,207,190,213);

line(200,207,200,213);

line(210,207,210,213);

line(220,207,220,213);

line(230,207,230,213);

line(240,207,240,213);

line(250,207,250,213);

line(260,207,260,213);

line(270,207,270,213);

line(280,207,280,213);

line(290,207,290,213);

line(300,207,300,213);

line(310,207,310,213);

line(320,207,320,213);

line(330,207,330,213);

line(340,207,340,213);

line(350,207,350,213);

}
10. Встановлюємо жовтий колір напису оператором setcolor(14);

Жо́втий - колір з довжиною хвилі від 565 нм до 590 нм. Один з стандартизованих відтінків жовтого є компонентом системи CMYK. Є додатковим кольором до синього. В стародавні часи, через недосконалість пігментів розглядався, як додатковий до пурпурного.
та виводимо "X" з координатами (370,215) функцією outtextxy(370,215,"X"); виводимо "У" з координатами (195,100) функцією outtextxy(195,100,"Y"). Визначаємо точку перетину осей функціями

outtextxy(200,215,"0");

setfillstyle(1,4);

В результаті отримуємо вікно для рисування графіка з розміткою осей координат у вигляді, показаному на рисунку 4.8.



Рисунок 4.8 – Рисування осей координат з розміткою
11. Встановлюємо поточний білий колір функцією setcolor(15).

12. Описуємо змінні: kx, ky – коефіцієнти, з якими стискується графік по х і у відповідно

float kx,ky,mx,my;

if (fabs(xmin)>xmax) mx=fabs(xmin); else mx=xmax;

if (fabs(ymin)>ymax) my=fabs(ymin); else my=ymax;

(400-80) означає: рисуємо графік з координати 80 до координати 400 по х

kx=(400-80)/(2*mx); //коефіцієнти 20

(400-180) означає: рисуємо графік з координати 180 до координати 400 по у

ky=(400-180)/(2*my);

13. Визначення коефіціенту стиску. Умову if (kx

if (kx

else kx=ky;


14. Рисування графіку. Задаємо цикл:

for(int j=1;j //рисування графіка

для побудови графіка за допомогою line

line(kx*xmas[j] 210,210-ky*ymas[j],kx*xmas[j 1] 210,210-ky*ymas[j 1]);


В результаті отримуємо вікно для рисування графіка у вигляді, наведеному на рисунку 4.9.

Рисунок 4.9 – Рисування косинусоїди
4.5 Створення вікна таблиці для виведення даних

//******************VIKNO TABLICI***********

1. Ініціалізуємо ще одну змінну int ch для роботи з клавіатурою

int ch;

2. Присвоюємо змінній і значення 35 – це кількість пар точок х і у

int i=35;

if(kill<35) означає: якщо кількість точок менша за 35, то виводимо на екран таблицю залежності у від х; Tablycia(xmas,ymas,0,kill): xmas – масив х-ів, ymas – масив у-ів, 0 – це початкова точка, kill – всі пари точок.

if(kill<35)

Tablycia(xmas,ymas,0,kill);

якщо кількість таких пар більша за 35, то виводимо табуляцію, але тільки з кількістю точок, що дорівнює 35.

else {


Tablycia(xmas,ymas,0,35);
3. Нескінченний цикл необхідний для того, щоб можна було рухатись по таблиці табуляції нескінченно):

while(1)


{

Вираз ch=getch() означає, що йде зчитування коду клавіші.

Вираз if(ch==27) перевіряє чи дорівнює змінна коду 27, а це код клавіші Esc. Якщо так, то exit(0), тобто виконується вихід з програми.

if(ch==27) exit(0);

Вираз if(ch==80) перевіряє чи дорівнює змінна коду 80, а це код клавіші ↓.

if(ch==80) { //донизу

4. Використовуємо умову

if(kill-i<=35), тобто якщо кількість точок менша за 35, то виводимо на екран

Tablycia(xmas,ymas,i,kill);

якщо не менша, то виводимо табуляцію з кількістю точок і 35. Інакше використовуємо такі оператори:

else

{

Tablycia(xmas,ymas,i,i 35); i =35;



}

}

5. Далі виконуємо такі ж операції, але уже для того, щоб рухатись по таблиці вгору*/


6. Вираз if(ch==72) перевіряє чи дорівнює змінна коду 80, а це код ↑.

if(ch==72) { //Vverh

if(i<35&&i>=0)

{Tablycia(xmas,ymas,0,35); i=0;}

else

{Tablycia(xmas,ymas,i-35,i); i-=35; }



}

}

}



}

Функція Tablycia() має такий заголовок:

void Tablycia(float *x,float *y,int p,int k),

де

float *x – масив значень точок по осі х,



float *y – масив значень точок по осі у,

int p – перша точка, з якої починаємо таблицю табуляції,

int k – кінцева точка табуляції.
7. За аналогією як будувалося вікно для графіка, встановлюємо колір фону, тексту, стиль, зокрема тип ліній, будуємо вікна, за допомогою таких операторів:

setcolor(15);

setfillstyle(1,8);

rectangle(440,50,600,430);

floodfill(455,70,15);

{

setcolor(14);



rectangle(440,50,600,430);

setcolor(12);

rectangle(436,46,604,434);

setcolor(10);

rectangle(433,43,607,437);

setcolor(11);

rectangle(430,40,610,440);

setcolor(13);

rectangle(427,37,613,443);

}

В результаті отримуємо вікно для таблиці значень функції у вигляді, наведеному на рисунку 4.10.



Рисунок 4.10 – Рисування вікна, де буде розміщена табуляція
8. Для рисування таблиці в цьому вікні використовуємо такі оператори:
setcolor(14);

line(520,50,520,430);

line(440,70,600,70);

setcolor(14);

outtextxy(480,60,"X");

outtextxy(550,60,"Y");

В результаті отримуємо вікно для виведення таблиці значень функції у вигляді, наведеному на рисунку 4.11.

.


Рисунок 4.11 – Рисування вікна, буде розміщена табуляція
9. Для виведення числових значень функції у вигляді таблиці в графічне вікно виконуємо перетворення їх в рядок. Для цього описуємо змінні char *vr1,*vr2, де *vr1 – тимчасова змінна, призначена для перетворення змінних (по х) з float в int; *vr2 – тимчасова змінна, призначена для перетворення змінних (по у) з float в int та використовуємо оператори:
char *vr1,*vr2;

int ytab,j;

for(ytab=75,j=p;j

{

sprintf(vr1,"%4.1f",x[j]);



outtextxy(465,ytab,vr1);
перетворюємо змінні float в int

sprintf(vr2,"%4.1f",y[j]);

outtextxy(540,ytab,vr2);

}

}


В результаті отримуємо вікно з таблицею значень функції у вигляді, наведеному на рисунку 4.12.

Рисунок 4.12 – Рисування вікна табуляції функції
10. Наступна функція int MAX()призначена для пошуку максимального значення в масивах х і у

int MAX(float *m,int n)

де*m – масив х-ів або у-ів, int n – кількість елементів в масиві.

{ float z; int imax;


Тимчасовій змінній z присвоюємо початковий номер елемента у масиві, а змінній imax – мінімальне значення.

z=m[0]; imax=0;


11. Задаємо цикл для пошуку максимального значення в масиві:

for(int i=1;i

{
Якщо поточний номер елемента більший за початковий, тобто if(m[i]>=z)

{

то початковому значенню присвоюємо нове



z=m[i];

номеру максимального елемента присвоюємо теж новий індекс

imax=i;

}

}



Повертаємо imax: return imax;

}
12. Створюємо функцію int MIN(float *m,int n)для знаходження мінімального значення. Принцип його знаходження такий самий, як для максимуму. Для цього використовуємо оператори:


int MIN(float *m,int n)

{ float z; int imin;

z=m[0]; imin=0;

for(int i=1;i

{

if(m[i]<=z)



{

z=m[i]; imin=i;

}

}

return imin;



}

Отже, для функції y[i]=cos(x[i]) вікно графіка має вигляд:


Рисунок 4.13 – Загальний вигляд вікна для побудови графіка функції

4.6 Контрольні запитання


  1. Які стандартні бібліотеки необхідно підключити при побудові графіка функції в С?

  2. Як реалізувати функцію, що рисує графік?

  3. Як реалізувати функцію, що будує таблицю залежності х від у?

  4. Як перевірити, чи крок табулювання функції більше нуля?

  5. Графіки яких функцій можна побудувати засобами мови
    програмування С?

  6. Як реалізувати цикл рисування графіка функції?

  7. Як перетворити змінні одного типу даних в інший? Для чого це може бути потрібно?

  8. Як здійснити виведення таблиці значень?

  9. Як побудувати осі графіка?

  10. Як на осях графіка відобразити шкалу значень?

  11. Як вивести графік табличної функції в окремому вікні?

4.7 Практикум з програмування




  1. Розробити функцію, що перетворювала б дані типу float в дані типу int.

  2. Написати фрагмент програми для виведення таблиці значень масивів X та Y в окремому вікні.

  3. Написати фрагмент програми для виведення max_x, max_y, min_x, min_y в окремому вікні.

  4. Написати фрагмент програми для побудови осей графіка табличної функції та розбиття його на поділки.

  5. Як промасштабувати табличну функцію Y(x)?

  6. Написати фрагмент програми для масштабування функції y=cos(x).

  7. Написати фрагмент програми для масштабування функції y=sin(x).

  8. Написати фрагмент програми для масштабування функції y=tan(x).

  9. Написати фрагмент програми для масштабування функції y=log(x).

5 ОСНОВНІ ПРИНЦИПИ РОБОТИ З ПОТОКАМИ ДАНИХ

5.1 Загальні відомості


Бібліотека мови С підтримує три рівня введення – виведення:

  • потоковий;

  • введення – виведення низького рівня;

  • консольне введення – виведення (спеціалізований обмін даними з дисплеем та портами введення – виведення).

На рівні потокового введення – виведення обмін даними виконується побайтно, що зручно як для файлів на диску так і для пристроїв побайтного обміну (прінтер, дисплей).

Функції бібліотеки введення – виведення мови С підтримують обмін даними з файлами на рівні потоку та дозволяють обробляти дані різних розмірів та форматів за допомогою буфера, тому поток – це файл з засобами буферизації. Файл – це іменована область на диску, призначена для зберігання текстових, символьних, аудіо-, відеоданих. Буфер – це частина оперативної пам’яті для тимчасового зберігання даних в процесі обміну.

В бібліотеці введення – виведення мови С існує ряд функцій, що підтримують роботу з потоками, такі як створення, введення-виведення, відриття-закриття, управління буферізацією, для використання яких необхідно підключення файлу stdio.h (#include). Однак використання цих функцій залежить від типу файлу (текстовий або бінарний), зв’язанного з потоком. В мові С розглядають два типи файлів: текстові і бінарні. Текстовий файл – це набір рядків заданого розміру, кожен з яких закінчується кодом #13 (CR) і кодом #10 (LF). Бінарний файл – це набір компонент заданого розміру, кожна з яких є набором байтів.
5.2 Читання і запис текстових файлів
Введення – виведення окремих символів

Одним з найбільш ефективних способів здійснення введення – виведення в потік одного символу є використання бібліотечних функцій getchar() і putchar().

Компонент (англ. component, нім. Komponente f) - різновид, складова частина чогось.
Бібліоте́ка або книгозбі́рня (грец. βιβλιον - книжка і θηκη - сховище, скриня) - культурно-освітній заклад, що здійснює збирання друкованих і рукописних матеріалів, проводить їх опрацювання і відображення у каталогах, організовує відповідне їх зберігання, збереження і обслуговування ними читачів.

getchar() – функція, що здійснює введення в потік одного символу. При звертанні вона повертає у функцію, яка її викликала, один введений символ. При читанні з потоку функцією getchar() може бути досягнуто кінця файлу. В цьому випадку операційна система у відповідь на спробу читання символу передає функції getchar () значення EOF (End of File).

putchar() – функція, що виводить в потік один символ, при цьому також повертає у функцію, яка її викликала, щойно введений символ.


Введення – виведення рядків

Бібліотека мови С для обміну рядками (масиву символів) через стандартні потоки містить функції gets() і puts(), які зручно використовувати при створенні діалогових систем. Обидві функції мають тільки один аргумент – вказівник s на масив символів. Якщо рядок прочитаний нормально, функція gets() повертає адресу того масиву s, в який відбувається введення рядка. В разі помилки повертається NULL.

Функція puts() у випадку успішного завершення повертає останній символ, який завжди є символом ’\n’. В разі помилки повертається EOF.
Прикла 5.1.: Використання функцій gets() і puts()

#include

char str1[ ] = ” ”;

int main ()

{

char name[80];



puts(str1);

gets(name);

return 0;

}
Будь-який рядок символів в мові С повинен закінчуватись нуль-символом ’\0’. В останній елемент масиву str1 нуль-символ буде записаний автоматично під час трансляції при ініціалізації масиву.

Трансляція (від старофр. translater, від лат. translatus, прикметник минулого часу від transferre - «передавати», «переносити», передача)


Форматне введення – виведення

Для роботи з стандартними потоками в режимі форматного введення – виведення визначені дві функції:

printf() – форматне виведення, перетворює дані з внутрішнього подання в символьний вигляд у відповідності з форматним рядком і виводить їх в потік. Дані, які перетворюються і виводяться, задаються як аргументи функції printf();

scanf() – форматне введення з вхідного потоку. Читає послідовності кодів символів з вхідного потоку та інтерпретує їх як цілі числа, дійсні числа, одиничні символи, рядки.

Інтерпретатор мови програмування (interpreter) - програма чи технічні засоби, необхідні для виконання інших програм, вид транслятора, який здійснює пооператорну (покомандну, построкову) обробку, перетворення у машинні коди та виконання програми або запиту (на відміну від компілятора, який транслює у машинні коди всю програму без її виконання).
Дійсні числа - елементи числової системи, яка містить у собі раціональні числа і, в свою чергу, є підмножиною комплексних чисел. Математична абстракція, яка виникла з потреб вимірювання геометричних і фізичних величин навколишнього світу, а також виконання таких математичних операцій як добування кореня, обчислення логарифмів, розв'язування алгебраїчних рівнянь.
Ці́лі чи́сла - в математиці елементи множини Z = =\lbrace \ldots -3,\,-2,\,-1,\,0,\,1,\,2,\,3\,\ldots \rbrace } яка утворюється замиканням натуральних чисел відносно віднімання. Таким чином, цілі числа замкнуті відносно додавання, віднімання та множення.


Для роботи з файлами задіяні такі функції:

fgetc(), getc() – введення (читання) одного символу з файлу;

fputc(), putc() – запис одного символу в файл;

fprintf() – форматне виведення у файл;

fscanf() – форматне введення (читання) з файлу;

fgets() – введення (читання) рядка з файлу;

fputs() – запис рядка в файл.
Функція fputs(const char *s, FILE *stream) записує обмежений символом ’\0’ рядок у потік, визначений вказівником stream, і повертає невід’ємне число. Символ ’\0’ в файл не переноситься, і символ ’\n’ не записується в кінці рядка замість ’\0’.

Функція fgets(char *s, int n, FILE *stream) – читає з визначеного вказівником stream потоку не більше (n-1) символів і записує їх в рядок, на який вказує вказівник s. Функція закінчує читання, як тільки прочитає (n-1) символів чи зустріне символ нового рядка ’\n’, який переноситься в рядок s. Додатково в кінець кожного рядка записується ознака кінця рядка ’\0’.

У випадку успішного завершення функція повертає вказівник s. При помилці чи при досягненні кінця файлу, при умові, що із файлу не прочитаний жоден символ, повертається значення NULL. В цьому випадку вміст масиву, який адресується вказівником s, залишається без змін. На відміну від fgets() функція gets() відкидає символ ’\n’.

Перед тим, як працювати з потоком, його необхідно ініціалізувати. При цьому потік зв’язується у виконуваній програмі зі структурою визначеного типу FILE. Визначення структурного типу FILE знаходиться в заголовному файлі stdio.h. В структурі FILE вміщуються компоненти, за допомогою яких ведеться робота з потоком: вказівник на буфер, вказівник поточної позиції в потоці та ін.

При відкритті потоку в програму повертається вказівник на потік, що є вказівником на об’єкт структурного типу FILE. Цей вказівник ідентифікує потік у всіх наспупних операціях.

Опера́ція (лат. operatio - дія, вплив) - дії, заходи, що виконуються за певним планом і спрямовані на вирішення якогось завдання, досягнення якоїсь мети або належить до кола функцій даного підприємства, установи, відділу, окремого працівника, певного обладнання тощо.

Вказівник на потік, наприклад fp, повинен бути описаний в програмі таким чином:


#include

FILE *fp;


Вказівник на потік набуває значення в результаті виконання функції відкриття потоку:
fp = fopen (ім’я_файлу, режим_відкриття);
Параметри функції fopen() є вказівниками на масиви символів, які вміщують відповідно ім’я файлу, зв’язаного з потоком, і рядок режимів відкриття. Однак ці параметри можуть задаватись і безпосередньо у вигляді рядка при виклику функції відкриття файлу:
fp = fopen ("file.txt","r");
де file.txt – ім’я деякого файлу, зв’язаного з потоком;

r – позначення одного з режимів роботи з файлом (тип доступу до потоку).

Після закінчення роботи з файлами рекомендується закрити їх явно. Для цього використовується функція fclose (вказівник на потік).

Відкритий файл можна відкрити повторно (наприклад, для зміни режиму роботи з ним) тільки після того, як файл буде закритий з допомогою функції fclose().


5.3 Читання і запис двійкових файлів
Текстові файли, незважаючи на своє широке поширення, є тільки одним з видів файлів, які можна зберігати на диску. Двійкові файли знайшли більш широке застосування в професійних програмах, тому що:

  1. одна з переваг збереження даних у двійкових форматах – швидкість (тобто немає необхідності перетворювати дані при передачі з диска в пам'ять і навпаки);
    Компа́кт-ди́ск (англ. compact disc) (CD) - переносний оптичний диск для збереження інформації (даних) у цифровому вигляді, тобто формату зберігання даних. Цей формат було спочатку розроблено для записування та відтворення лише звукозаписів, але пізніше, його було пристосовано для зберігання даних: (CD-ROM).


  2. інша перевага – пам'ять. Так, наприклад, змінна типу double займає 4 байти, а в текстовій формі набагато більше. Звичайно двійкові файли за розміром менші текстових і в більшості випадків програми обробляють їх швидше, ніж текстові.

Відкриття двійкових фалів

Для відкриття двійкового файлу необхідно:


  1. визначити файлову змінну File *fp;

  2. безпосереднє відкриття виконуєтся функцією fopen() по всіх режимах якої додається буква "b" або "rb" – читання, "wb" – записування, "ab" – дозаписування, "r b" – читання та записування в існуючому файлі, "w b" – читання та записування в існуючому або новому файлі, "a b" – дозаписування і читання з існуючого файлу.

Наприклад, оператор fp=fopen("test.txt","r b") відкриває файл для читання і записування в двійковому режимі. При відкритті можливі помилки (тобто програмні переривання), які можна передбачити за допомогою фрагмента програми:


File *out;

out = fopen (filename, "wb");

if ( ! out)

{

puts ("Саn't create file");



exit (1);

}
Існує два способи читання і записування двійкових файлів: послідовний і прямий (довільний).

5.4 Файли з послідовним доступом
Послідовна обробка корисна для швидкого запам'ятовування значень у файлах і для роботи з файловими даними, як з потоком байтів (аналогічно запису на магнітну стрічку).

На даний час як магнітні носії систем і пристроїв ЦМЗ найчастіше використовуються магнітні стрічки і диски. В системах ЦМЗ, що застосовуються в інформаційно-вимірювальній техніці, в основному використовуються магнітні стрічки.

Запис даних у файл з послідовним доступом
Приклад 5.2. Написати програму записування даних у послідовний файл
#include

#include

int main()

{

File *outf;



int i;
outf = fopen ("int.dat", "wb");
if ( ! outf)

{

puts ("Can’t create file");



exit (1);

}
puts ("Zapis into file");

for (i=0; i<100; i )

fwrite(&i, sizeof(int),1, outf);

fclose (outf);

return 0;

}
Для записування даних у двійковий файл використовується функція fwrite(), що містить чотири параметри:


  1. адресу змінної чи масиву змінних, з якого байти копіюються на диск;

  2. число байтів в одній змінній;

  3. число записуваних елементів: 1 для одного значення, або інше позитивне ціле число записуваних елементів масиву;
    Ціле число (англ. Integer) - поширений тип даних, що представляє ціле число.


  4. змінна файлового типу File *, відкритого в двійковому режимі.

Для записування у відкритий файл на диску масиву у 100 значень можна скористатися фрагментом програми:
int array[100];

fwrite(&array, sizeof(int),100,outf);

Читання даних з файлу послідовного доступу за допомогою функції fread()
Приклад 5.3. Написати програму для послідовного читання двійкових значень з файлу int.dat
#include

#include

int main()

{

File *inpf;



int I, val;

inpf = fopen ("int.dat", "rb");


if ( ! inpf)

{

puts ("Can’t create file");



exit (1);

}
for (i=0; i<100; i )

{

fread(&val, sizeof(int),1, inpf);



printf ("%d",val);

}
return 0;

}
Функція fread() вимагає тих же аргументів, що і функція fwrite(). Перший аргумент функції є адресою приймача, у який ця функція повинна скопіювати байти з диска, тому розмір цієї змінної достатній для запам'ятовування необхідної кількості байтів.

Для переміщення всього масиву зі 100 цілочислових значень з диска у файл можна використовувати фрагмент програми:


int array[100];

fread(&array, sizeof(int),1, inpf);


це буде самим швидким способом читання значень з диска в пам'ять.
5.5 Файли з довільним доступом
Особливістю таких файлів є те, що:

  1. файл складається з елементів (записів) однакової довжини (розміру). Кожен запис у файлі має номер;

  2. уздовж файлу переміщається вказівник, положення якого можна позиціонувати програмно за допомогою функції fseek().


Запис #0

Запис #1

Запис #n

Запис #2


  1. функція fseek() вимагає три аргументи:

    • змінна потоку типу File*, відкритого для двійкового доступу;

    • значення зміщення вказівника щодо заданої (чи поточної) позиції;

    • один із трьох компонентів:

SEEK_SET – зсув вказівника на число байтів, на які внутрішній вказівник пересувається вперед від початку файлу;

SEEK_CUR – зсув на число байтів вперед чи назад від поточної позиції вказівника, в залежності від знака константи;

SEEK_END – зсув на число байтів від кінця файлу в напрямку до початку.
Приклад 5.4. Написати програму для читання 11-го запису у файлі int.dat

#include

#include

int main()

{

File *inpf;



int val;

inpf = fopen (″int.dat″, ″rb″);

if ( ! inpf)

{

puts (″Can’t create file″);



exit (1);

}

fseek (inpf, 10*sizeof(int),SEEK_SET);



fread(&val, sizeof(int),1, inpf);

printf (″ Record #10 == %d″,val);

fclose(inpf);

return 0;

}
Другий аргумент у fseek() – добуток розміру в байтах змінної типу int на номер запису (10) шуканого значення.

Приклад 5.5. За допомогою функції fseek() і fwrite() модифікувати 11-й запис у файлі int.dat


#include

#include

int main()

{

File *outf;



int val=99; /*нове значення запису */

outf = fopen (″int.dat″, ″r b″);


if ( ! outf)

{

puts (″Can’t create file″);



exit (1);

}
printf(″Writing %d to record #10″,val);


/* модифікація 10-го запису */

fseek (outf, 10*sizeof(int),SEEK_SET);

fwrite(&val, sizeof(int),1, outf);

fclose(outf);

return 0;

}
5.6 Передача файлів між комп’ютерами


Сьогодні багато організацій мають у своєму розпорядженні кілька комп'ютерів, причому часто ці комп'ютери виявляються різних типів або різних моделей, а також мають несумісні формати дисків.
Організа́ція (від грец. ὄργανον - інструмент) - цільове об'єднання ресурсів для досягнення певної мети.
При використанні різних комп'ютерів більша перевага може бути досягнута при з'єднанні комп'ютерів через їхні послідовні порти з метою спільного використання ними інформації і/або програм. У багатьох випадках створення програм, що забезпечують обмін файлами для таких комп'ютерів через їхні послідовні порти, є проблематичним.

Однак існує досить швидкодійна й ефективна програма передачі файлів. Ця програма має ряд значних переваг: вона працює з будь-якими типами файлів на всіх типах комп'ютерів, що природно відрізняються один від одного своєю продуктивністю і, найголовніше, не використовують апаратного підтвердження зв'язку.

Продукти́вність англ. productivity, нім. Produktivität f) - у широкому розумінні - здатність давати продукцію.
У додаток до всього, програма може працювати навіть тоді, коли апаратне підтвердження зв'язку в принципі неможливе і непотрібне.

Підпрограми передачі файлів виконують свої функції, використовуючи програмне підтвердження зв'язку, і функціонують фактично в різних середовищах. Однак для рішення глобальної проблеми краще пожертвувати продуктивністю, збільшивши надійність системи.

Факт (від лат. factum - зроблене) - поняття, що має виражену суб'єкт-об'єктну природу, що охоплює справжню подію або наслідок діяльності (онтологічний аспект) і, що вживається для вираження особливого різновиду емпіричного знання, яке, з одного боку, здійснює вихідні емпіричні узагальнення, будучи безпосередньою основою теорії або здогадки, а з другого боку - несе у своєму вмісті сліди семантичного впливу останніх (логіко-гносеологічний аспект).
Наді́йність - властивість технічних об'єктів зберігати у часі в установлених межах значення всіх параметрів, які характеризують здатність виконувати потрібні функції в заданих режимах та умовах застосування, технічного обслуговування, зберігання та транспортування.

Програмне підтвердження зв’язку

Коли апаратне підтвердження зв'язку неможливе або непотрібне, єдиним способом, що дозволяє уникнути помилок переповнення регістра, що не можуть бути зареєстрованими безпосередньо під час передачі даних по каналу зв'язку, є введення програмного підтвердження зв'язку. Програмне підтвердження зв'язку працює в такий спосіб: комп'ютер-джерело посилає перший байт і переходить у стан чекання повернення від комп'ютера-приймача звітувального байта (байта, що підтверджує прийняття попереднього повідомлення). При одержанні звітувального байта, комп'ютер-джерело посилає наступний байт і знову переходить у стан чекання звітувального байта від комп'ютера-приймача.

Цей процес продовжується доти, доки весь файл повністю не буде переданий. Нижче наведені в термінах псевдо-С процедури передачі і прийому даних.


send()

{

while ( є байти для передачі ){



send( байт );

wait();


}

}
receive()

{

do {


receive_byte();

send( звітувальний байт );

} while( поки всі байти не зчитані );

}
При цьому підході передача даних не викликає ніколи переповнення регістра в порту-приймачі незалежно від того, наскільки велика різниця у швидкості виконання операцій комп'ютерів, між якими встановлений зв'язок.

При цьому типі підтвердження зв'язку є лише один недолік – швидкість передачі даних падає вдвічі в порівнянні з теоретично можливою. Це пояснюється тим, що при передачі одного байта інформації фактично відбувається передача двох байтів (згадайте про звітуючий байт).
Перекачування файлу

Першою необхідною підпрограмою є функція, що забезпечує передачу файлу через послідовний порт. У загальному випадку ця функція повинна відкрити файл, що буде переданий на інший комп'ютер, підрахувати його довжину, передати в порт-приймач довжину переданого файлу і, зрештою, перекачати сам файл. Функція send_file(), представлена нижче, призначена для розв’язання саме таких задач.


/* пеpекачка специфікованого файлу */

void send_file(fname)

char *fname;

{

FILE *fp;



char ch;

union {


char c[2];

unsigned int count;

} cnt;
if(!(fp=fopen(fname,"rb"))) {

printf("Вхідний файл не може бути відкритим\n");

exit(1);

}

send_file_name(fname); /* пеpедача імені файлу */



wait(PORT); /* очікування звітувального байта */
/* обчислення розміру вихідного файлу */

cnt.

Обчи́слення - є гілкою математики, зосередженою на функціях, похідних, інтегралах, і нескінченному ряду чисел. Цей предмет являє собою важливу частину сучасної математичної освіти. Воно складається з двох основних галузей - диференціального і інтегрального численнь, які пов'язують основні теореми обчислення.
count = filesize(fp);


/* pозміp посилання */

sport(PORT, cnt.c[0]);

wait(PORT);

sport(PORT, cnt.c[1]);


do {

ch = getc(fp);

if(ferror(fp)) {

printf(" помилка читання вихідного файлу\n");

break;

}
/* очікування готовності поpта-пpиймача */



if(!feof(fp)) {

wait(PORT);

sport(PORT, ch);

}

} while(!feof(fp));



wait(PORT);

/* очікування підтвердження отримання останнього байта*/

fclose(fp);

}
Функція send_file_name(), наведена нижче, встановлює відповідність між ім'ям прийнятого і переданого файлів.

/* Пеpекачка імені файлу */

void send_file_name(f)

char *f;

{

printf(" Очікування пеpедачі... \n");



do {

sport(PORT, '?');

} while(!kbhit() && !(check_stat(PORT)&256));

if(kbhit()) {

getch();

exit(1);


}

wait(PORT);/* очікування отримання звітувального байта */

printf("Пеpедано %s\n\n",f);
/* фактична пеpедача імені файлу */

while(*f) {

sport(PORT, *f );

wait(PORT); /* очікування отримання звітувального байта */

}

sport(PORT,'\0'); /* символ кінця рядка */



}
Функція send_file_name() призначена для розв’язання двох основних задач: по-перше, вона встановлює зв'язок з комп'ютером-приймачем шляхом передачі йому маркера запитання ('?') і чекає відповіді від нього у вигляді звітувального байта (як звітувальний символ використовується крапка. Однак можна за своїм розсудом використовувати інший символ). Після того, як зв'язок буде встановлено, здійснюється передача імені файлу. Ця функція завершує аварійно свою роботу при надходженні переривання від клавіатури.

Функція wait(), наведена нижче, очікує звіт від комп'ютера-приймача, що реалізує програмне підтвердження зв'язку.


/* очікування відповіді */

void wait(port)

int port;

{

if(rport(port)!='.') {



printf("помилка встановлення зв'язку \n");

exit(1);


}

}
Таким чином, при виявленні помилки ця функція припиняє свою роботу. Однак можна передбачити обробку даної ситуації.

Функція filesize() повертає розмір файлу в байтах. Її використання можливо, якщо компілятор С підтримує функцію обчислення довжини файлу, у протилежному випадку потрібно замінити цю функцію розробленою вами, але таку, що виконує аналогічні дії. Змінна cnt, що входить до складу структури union, служить для збереження двобайтової довжини файлу, але потрібно пам'ятати, що за одиницю часу можна переслати через послідовний порт тільки один байт.
Прийом файлу

Прийом файлу є прямо протилежною операцією передачі файлу. По-перше, функція прийому очікує маркер запиту на одержання даних (символ ‘?’). На одержання маркера функція відповідає крапкою (символом звітування). Після одержання імені файлу функція очікує одержання його розміру в байтах. В остаточному підсумку функція починає читання файлу. Після одержання і читання кожного байта функція посилає комп’ютерові-джерелу звітувальний байт. У такий спосіб вона реалізує програмне підтвердження зв’язку. Функція rec_file() наведена нижче.


Приклад 5.6 Прийом файлу
void rec_file()

{

FILE *fp;



char ch;

char fname[14];

union {

char c[2];



unsigned int count;

} cnt;
get_file_name(fname); /* одержання імені файлу */

printf(" Отриманий файл %s\n",fname);

remove(fname);

if(!(fp=fopen(fname, "wb"))) {

printf(" Неможливо відкрити вихідний файл \n");

exit(1);

}
/* Одержання довжини файлу */

sport(PORT, '.'); /* звітування */

cnt.c[0] = rport(PORT);

sport(PORT, '.'); /* звітування */

cnt.c[1] = rport(PORT);

sport(PORT, '.'); /* звітування */

for(; cnt.count; cnt.count--) {

ch = rport(PORT);

putc(ch, fp);

if(ferror(fp)) {

printf(" помилка запису у файл ");

exit(1);

}

sport(PORT, '.'); /* звітування */



}

fclose(fp);

}
Функція get_file_name() наведена нижче.
/* Одержання імені файлу */

void get_file_name(f)

char *f;

{

printf("Чекання одержання...\n");



while(rport(PORT)!='?') ;

sport(PORT, '.'); /* звітування */

while((*f=rport(PORT))) {

if(*f!='?') {

f ;

sport(PORT, '.'); /* звітування */



}

}

}


5.7 Контрольні запитання


  1. За допомогою яких функцій здійснюється введення-виведення одного символу?

  2. Для чого призначені функції gets() і puts()?

  3. Що являє собою текстовий файл?

  4. Які функції призначені для роботи з текстовими файлами?

  5. Напишіть функції, які здійснюють відкриття файлу, та вкажіть їх параметри?

  6. Які ви знаєте режими відкриття текстового файлу?

  7. Що таке двійковий файл?

  8. Які переваги двійкових файлів ви знаєте?

  9. Як здійснюється відкриття двійкових файлів?

  10. Які є способи читання і запису даних у двійкові файли? Наведіть приклад.

  11. Як здійснюється запис даних у файл з послідовним доступом? Наведіть приклад

  12. Як відбувається читання даних з файлу послідовного доступу? Наведіть приклад.

  13. Які особливості файлу з довільним доступом? Наведіть приклад.

  14. Як здійснюється перекачування файлів?

  15. Як відбувається прийом файлів з порту?

5.8 Практикум з програмування




  1. Написати фрагмент програми для підрахування кількості рядків в текстовому файлі.

  2. Написати фрагмент програми для підрахування кількості слів в текстовому файлі.

  3. Написати фрагмент програми для порівняння двох текстових файлів та виведення номера рядка та позиції символу, де вони відрізняються.

  4. Написати фрагмент програми для підрахування скільки разів з’являється дане слово в текстовому файлі.

  5. Написати фрагмент програми для дозапису рядка в початок текстового файлу.

  6. Написати фрагмент програми для дозапису даних у початок існуючого двійкового файлу.

  7. Написати фрагмент програми для дозапису даних у середину існуючого двійкового файлу з заданої позиції.

  8. Написати фрагмент програми для видалення заданої кількості даних з початку двійкового файлу.

  9. Написати фрагмент програми для видалення заданої кількості даних з заданої позиції заданого двійкового файлу і вставляння їх з заданої позиції у новий файл.

  10. Написати фрагмент програми для перезапису змісту файлу з кінця в початок у зворотному порядку.

6 ОСОБЛИВОСТІ РОБОТИ З ТЕКСТОВИМИ ДАНИМИ
МОВОЮ С

6.1 Загальні відомості


Для подання текстової інформації мовою С використовуються символи (константи), символьні змінні і рядки (рядкові константи), для яких у стандарті мови С не введено окремого типу на відміну від деяких інших мов програмування.

Для символьних даних введений базовий тип char. Опис символьних змінних має вигляд:

char список_імен_змінних;

Наприклад:

char a,z;
Введення-виведення символьних даних

Для введення і виведення символьних значень у форматних рядках бібліотечних функцій printf() і scanf() використовується специфікація перетворення %с.

Специфіка́ція (англ. specification) - формалізований опис властивостей, характеристик і функцій об'єктів.

Розглянемо таку задачу.

Ввести речення, слова в якому розділені пропусками і наприкінці якого стоїть крапка. Видалити пропуски, які повторюються між окремими словами (залишити по одному пропуску), вивести відредаговане речення на екран.

Редагува́ння - це приведення об'єкта редагування у відповідність із чинними у певний час у конкретному суспільстві нормами, а також його творча оптимізація, метою яких є отримання заданого соціального ефекту.

Текст програми:

/* Видалення повторюваних пропусків */

#include "stdafx.h"

void main( )

{

char z,s; /* z - поточний символ, що вводиться */



printf("\n Напишіть речення з крапкою в кінці:\n");

for (z=s=' ';z!='.';s=z)

{/* s - попередній символ */

scanf("%c",&z);

if (z==' '&& s==' ') continue;

printf ("%c",z) ;

} /* Кінець циклу обробки */

} /* Кінець програми */


У програмі дві символьні змінні: z – для читання попереднього символу і s – для збереження попереднього. В заголовку циклу змінні z і s одержують значення «пропуск». Черговий символ вводиться як значення змінної z, і пара z, s аналізується. Якщо хоча б один із символів значень пари відмінний від пропуску, то значення z друкується. В заголовку циклу z порівнюється із символом «крапка» і при розбіжності запам’ятовується як значення s. Далі цикл повторюється до появи на вході крапки, причому поява двох пропусків (z і s) приводить до пропускання оператора друку.

Приклад роботи програми.

Напишіть речення з крапкою в кінці:

yyyyy yyyyy hhhhh ttttt.

yyyyy yyyyy hhhhh ttttt.

Крім scanf() і printf() для введення і виведення символів в бібліотеці передбачені спеціальні функції обміну:

getchar() – функція без параметрів.

Спеціальні функції - функції, що зустрічаються в різних додатках математики (найчастіше - в різних задачах математичної фізики), які не виражаються через елементарні функції. Спеціальні функції представляються у вигляді рядів або інтегралів.
Дозволяє читати з вхідного потоку (звичайно з клавіатури) по одному символу за одне звертання. Як і при використанні функції scanf(), читання даних, що вводяться, починається після натискання клавіші . Це дає можливість виправляти інформацію, що вводиться (стираючи останні введені символи за допомогою клавіші ) до початку її читання програмою;

putchar(X) – виводить символьне значення X в стандартний потік (звичайно на екран дисплея).


Внутрішні коди й упорядкованість символів

У мові прийнята угода, що скрізь, де синтаксис дозволяє використовувати цілі числа, можна використовувати і символи, тобто дані типу char, що при цьому подаються числовими значеннями своїх внутрішніх кодів. Така угода дозволяє порівняно просто упорядковувати символи, працюючи з ними як з цілочисловими величинами. Наприклад, внутрішні коди десяткових цифр в таблицях кодів ASCII упорядковані за числовим значенням, тому нескладно перебирати символи десяткових цифр у потрібному порядку.


Рядки чи рядкові константи

У програмі рядки або рядкові константи подаються послідовністю зображень символів, які поміщені в лапки (не в апострофи), наприклад "будь-які символи".

Апо́строф (від грец. αποστροφος - «звернений набік») - нелітерний орфографічний знак. Це графічний знак, який не позначає звука. За допомогою апострофа в українській мові відокремлюються йотовані голосні літери від попередніх губних приголосних та «р», наприклад: м’язи, бур’ян.
Серед символів рядка можуть бути ескейп-послідовності, що відповідають кодам не зображуваних (спеціальних) символьних констант.

Приклади рядків:

"1234567890"

"\t Склад президії"

"Початок рядка \n і кінець рядка".

Однак у рядків є деякі особливості. Транслятор відводить кожному рядку окреме місце в пам'яті ЕОМ навіть у тих випадках, коли кілька рядків повністю збігаються (стандарт мови С припускає, що в конкретних реалізаціях це правило може не виконуватися).

Трансля́тор (англ. translator) - програма або технічний засіб, який виконує перетворення чи іншу обробку текстів програм.
Розміщаючи рядок у пам'яті, транслятор автоматично додає в його кінці символ '\0', тобто нульовий байт. У записі рядка може бути й один символ: "А", однак на відміну від символьної константи 'А' (використані апострофи) довжина рядка "А" дорівнює двом байтам.
Апостроф за необхідності застосовують для позначення м'яких приголосних у фонетичній транскрипції, зокрема, для праслов'янської мови - символ «ь» передає там особливий надкороткий голосний. Цікаво, що в старослов'янському письмі, коли знак «ь» ще передавав редукований голосний, для позначення м'якості використовували (поряд з циркумфлексом над приголосним) значок, дуже схожий на апостроф.
На відміну від інших мов (наприклад, від Паскаля) у мові С немає окремого типу для рядків. Прийнято, що рядок – це масив символів, тобто він завжди має тип char[ ]. Таким чином, рядок вважається значенням типу "масив символів". Кількість елементів у такому масиві на 1 більша, ніж у зображенні відповідної рядкової константи, тому що в кінець рядка доданий нульовий байт '\0'.

Присвоїти значення масиву символів (тобто рядку) за допомогою звичайного оператора присвоювання не можна. Помістити рядок у масив можна або за допомогою ініціалізації (при визначенні символьного масиву), або за допомогою функцій введення. У функції scanf() чи printf() для символьних рядків використовується специфікація перетворення %s.

При визначенні масиву типу char з одночасною ініціалізацією можна не вказувати межі зміни індексу. Сказане ілюструє нижченаведена програма:
/* Друкування символьного рядка */

#include

void main( )

{

char B[]="Сезам, відкрийся!

Друка́рство - принцип одержання відбитків письмових знаків за допомогою тиснення. Отримані таким чином роботи можна використовувати у великих кількостях - що і стало суттю друкарства. До цього винаходу, на створення та відтворенням рукописних документів і книг мали монополію лише невелика кількість фахівців (особливо освічені ченці монастирях).
";



printf("%s",B);

} /* Кінець програми */


Результат виконання програми:

Сезам, відкрийся!


У програмі довжина масиву В – 17 елементів, тобто довжина рядка, що поміщається в масив (16 символів), плюс нульовий байт закінчення рядка. Саме 17 байтів виділяється при ініціалізації масиву в наведеному прикладі. Ініціалізація масиву символів за допомогою рядкової константи являє собою скорочений варіант ініціалізації масиву і введена в мову для спрощення. Можна скористатися звичайною ініціалізацією, помістивши початкові значення елементів масиву у фігурні дужки і не забувши при цьому помістити в кінці списку початкових значень спеціальний символ закінчення рядка '\0'. Таким чином, у програмі була б припустима така ініціалізація масиву В:

char B[ ]={'С','е','з','а','м',',',' ','в','і', 'д','к','р','и','й','с','я','!','\0' };

Домовленість про обов’язкову наявність ознаки закінчення рядка потрібно дотримуватись, формуючи в програмах рядки з окремих символів. Як приклад розглянемо таку задачу: «Ввести речення, що закінчується крапкою, слова в якому відділені пропусками. Надрукувати останнє слово речення».

Аналіз умови задачі дозволяє виявити такі помилкові ситуації й особливі випадки: відсутність крапки в кінці речення;

Театральна лабораторія «ВідСутність» - зразковий художній колектив заснований в 2010 році за ініціативи Юрія Паскара в місті Рівне. Діє на базі Рівненського міського Палацу дітей та молоді.
пропуск чи пропуски перед першим словом речення; кілька пропусків між словами; пропуски перед крапкою, що завершує речення; відсутність слів у реченні (тільки крапка). Щоб не ускладнювати розв’язання задачі, приймемо умову про те, що речення, яке вводиться, завжди поміщається на одному рядку дисплея, тобто довжина його не перевищує 80 символів. Це дозволить легко виявляти відсутність крапки в кінці речення й обмежує довжину будь-якого слова речення. Щоб врахувати особливі ситуації з пропусками, необхідно при аналізі чергового введеного символу (змінна s) розглядати і попередній символ (змінна ss). Для виявлення відсутності слів у реченні будемо обчислювати довжину k кожного чергового слова, що вводиться. Якщо k==0, а вводиться символ '.', то це ознака порожнього речення.


Текст програми:
1   2   3   4   5   6   7   8   9   10   11