Підрахувати кількість символів вхідного потоку

Розглянемо програму:#include <stdio.h>main(){ long nc; nc=0; while (getchar()!=EOF) ++nc; printf("%1d\n",nc);}

Програма підрахунку символів накопичує їхню кількість у змінну типу long, а не int (максимальне число – 32767), і, якщо описати лічильник як int, то він буде переповнятися навіть при порівняно малому файлі. Специфікація перетворення %1d указує printf, що відповідний аргумент є цілим типу long.

Для роботи із більшими числами можна використовувати тип double. Ми використаємо оператор for замість while для того, щоб проілюструвати інший спосіб запису циклу:

main(){ /*count characters in *input*/ double nc; for (nc=0;getchar()!=EOF; ++nc); printf("%.0f\n",nc);} Функція printf використовує специфікацію %f як для float, так і для double; специфікація %.0f дозволяє не друкувати дробову частину.

Тіло оператора циклу for тут порожнє, тому що вся робота виконується в перевірочній та ініціювальній частинах. Якщо файл введення не містить жодних символів, то умова у while чи for не виконається при найпершому звертанні до getchar, і, отже, програма видасть нуль.

3. Підрахувати кількість рядків у файлі.

Вважатимемо, що рядок закінчується \n.

main(){ /*count lines in input*/ int s,nl; nl=0; while ((s=getchar())!=EOF) if (s=='\n') ++nl; printf("%d\n",nl);}

Тіло while тепер містить оператор if, який, у свою чергу, керує оператором інкремента ++nl. Оператор if перевіряє вкладену в круглі дужки умову і, якщо вона істинна, виконує оператор, що йде за ним.

4. Написати програму, що копіює символи вхідного файла у вихідний.

Загальна схема програми:

ввести символwhile (символ не є ознакою кінця файла)вивести тільки що прочитаний символввести новий символТекст програми:#include <stdio.h>main(){/*copy input tо output;*1st version*/int c; c=getchar(); while (c!=EOF) { putchar(c); c=getchar(); }}

Основна проблема полягає в тому, щоб зафіксувати кінець файла. Коли функція getchar досягає кінця файла, вона повертає значення, що не є дійсним символом. Однак яке значення є ознакою кінця файла? Це може бути –1 чи 0, тому використовується символічне ім'я (макровизначення) EOF, яке визначається як

#define EOF -1

або

#define EOF 0

У цьому фрагменті змінна 'с' описана як int, а не char, для того, щоб вона могла зберігати значення, яке повертається getchar.

Цю програму можна написана більш стисло.

У мові C будь-яке присвоювання, наприклад

c=getchar();

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

main(){/*copy input->output;*2nd version*/ int c; while((c=getchar())!=EOF) putchar(c);}

Програма отримує символ зі стандартного введення, присвоює його змінній 'с' і потім перевіряє, чи не є цей символ ознакою кінця файла. Якщо не є – виконується тіло оператора while, що виводить цей символ. Потім цикл while повторюється. Коли, нарешті, буде досягнутий кінець файла введення, оператор while завершується, а разом з ним закінчується виконання й функції main.

Важливо зрозуміти, що круглі дужки навколо присвоювання в умовному виразі дійсно необхідні. Пріоритет операції != вище, ніж операції присвоювання =, а це означає, що без круглих дужок перевірка умови != буде виконана до присвоювання =. Таким чином, оператор

c=getchar()!=EOF

еквівалентний оператору

c=(getchar()!=EOF)

5. Напишіть програму з використанням циклів, що створює трикутник:

* *** ***** ******* ********* /*Трикутник із зірочок*/ #include <stdio.h> /*Друк n символів c*/ printn(c,n){ while(--n>=0) putchar(c); } int lines=10; /*кількість рядків трикутника*/ void main(argc,argv) char*argv[]; { register int nline; /*номер рядка*/ register int naster; /*кількість зірочок у рядку*/ register int i; if(argc>1) lines=atoi(argv[1]); for(nline=0;nline<lines;nline++){ naster=1+2*nline; /*лідируючі пропуски*/ printn(' ',lines-1 – nline); /*зірочки*/ printn('*',naster); /*переведення рядка*/ putchar('\n'); } exit(0); /*завершення програми*/ }

6. Написати програму, що підраховує кількість слів у файлі.

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

