Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

osn_progr_final

.pdf
Скачиваний:
37
Добавлен:
12.02.2016
Размер:
3.27 Mб
Скачать

void main()

{

char text[128], //вихідний текст copy[128], //копія вихідного тексту *p, //початок чергового речення

*s, //початок чергового слова raz1[]="!?.", //розділювачі речень raz2[]=".?!,;: ";//розділювачі слів int l, //довжина текста

k, //кількість речень u;

do

{

clrscr();

puts("Введіть вхідний текст"); gets(text);

l=strlen(text);

strcpy(copy,text);

for(p=strtok(text,raz1),k=0;p!=NULL;p=sttok(NULL

,raz1))

k++;

for(s=strtok(copy,raz2),u=0;s!=NULL;s=strtok(NUL

L,raz2))

u++;

puts("Середня довжина речень:"); printf("%5d",l/k);

puts("\nСередня кількість слів у реченні"); printf("%5d",u/k);

puts("\nДля продовження натисніть ENTER, для ви-

ходуESC"); }while(getch()!=27);

}

Приклад 4 Нехай задано цілочисельний арифметичний вираз, записаний як

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

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

void main()

{

101

char a_v[80], a_v1[80], *p, c[40]; char *oper="+-*/%", *cifr="0123456789", *c_o="0123456789+-*/%";

int a[40], l_a_v, l, i, j, jk, ac; textmode(1); textcolor(YELLOW);

textbackground(BLUE);

m1:clrscr();

puts("Введіть арифметичний выраз: "); gets(a_v);

strcpy(a_v1, a_v); l_a_v=strlen(a_v); l=strspn(a_v,c_o);

if(l!=l_a_v) { puts("\n Помилка у виразі");

goto end; } p=strtok(a_v, oper); i=0;

do

{

a[i++]=atoi(p);

}

while(p=strtok(NULL, oper)); strcpy(a_v, a_v1); p=strtok(a_v, cifr);

j=0; do

{

c[j++]=*p;

}

while(p=strtok(NULL, cifr));

if(i!=j+1) { puts("\n Помилка у виразі"); goto end; }

jk=j;

ac=a[0];

i=j=0;

while(j<jk)

{

switch(c[j++])

{

case '+' : ac+=a[++i]; break; case '-' : ac-=a[++i]; break; case '*' : ac*=a[++i]; break; case '/' : ac/=a[++i]; break; case '%' : ac%=a[++i];

}

}

102

strcpy(a_v, a_v1); printf("\n%s = %d", a_v, ac); end:

printf("\n\n Для продовження - натисніть 7 : "); scanf("%d", &l); getchar();

if(l==7) goto m1;}

Приклад 5

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

#include<stdio.h>

#include<conio.h>

#include<stdlib.h>

#include<string.h> void main()

{

int n,*arr,i; char str[301],ch;

srand(time(NULL));

m1:

clrscr();

printf("Введіть текст(не більше 300 символов), що закінчується <Enter>:\n");

gets(str);

n=strlen(str);

arr = NULL;

arr = (int*) calloc(n,sizeof(int));//виділення пам”яті

clrscr();

puts("Введений текст:"); printf("\"%s\"",str);

putchar('\n'); puts("\nСформований ключ:"); for(i=0;i<n;i++)

{

103

/*заповнення масиву випадковими числами з діапазона[0..99] та друк*/

arr[i]=rand()%100;

printf("%4d",arr[i]);

}

for(i=0;i<n;i++) str[i]-=arr[i]; printf("\n\nЗашифрований текст:\n"); putchar('"');

for(i=0;i<n;i++) printf("%c",str[i]); putchar('"');

puts("\n\nРозшифровка:"); putchar('"');

for(i=0;i<n;i++) printf("%c",str[i]+arr[i]); putchar('"');

free(arr); //очистка пам”яті printf("\n\nПродовжуємо? (7-так):"); if(getch()=='7') goto m1;

}

Приклад 6 Відцентруємо рядки тексту.

Вхідні рядки не повинні містити табуляцій

#include <stdio.h>

 

extern char *gets();

 

#define WIDTH 60

/* ширина листа */

main(){

 

char rd[81]; register char *s;

char *head,

/* початок тексту */

*tail;

/* кінець тексту */

register int len, i;

int shift;

/* відступ */

/* Читати з стандартного вводу в rd по одному рядку, * доки файл не закінчиться. */

while( gets( rd ) != NULL ){ if( !*rd ){

/* Рядок порожній */ putchar( '\n' ); continue;

}

/* пропуск пропусків на початку рядка */ for( s = rd; *s == ' ' ; s++ );

if( ! *s ){

104

/* Рядок складається лише з пропусків */ putchar( '\n' ); continue;

}

head = s;

/* стати на кінець рядка */ while( *s ) s++;

/* шукати останній непропуск */ s--;

while( *s == ' ' && s != rd ) s--; tail = s;

/* Довжина тексту */ len = (tail-head) + 1;

/* різниця вказівників – ціле число */ shift = (WIDTH - len)/2;

if(shift < 0 ){

fprintf(stderr, "Рядок довший ніж %d\n", WIDTH

);

shift = 0;

}

/* Друк результату */

for( i=0; i < shift; i++ ) putchar( ' ' );

while( head <= tail ) putchar( *head++ ); putchar( '\n' );

}

}

Приклад 7 Задача про розмін монети

Знайдемо всі можливі коефіцієнти a0 .. an розкладу числа S у

вигляді S = a0 * c0 + a1 * c1 + ... + an * cn, де c0 .. cn задані та впорядковані, ai >= 0, ci >= 0.

#include <stdio.h>

/* Тут задаємо вартості розмінних монет */ int cost[] = {

1, 2, 3, 5, 10, 15, 20, 50, 100, 300, 500 /* копі-

йок */

};

#define N

(sizeof cost / sizeof(int))

int count[ N ];

/* кількість монет даного типу

(коефіцієнти ai) */

long nvar;

/* число вариантов */

105

main( ac, av ) char *av[];

{

int coin;

if( ac == 1 ){

fprintf( stderr, "Вкажіть, яку монету размінювати: %s число\n",

av[0] ); exit(1);

}

coin = atoi( av[1] );

printf( " Таблиця розмінів монеты %d

коп.\n", coin );

printf( " Кожний стовпчик містить кількість монет вказаної вартості.\n" );

printf( "------------------------------------------------

-------------------\n" );

printf( "| 5р. | 3р. | 1р. | 50к.| 20к.| 15к.| 10к.| 5к.| 3к.| 2к.| 1к.|\n" );

printf( "------------------------------------------------

-------------------\n" );

change( N-1, coin );

printf( "------------------------------------------------

-------------------\n" );

printf( "Всього %ld варіантів\n", nvar );

}

/* рекурсивный размін */ change( maxcoin, sum )

int

sum;

/*

монета, яку міняємо */

int

maxcoin;

/*

індекс по масиву cost[] монети

максимальної вартості, допустимої при даному разміні.

*/

{

register i;

if( sum == 0 ){ /* вся сума розміняна */ /* роздрукувати черговий варіант */ putchar( '|' );

for( i = N-1 ; i >= 0 ; i-- ) if( count[i] )

printf(" %3d |", count[ i ] );

106

else

printf(" |" ); putchar( '\n' );

nvar++;

return;

}

if( sum >= cost [ maxcoin ] ){

/* якщо можна видати монету вартістю

cost[maxcoin] , то відати її:

*/

count[ maxcoin ] ++;

/* порахували видану мо-

нету */

 

/* розмінюємо залишок суми :

Перший аргумент - можливо можна дати ще одну таку монету ?

Другий аргумент - загальна сума зменшилась на одну монету cost[maxcoin].

*/

change( maxcoin, sum - cost[maxcoin] );

count[ maxcoin ] --; /* ... Тепер спробуємо інший варіант ... */

}

/* спробувати розмін більш мілкими монетами */ if( maxcoin )

change( maxcoin-1, sum );

}

Приклад 8. Програма, що друкує сама себе Напишемо програму, яка друкує “сама себе”. Такі програми є

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

#include <stdio.h>

/* 1

*/

char *s[] =

/* 2

*/

{

/* 3

*/

#include <stdio.h>

 

 

"char *s[] =",

 

 

"{",

 

 

"рядок 4",

 

 

...,

 

 

107

"рядок N"

 

 

 

};

/* 4

*/

рядок програми 5

/* 5

*/

...

/*

6

*/

рядок програми N

/*

7

*/

Роздрукувати програму можна, використовуючи цикл for.Загальна технологія наступна. Спочатку друкуємо перші три рядки програми як s[0],s[1],s[2]:

for(i=0; i<2; i++) {fputs(s[i], stdout); putc(NEW_LINE,stdout);}

Отримаємо:

#include <stdio.h>

/* 1

*/

char *s[] =

/*

2

*/

{

/*

3

*/

Потім–всі елементи , що ініціалізують масив вказівників s. При цьому необхідно друкувати відкриваючі лапки, s[i], закриваючі лапки, кому (крім останнього рядка ) і новий рядок. У рядкових константах не можемо використовувати лапки та символ нового рядка, тому доведеться використовувати їх коди відповідно 34 та 10 (для ASCII).

for(j = 0; j<21; j++) {putc(QUOTE,stdout); fputs(s[j], stdout); putc(QUOTE,stdout); putc(',',stdout); putc('\n',stdout);getch();}

Отримаємо всі рядки, що ініціалізують масив s:

#include <stdio.h>"char *line[] =", "{",

"рядок 4",

...,

"рядок N"

Потім друкуємо елементи масиву s, починаючи з четвертого (у схемі

"рядок 4"):

for(; i<21; i++) {fputs(s[i],stdout); putc(NEW_LINE,stdout);}

Отримаємо:

}; /* 4 */

108

рядок 4

/* 5

*/

...

/*

6

*/

рядок N

/*

7

*/

В наведеній схемі не використовуються пропуски, що не є принциповим.

Рядок N повинен містити закриваючу фігурну дужку. Набір рядків, очевидно, повинен містити фінкцію main() та відкриваючу фігурну дужку. Все інше в цьому переліку рядків може бути довільним. Ось текст програми:

#include <stdio.h> char *s[]=

{

"#include <stdio.h>", "char *s[] ={",

"};",

"#define QUOTE 34 ", "#define NEW_LINE 10 ", "int main()",

"{",

"int i,j;",

"for(i = 0; i < 2; i++)", "{fputs(s[i], stdout);", "putc(NEW_LINE,stdout);}", "for(j = 0; j<21; j++)", "{putc(QUOTE);", "fputs(s[j], stdout);", "putc(QUOTE,stdout);", "putc(',',stdout);", "putc(NEW_LINE,stdout);}", "for(; i<21; i++)", "puts(line[i], stdout);", "return 0;",

"}",

};

#define QUOTE 34 #define NEW_LINE 10 int main()

{

int i,j;

for(i=0; i<2; i++) {fputs(s[i], stdout); putc(NEW_LINE,stdout);} for(j = 0; j<21; j++)

109

{putc(QUOTE,stdout); fputs(s[j], stdout); putc(QUOTE,stdout); putc(',',stdout); putc('\n',stdout);getch();} for(; i<21; i++) {fputs(s[i],stdout); putc(NEW_LINE,stdout);} return 0;

}

5.10.5 Структури та об’єднання .

5.10.5.1 Структури

Синтаксично структури задаються наступним чином: struct [<тег>] {<список оголошення елементів >} <описувач> Наступна форма

struct <тег> <описувач> […<описувач>]-

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

Приклад:

struct point { int x,

int y;} A,B; struct { int x; float y;} Z,S;

Доступ до елемента структури здійснюється двома способами. Якщо визначений екземпляр структури, то доступ здійснюється конструкцією виду <описувач> . <ім’я поля>. У випадку, коли оголошений вказівник на екземпляр структури, доступ здійснюється з використанням операції ->: <вказівник> -> <ім’я поля>. Наприклад:

struct point *pa;

pa->x=4;

Структури можуть бути вкладеними, тобто полем структури також може бути структура:

struct line {int d; struct point a; struct point b;} L1,L2;

Доступ здійснюється таким чином:

L1.a.x=2;

L2.b.y=3;

Використовуємо стільки операцій доступу , скільки є рівнів вкладеної структури. Якщо оголосити вказівник на структуру line

110

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]