#define yes 1#define no 0 main(){ int c,nl,nw,inword; inword=no; nl=nw=nc=0; while((c=getchar())!=EOF) { ++nc; if (з=='\n') ++nl; if (c==' '||c=='\n'||c=='\t') inword=no; else if(inword==no) { inword=yes; ++nw; } } printf("%d%d%d\n",nl,nw,nc);} Щоразу, коли програма зустрічає перший символ слова, вона збільшує лічильник кількості слів на одиницю. Змінна inword стежить за тим, знаходиться програма в даний момент усередині слова чи ні. Спочатку змінній присвоюється no, що означає "не в слові". Ми нааємо перевагу символічним константам yes і no перед літерними значенням 1 і 0, тому що вони роблять програму зручнішою для читання. До того ж зміни набагато легше вносити в ті програми, де числа фігурують тільки як константи.

Рядок nl=nw=nc=0; дозволяє всім трьом змінним присвоїти нулі.

Операція || означає "або", так що рядок

if(c==' '||c=='\n'||c=='\t')

означає "якщо c – пропуск, або c – символ нового рядка, або c –табуляція...". (Умовна послідовність \t є зображенням символу табуляції.)

Оператор, що йде за else, є оператором if, який керує двома операторами у фігурних дужках.

7. Підрахувати кількість входжень кожної з літер алфавіту у файл: #include <stdio.h>#include <ctype.h> long bcnt[8];char masks[8]={/*маски бітів*/ 1,2,4,8,16,32,64,128};long cnt[256]; /*лічильники для кожної з 256 літер*//*друк літер*/char *pr(c){ static char buf[20];switch(c){ case '\n': return "\\n"; case '\r': return "\\r"; case '\t': return "\\t"; case '\b': return "\\b"; case '\f': return "\\f"; case '\033': return "ESC"; case '\0': return "\\0"; case 0177: return " ^? "; } if(c<' '){ sprintf(buf,"^%c",c+'A'–1); }else if(isspace(c)){ sprintf(buf," '%c' ",c); }else if(!isprint(c)) sprintf(buf,"\\%3o",c); else sprintf(buf," %c ",c); return buf;}main(argc,argv) char**argv; { FILE*fp;if(argc==1) process(stdin); else{argv++;argc--; while(*argv){ printf("-----FILE %s -----\n",*argv); if((fp=fopen(*argv,"r"))==NULL){ printf("Can not open\n"); }else{process(fp); fclose(fp);} argv++; argc--; } } exit(0);}/*обробити файл із покажчиком fp*/process(fp) FILE *fp;{register i;int c;int n;/*зачищення лічильників*/ for(i=0;i<256;i++)cnt[i]=0L; for(i=0;i<8;i++)bcnt[i]=0;while((c=getc(fp))!=EOF){ c&=0377; /*по літері*/ cnt[c]++; /*підрахунок бітів*/ for(i=0;i<8;i++) if(c& masks[i]) bcnt[i]++; } /*видача результатів у COL колонок*/#define COL 4 printf("\tASCII map\n"); for(n=i=0;i<256;i++){ /*if(cnt[i]==0l) continue;*/ printf("%s %5ld|",pr(i),cnt[i]); if(++n==COL){n=0; putchar('\n');}/*чи if((i%COL)==(COL-1)) putchar('\n');*/ } printf("\n\tBITS map\n"); for(i=7;i>=0;i--) printf("%6d",i); putchar('\n'); for(i=7;i>=0;i--) printf("%6ld",bcnt[i]); putchar('\n'); putchar('\n');

}

8. Написати програму, що зчитує рядки й друкує найдовший з них.

Схема програми:

while (є ще рядок)if (цей рядок довший за найдовший з попередніх) запам'ятати цей рядок і його довжинунадрукувати найдовший рядок

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

#define maxline 1000 /*довжина максимального рядка*/main(){ int len; /*довжина поточного рядка*/ int max; /*максимальна довжина*/ char line[maxline]; /*поточний рядок*/ char save[maxline]; /*найдовший збережений рядок*/ max=0; while ((len=getline(line,maxline))>0) if(len>max) { max=len; copy(line,save); } if (max>0) printf("%s",save);}getline(s,lim) /*отримує рядок та записує його в *s, повертає довжину рядка*/ char s[]; int lim;{ int c,i; for (i=0; i<lim–1&&(c=getchar())!=EOF && c!='\n';++i) s[i]=c; if (c=='\n') { s[i]=c; ++i; } s[i]='\0'; return (i);}copy(s1,s2) /*копіює s1 у s2;*/ char s1[],s2[];{ int i; i=0; while ((s2[i]=s1[i])!='\0') ++i;} Функції main і getline пов'язуються як через пару аргументів, так і через значення, що повертається. Аргументи getline описані в рядках char s[];int lim;

які вказують, що перший аргумент є масивом, а другий – цілим.

Довжина масиву s не зазначена, тому що вона визначена в main. Функція getline використовує оператор return для передавання значення назад так само, як це робила функція power. Щоб позначити кінець рядка символів, функція getline поміщає в кінець створюваного нею масиву символ '\0'.

Специфікація формату %s указує, що printf очікує рядок, який закінчується нуль-символом. Проаналізувавши функцію copy, бачимо, що і її вхідний аргумент має закінчуватися символом '\0', вона копіює цей символ у вихідний аргумент s2.

Функція getline при заповненні масиву припиняє подальше отримання символів, якщо рядок перевищив максимально допустиму довжину, навіть якщо не зустрічає символу нового рядка. Перевіривши отриману довжину й останній символ, функція main може встановити, чи не був цей рядок занадто довгим.

Користувач функції getline не може заздалегідь довідатися, на­скільки довгим виявиться рядок, що вводиться. Тому в getline включено контроль переповнення. У той самий час користувач функції copy вже знає (чи може довідатися), який розмір рядків, тому додаткового контролю не потрібно.

9. Написати програму, що друкує слова в рядках файла у зворотному порядку. #include <stdio.h>#include <ctype.h>#include <string.h>#include <locale.h>#define MAXL 255 /*макс. довжина рядка*//*Якби ми не включили ctype.h, то повинні були б визначити: *#define isspace(c)((c)==' '||(c)=='\t'||(c)=='\f')*/main(argc,argv) char**argv;{ setlocale(LC_ALL,""); if(argc==1){ /*програма викликана без аргументів*/ munch(""); } else{ /*аргументи програми – імена файлів*/ while(argv[1]){ munch(argv[1]); argv++; argc--; } } total();exit(0);}/*обробити файл з іменем name*/munch(name)char*name;{ char l[MAXL]; /*буфер для чергового рядка*/ int len; /*довжиною цього рядка*/ char*words[50]; /*таблиця полів рядка*/ char**s; /*службова*/ int nwords; /*кількість слів у рядку*/ FILE *fp; if(name==NULL||!*name) fp=stdin; /*стандартне введення*/ else if((fp=fopen(name,"r"))==NULL){ fprintf(stderr,"Не можу відкрити файл %s\n", name); return; } printf("----------------------------%s----\n",name); while(fgets(l,MAXL,fp)!=NULL){ len=strlen(l); if(len && l[len-1]=='\n') l[--len]='\0';if(nwords=parse(l,words)){ /*друк слів у зворотному порядку*/ for(--nwords;nwords>=0;nwords--){ printf("%s",words[nwords]); add(words[nwords]); } } putchar ('\n'); } if(fp!=stdin) fclose(fp);}/*розкласти рядок на слова*/parse(s,tabl) register unsigned char*s; unsigned char*tabl[];{ char eol=0; int nwords=0;while(!eol){ /*пропустити пропуски та табуляції*/ while(isspace(*s))s++; if(!*s) /*рядок закінчився*/ break; *tabl++=s;nwords++; /*початок чергового слова*/ /*поки не пропуск і не кінець рядка*/ while(*s &&!isspace(*s))s++; /*покажчик указує на символ, що йде за словом*/ if(!*s)eol++; *s='\0'; /*закрили Слово, починаємо Справу*/ s++; } *tabl=NULL; return nwords;}/*побудова таблиці слів, що зустрічаються у файлі*/#define MAXWORDS 1024 struct W{ int ctr; /*кількість входжень слова*/ char*wrd; /*слово*/}w[MAXWORDS]; /*таблиця*/int busy=0; /*зайнято в таблиці*/ extern char*malloc(); /*Добавити слово в таблицю*/add(word)char*word;{ register i; static alert=1; /*немає вже слова в таблиці?*/ /*якщо є – просто збільшити лічильник*/ for(i=0;i<busy;i++){ if(!strcmp(word,w[i].wrd)){ w[i].ctr++; return; } } if(busy>=MAXWORDS){ if(alert){ fprintf(stderr, "Переповнення таблиці слів\7\n"); alert=0; } return; }/*ні, слова немає. Записуємо:*/ w[busy].wrd=malloc(strlen(word)+1); /*1байт під символ\0*/if(w[busy].wrd==NULL){ fprintf(stderr,"Мало пам’яті\n"); busy=MAXWORDS+1; /*ніби переповнення*/ return; } w[busy].ctr=1; strcpy(w[busy].wrd,word); busy++;}compare(a,b)struct W*a,*b;{ return strcoll(a->wrd,b->wrd); /*strcoll порівнює слова в алфавітному порядку*/}/*друк усіх слів, що зустрічаються в тексті, та кількості їхніх входжень*/total(){ register i; /*сортуємо слова за алфавітом*/ qsort(w,busy,sizeof(struct W),compare); printf("-----|-----------ПІДСУМОК---------------\n"); for(i=0;i<busy;i++) printf("%4d|%s\n", w[i].ctr, w[i].wrd);}10. Розділити дійсне число x на дійсне число у з точністю до n цифр після коми (40<=n<=60).

При написанні програми використаємо бібліотечну функцію fmod(x,y), яка повертає залишок від ділення числа x на y для дійсних x та y. Спочатку надрукуємо цілу частину x/y. Потім fmod(x,y) домножуватимемо на 10 доти, доки не отримаємо число, більше ніж 1. Тоді надрукуємо цілу частину цього числа. Процес продовжуватимемо до заданої точності n.

#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <math.h>

void main()
{
float x,y,z,t,s;
int i,j,flag,n,k;
m1:
clrscr();

printf("\n Ділене: ");
scanf("%f",&x);

printf("\n Дільник: ");
scanf("%f",&y);

printf("\n Введіть точність 40<=n<=60: ");
scanf("%d",&n);


printf("\n Отримали число:\n");
printf("%d.",(int)((x/y)));

for(i=0;i<n;i++)
{
flag=0;
t=fmod(x,y);
if(t==0)flag=1;
else flag=0;

while(!flag)
{
if(t<y)t*=10.0;
else flag=1;
}
s=t/y;
if(fabs(s)>=1e-5)printf("%d",(int)s);
if(s==0)printf("%d",(int)s);
x=t;
}

printf("\n Продовжуємо-7:");
scanf("%d",&k);
if(k==7){gotoxy(1,wherey()-1);delline();goto m1;}
getch();

}

11. Написати програму для організації роботи з базою даних. Вважати, що дані є сукупністю деяких ключа та значення (символьного рядка). #include <stdio.h>/*Усі записи в базі мають фіксований розмір*/#define VLEN 20#define KEY_FREE(-13) /*ключ вільного місця. Він довільний, але не є вхідним даним*/ struct data{ short b_key; /*ключ*/ char b_val[VLEN]; /*рядок-значення*/};char BASEF[]=".base"; /*ім’я файла бази*/FILE*fbase; /*pointer на базу*/struct data tmp; /*допоміжна змінна*/voidinitBase (void){ /*fopen:r read (читання) *w write (запис), файл створюється заново. *(створюється, якщо не було, якщо був – спустошується). *r+читання та запис (файл уже існує). *w+читання та запис (створюється порожній файл). *a append (запис у кінець файла), створити, якщо немає: *тут мається на увазі, що кожна операція запису спочатку ставить покажчик запису на кінець файла*/ if((fbase=fopen(BASEF,"r+"))==NULL){ if((fbase=fopen(BASEF,"w+"))==NULL){fprintf(stderr, "Не можу відкрити базу даних %s\n",BASEF); exit(1); } fprintf(stderr, "База створена\n"); }}voidcloseBase (void){ fclose(fbase);}/*Урахуйте, що якщо ви записуєте у файл структури, то у файлі не буде поділу на рядки – файл НЕТЕКСТОВИЙ! Тому читати такий файл можна тільки структурами: read(), fread() (але не scanf і не fgets)*//*Пошук за ключем. Видати (-1), якщо запису з даним ключем немає, інакше – номер слота, де міститься запис з даним ключем*/intbget (int key){ int n;/*послідовно передивитися весь файл*/ rewind(fbase); /*на початок файла. Еквівалент fseek(fbase, 0L, 0);*/n=0; /*int скільки_елементів_масиву_дійсно_зчитано= *fread(адреса_масиву_куди_зчитувати, *розмір_одного_елемента_масиву, *скільки_елементів_зчитувати_в_масив, канал); *Зазначимо, що кількість даних задається НЕ в байтах, *а в 'штуках'*/ while(fread(&tmp, sizeof(tmp),1,fbase)==1){ if(tmp.b_key==key) return n; n++; } return(-1); /*не знайдено*/}/*модифікувати запис з індексом ind*/voidbmod (int ind, int key, /*новий ключ*/ char *val /*нове значення*/){ struct data new;fseek(fbase,(long)sizeof(struct data)*ind,0); new.b_key=key; strncpy(new.b_val,val,VLEN); /*int скільки_елементів_масиву_дійсно_записано= *fwrite(адреса_масиву_який_записувати, *розмір_одного_елемента_масиву, *скільки_елементів_масиву_записувати, канал); */ if(fwrite(&new,sizeof new,1,fbase)!=1) fprintf(stderr,"Помилка запису.\n");} /*видалення запису за ключем*/intbdel(int key){ int ind=bget(key); if(ind==-1) return(-1); /*запису з таким ключем немає*/ bmod(ind,KEY_FREE,""); /*записати ознаку вільного місця*/ return 0;}/*Службова процедура дописування до кінця файла*/voidbappend (int key,char*val){ struct data new; /*стати на кінець файла*/ fseek(fbase,0L,2); /*і записати нову структуру в кінець*/ new.b_key=key; strncpy(new.b_val,val,VLEN); fwrite(&new,sizeof(struct data),1,fbase);}/*дописування нового запису. Якщо запис з таким ключем є - видати помилку*/intbput (int key,char*val){ int i=bget(key); if(i!=-1) return(-1); /*запис уже є*//*знайти вільне місце*/ i=bget(KEY_FREE); if(i==-1){/*немає вільних місць*/ bappend(key,val); return 0; } /*інакше вільне місце знайдене. *Замінюємо його на корисну інформацію*/ bmod(i,key,val);}/*роздрукувати всю базу даних підряд*/voidbprint (void){ int n; int here=0;rewind(fbase); n=0; printf("-номер--ключ-------значення------------\n"); while(fread(&tmp,sizeof tmp,1,fbase)==1){ if(tmp.b_key==KEY_FREE){ n++; continue; } printf("#%-2d|%6d\t|%s\n",n,tmp.b_key,tmp.b_val); here++;n++; } printf("-----------------------------------------\n"); printf("Довжина бази:%d Зайнято:%d\n\n",n,here);}/*заміна поля val у запису з ключем key*/intbchange (int key,char*val){ int ind; ind=bget(key); if(ind==-1){ /*запису з таким ключем не існує*/ /*Додати як новий запис*/ bput(key,val); return 0; } bmod(ind,key,val); return 1;}/*Аналогічна функція, яка використовує інший спосіб. *Крім того, якщо такий ключ існує, нічого не відбувається*/intbchg (int key,char*val){ struct data d;rewind(fbase); /*на початок файла*/ while(fread(&d,sizeof d,1,fbase)==1){ /*пошук ключа*/ if(d.b_key==key){ /*повернутися назад від поточної позиції*/ fseek(fbase,–(long)sizeof d,1); /*не підходить (long)-sizeof d!!!*/d.b_key=key; strncpy(d.b_val,val,VLEN); fwrite(&d,sizeof d,1,fbase);/*між fread і fwrite має бути *хоча б один fseek.*/ fseek(fbase,0L,1); /*нікуди не зсуватися*/ return 0; /*зроблено*/ } } return(-1); /*такого ключа не було*/}/*Приклад*/voidmain (void){ int i;initBase(); bprint(); bdel(8);printf("Створюємо базу даних\n"); bput(1, "рядок1"); bput(2, "рядок2"); bput(3, "рядок3"); bput(4, "рядок4"); bprint();printf("Видаляємо записи з ключами 1 і 3\n"); bdel(1); bdel(3); bprint();printf("Додаємо записи 5,6 і 7\n"); bput(5, "рядок5"); bput(6, "рядок6"); bput(7, "рядок7"); bprint();printf("Замінюємо рядок у запису з ключем 2\n"); bchange(2, "новий рядок 2"); bprint();printf("Замінюємо рядок у запису з ключем 4\n"); bchange(4, "новий рядок 4"); bprint();printf("Замінюємо рядок у запису з ключем 3 і ключ 3 на 9\n"); bchange(2, "новий рядок 2"); bprint();i=bget(3); printf("Зараз запис із ключем 3 містить \"%s\"\n", tmp.b_val); bmod(i,8, "Новий рядок 3/9"); bprint();closeBase();}

Завдання для самостійної роботи

1. Серед тризначних чисел знайти такі, щоб сума факторіалів їхніх цифр рівнялася б самому числу, використовуючи підпрограму обчислення факторіала.

2. Дано координати трикутника й точки на площині. Визначити, чи лежить точка всередині трикутника.

3. Описати функцію Min2(A, B), Max2(A,B), що знаходить мінімальне/макси­мальне із двох дійсних чисел А та B. За її допомогою знайти мінімальні/максимальні із пар чисел A та B, A та C, A та D, якщо дано числа A, B, C, D.

4. Описати функцію Fact2(N) цілого типу, що обчислює значення подвійного факторіала: N!!=1·3·5 ·...·N, якщо N непарне, N!!=2·4·6· ...·N, якщо N парне (N > 0 – параметр цілого типу).

5. Описати функцію Exp1(x,eps) дійсного типу (параметри x, eps дійсні, eps > 0), що знаходить наближене значення функції exp(x):

exp(x)= 1+ x + x 2/2!+ x 3/3!+ ... + xn / n!+ ....

У сумі враховувати всі доданки, більші за eps. За допомогою Exp1 знайти наближене значення експоненти для даного x при шести даних eps.

6. Описати функцію Power(x,a,eps) дійсного типу (параметри x, a,eps дійсні, | x | < 1, a > 0, eps > 0), що знаходить наближене значення функції (1+ x) a:

(1 + x) a =1+ a · x + (a – 1)· x 2/2! + a ·(a – 1) ·...· (a – n +1) ·xn / n! + ....

У сумі враховувати всі доданки, за модулем більші ніж eps. За допомогою PowerA знайти наближене значення (1+ x) a для заданих x та a за шести різних значень eps.

7. Описати функцію Length(Ax,Ay,Bx,By) дійсного типу, що знаходить довжину відрізка AB на площині за координатами його кінців:

| AB | = sqrt((Ax – Bx)2+(Ay – By)2)

(Ax, Ay, Bx, By – дійсні параметри). За допомогою цієї функції знайти довжини відрізків AB, AC, AD, якщо дано координати точок A, B, C, D.

8. Використовуючи функцію Length із попереднього завдання, описати функцію Perim(Ax,Ay,Bx,By,Cx,Cy) дійсного типу, що знаходить периметр трикутника ABC за координатами його вершин (Ax, Ay, Bx, By, Cx, Cy – дійсні параметри). За допомогою цієї функції знайти периметри трикутників ABC, ABD, ACD, якщо задано координати точок A, B, C, D.

9. Використовуючи функції Length та Perim із попереднього завдання, описати функцію Area(Ax, Ay, Bx, By, Cx, Cy) дійсного типу, що знаходить площу трикутника ABC за формулою Герона. За допомогою цієї функції знайти площі трикутників ABC, ABD, ACD, якщо дано координати точок A, B, C, D.

10. Використовуючи функції Length та Area із попереднього завдання, описати процедуру Dist(Px, Py, Ax, Ay, Bx, By, D), що знаходить відстань D від точки P до прямої AB за формулою D =2 SPAB /| AB |, де SPAB – площа трикутника PAB. За допомогою цієї процедури знайти відстані від точки P до прямих AB, AC, BC, якщо дано координати точок P, A, B, C.

11. Використовуючи процедуру Dist із попереднього завдання, описати процедуру Heights(Ax, Ay, Bx, By, Cx, Cy, h1, h2, h3), що знаходить висоти h1, h2, h3 трикутника ABC, проведені відповідно з вершин A, B, C. За допомогою цієї процедури знайти висоти трикутників ABC, ABD, ACD, якщо дано координати точок A, B, C, D.


ОБ'ЄКТНО-ОРІЄНТОВАНЕ програмування ТА С++

Основи сучасного програмування Основи сучасного програмування Основи сучасного програмування Основи сучасного програмування Основи сучасного програмування Основи сучасного

Елементи концепції


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: