Костюк - Основы программирования
.pdf201
/*11*/ – попытка чтения из первого файла 1000 байт в массив X, k – количе
ство прочитанных байт ;
/*12*/ – запись во второй файл k байт из массива X; /*13*/ – увеличение счетчика числа прочитанных байт;
/*15*/ – закрытие файлов; /*16*/ – вывод длины файла.
Файлы в программе открываются как двоичные, поэтому в них может быть запи сана произвольная информация.
Программа (Б.2) выполняет действия, аналогичные тем, которые описаны в про грамме (3.20), и, кроме того, производит дополнительные проверки.
Конец примера.
Пример Б.3. Программа сортировки слиянием линейного списка. Пусть описа ние структуры для элемента списка имеет вид:
struct el{int s; struct el *p;}; |
(Б.3) |
Вспомогательная функция (Б.2) слияния двух непустых упорядоченных по воз растанию линейных списков реализует на Си алгоритм (3.24).
|
|
void slist(struct el *p11, struct el *p22, |
|
struct el **p3) |
|
{struct el *p4,*p1,*p2; |
|
p1=p11; p2=p22; |
|
if (p1->s<=p2->s) |
|
{*p3=p1; p4=p1; p1=p1->p;} |
|
else {*p3=p2; p4=p2; p2=p2->p;} |
(Б.4) |
while ((p1!=NULL)&&(p2!=NULL)) |
|
if (p1->s<=p2->s) |
|
{p4->p=p1; p4=p1; p1=p1->p;} |
|
else {p4->p=p2; p4=p2; p2=p2->p;} |
|
if (p1!=NULL) p4->p=p1; |
|
} else p4->p=p2; |
|
В функции slist первые два параметра входные: p11 – указатель на начало первого списка, p22 – указатель на начало второго списка. Третий параметр p3 – выходной: после выполнения процедуры он будет являться указателем на начало объединенного списка, причем в функцию он передается по ссылке (поэтому в его описании имеется две звездочки). Функция конструирует выходной список из эле ментов двух входных списков, поэтому после ее исполнения входные списки пере стают существовать.
Функция (Б.5) реализует на Си рекурсивный алгоритм сортировки слиянием ли нейного списка (4.7).
202
|
|
void sortlist(struct el **p, int n) |
|
{struct el *p1, *p2; |
|
int k,i; |
|
if (n>1) |
|
{k=n/2; p1=*p; |
|
for (i=1;i<=k-1;i++) p1=p1->p; |
(Б.5) |
p2=p1->p; p1->p=NULL; p1=*p; |
|
sortlist(&p1,k); sortlist(&p2,n-k); |
|
} }slist(p1,p2,p); |
|
В функции sortlist первый параметр – указатель на начало списка сортиру емых элементов – в функцию передается по ссылке. Второй параметр задает количе ство элементов списка. Функция конструирует упорядоченный список из элементов входного списка.
Программа (Б.6) вначале вводит количество сортируемых чисел, затем сами эти числа и формирует из них линейный список. После этого с помощью вызова функции sortlist элементы списка упорядочиваются. В конце программы упорядоченные
элементы выводятся. Полный текст программы должен включать директивы:
#include <stdlib.h>
#include <stdio.h>
а также описание структуры (Б.3) и функции (Б.4) и (Б.5).
void main(void)
{int i,n,v;
struct el *p1, *p2, *p3;
scanf("%d",&n); /*ввода числа элементов n*/ p1=malloc(sizeof(struct el)); p2=p1;
/*создан 1–й элемент будущего списка*/
for(i=0;i<n;i++) |
|
/*ввод в цикле*/ |
|
{scanf("%d",&v); |
/*элементов и формирование*/ |
|
|
p2->s=v; |
/*из них списка*/ |
(Б.6) |
|
if(i<n-1) |
/*если не последний элемент списка*/ |
||
{p3=malloc(sizeof(struct el)); |
/*то создание*/ |
|
|
}}p2->p=p3; p2=p3; /*еще одного элемента списка*/ |
|
||
p2->p=NULL; /*обнуление последней ссылки в списке*/ |
|
||
sortlist(&p1,n); |
/*вызов функции сортировки списка*/ |
|
|
p2=p1; |
/*вывод в цикле элементов списка*/ |
|
|
while(p2!=NULL) |
|
||
{printf("%d ",p2->s); p2=p2->p;} |
|
|
203
}
Конец примера.
Пример Б.4. Программа численного интегрирования произвольной функции од ной переменной f (x) на интервале [a, b] методом трапеций путем деления интерва ла на n равных частей. Функция интегрирования Integr реализует алгоритм (3.28) из примера 3.25.
float Integr(float (*f)(float), float a, float b, int n)
{int i; float d,s;
s=(f(a)+f(b))/2; d=(b-a)/n; for(i=1;i<n;i++)
s=s+f(a+i*d); }return s*d;
Пусть в программе имеются следующие описания интегрируемых функций:
float f1(float x)
{return exp(sqrt(x));} float f2(float x)
{return sqrt(exp(x));}
(Б.7)
(Б.8)
Пусть также функции занумерованы числами 1 и 2. Тогда программа (Б.9) вводит номер подинтегральной функции, границы интервала и количество частей деления интервала, после чего вычисляет интеграл вызовом функции Integr и выводит вы численное значение интеграла. Ее текст должен содержать директивы:
#include <stdio.h>
#include <math.h>
void main(void) |
|
|
{float y, a, b; int i,n; |
|
|
const float (*f[])(float)={f1,f2}; |
|
|
/*описание константного массива функций*/ |
|
|
scanf("%d%d%f%f%d",&i,&a,&b,&n); |
(Б.9) |
|
y=Integr(f[i-1],a,b,n); |
/*ввод входных данных*/ |
|
/*вычисление интеграла*/ |
|
|
printf("%10.5f",y); |
/*вывод результата*/ |
|
} |
|
|
204
Конец примера.
Пример Б.5. Пусть программа вводит целое n, после чего генерирует и выводит все возможные перестановки чисел от 1 до n. Генерация перестановок осуще ствляется рекурсивным алгоритмом (4.8), который реализован в виде функции per, алгоритм (Б.10). В ней используются глобальные массивы P и R и переменная n.
Перестановка заносится в массив P, начиная с нулевого элемента. В программе (Б.11) в описании массива P указано 20 элементов, поэтому нельзя вводить n > 20 и генерировать перестановки с большим числом элементов.
void per(int k) /*функция генерации перестановок*/
{int i,j; for(i=1;i<=n;i++)
if(R[i]==0)
{P[k]=i; R[i]=1;
if(k==n-1) /*вывод сгенерированной перестановки*/
{for(j=0;j<n;j++)printf(”%3d”,P[j]); |
(Б.10) |
||
}printf(”\n”); /* переход к новой строчке вывода*/ |
|
||
else per(k+1); |
|
|
|
}R[i]=0; |
|
|
|
} |
|
|
|
|
|
|
|
#include <stdio.h> |
/*библиотека ввода-вывода*/ |
|
|
int n,P[20],R[21]; /*описание глобальных переменных*/ |
|
||
void main() |
|
|
|
{int i; |
|
/*ввод n*/ |
(Б.11) |
scanf(”%d”,&n); |
|
||
for(i=1;i<=n;i++) R[i]=0; /*обнуление массива R */ |
|
||
}per(0); |
/*вызов функции генерации перестановок*/ |
|
Конец примера.
Пример Б.6. Программа, вычисляющая определитель квадратной матрицы. Вы числение определителя осуществляется функцией Det, которая реализует алгорит
мы (7.16)–(7.20).
Первый параметр n функции Det, – размер матрицы, второй параметр A – указатель на область памяти, в которой размещены элементы матрицы по строкам. Функция вычисляет значение определителя с точностью, определяемой глобально
205
описанной константой eps. При обращении к элементам матрицы в выражениях
приводится явное вычисление индекса. Так, чтобы обратиться к элементу матрицы Aij в тексте программы записывается: *(A+i*n+j). В функции Det используется
глобальная константа eps, описание которой может иметь вид: const eps=1e-6;
|
|
|
float Det(int n, float *A) |
||
{int i=0, r=n, p=1, v, j, k; float z; |
|
|
while (i<r) |
/*выбор ведущего элемента*/ |
|
{v=i; |
|
|
for (j=i+1;j<n;j++) |
|
|
if (abs(*(A+j*n+i))>abs(*(A+v*n+i))) v=j; |
|
|
if (abs(*(A+v*n+i))<eps) r=i; |
|
|
else |
/*перестановка строк*/ |
|
{if (v!=i) |
|
|
{p=-p; |
|
|
for (j=i;j<n;j++) |
|
|
{z=*(A+i*n+j); *(A+i*n+j)=*(A+v*n+j); |
|
|
} }*(A+v*n+j)=z; |
/*вычитание строк*/ |
(Б.12) |
for (k=i+1;k<n;k++) |
|
|
{z=*(A+k*n+i)/ *(A+i*n+i); |
|
|
}for (j=i;j<n;j++)*(A+k*n+j)-=z* *(A+i*n+j); |
|
|
}i=i++; |
|
|
} |
/*вычисление определителя*/ |
|
if (r<n-1) z=0; |
|
|
else |
/*по треугольной матрице*/ |
|
{z=p**A; for (i=1;i<n;i++) z*=*(A+i*n+i);} |
|
|
}return z; |
|
|
Ниже приведена главная программа, вызывающая функцию Det.
void main()
{float y, *M; int i, j, n;
scanf("%d",&n); /*ввод размера матрицы*/
|
|
206 |
|
|
|
|
|
|
M=malloc(n*n*sizeof(float)); /*выделение памяти*/ |
||
|
for(i=0;i<n;i++) |
/*ввод элементов матрицы*/ |
|
|
for(j=0;j<n;j++) |
|
(Б.13) |
|
scanf("%f",M+n*i+j); |
/*вычисление определителя*/ |
|
|
y=Det(n,M); |
|
|
|
printf("%10.5f",y); |
/*вывод результата*/ |
|
|
}free(M); |
/*освобождение памяти*/ |
|
В программе (Б.13) вначале вводится размер матрицы n, после чего динамиче ски выделяется память для n2 элементов матрицы и производится построчно ввод всех n2 элементов. Далее с помощью вызова функции Det вычисляется значение определителя, которое затем выводится. В конце программы выделенная для матри цы память освобождается.
В тексте программы (Б.13) должно быть описание функции (Б.12), а также дирек тивы препроцессора:
#include <stdio.h>
#include <stdlib.h>
Конец примера.
Приложение В Таблицы кодов ASCII
В.1 Основная таблица ASCII
В таблице код символа вычисляется как сумма номера строки (от 0 до 15) и чис ла, которым помечен столбец. Например, код символа '<' равен 12+48=60. Основ
ная таблица ASCII содержит символы с кодами от 0 до 127, для их записи достаточно 7 бит. При записи кода в байт (8 бит) старший бит полагается равным нулю.
0 |
16 |
32 |
48 |
64 |
80 |
96 |
112 |
|
0 |
|
|
|
0 |
@ |
P |
‘ |
p |
1 |
|
|
! |
1 |
A |
Q |
a |
q |
2 |
|
|
" |
2 |
B |
R |
b |
r |
3 |
|
|
# |
3 |
C |
S |
c |
s |
4 |
|
|
$ |
4 |
D |
T |
d |
t |
5 |
|
|
% |
5 |
E |
U |
e |
u |
6 |
|
|
& |
6 |
F |
V |
f |
v |
7 |
|
|
’ |
7 |
G |
W |
g |
w |
8 |
|
|
( |
8 |
H |
X |
h |
x |
9 |
|
|
) |
9 |
I |
Y |
i |
y |
10 |
|
|
* |
: |
J |
Z |
j |
z |
11 |
|
|
+ |
; |
K |
[ |
k |
{ |
12 |
|
|
, |
< |
L |
\ |
l |
| |
13 |
|
|
- |
= |
M |
] |
m |
} |
14 |
|
|
. |
> |
N |
^ |
n |
~ |
15 |
|
|
/ |
? |
O |
_ |
o |
|
Коды от 0 до 31 соответствуют специальным управляющим символам, код 32 имеет символ пробела, код 127 – символ del (удаление).
208
В.2 Кодовая таблица 866 (MS DOS)
Вторая часть таблицы ASCII содержит символы с кодами от 128 до 255, при за писи кода в байт (8 бит) старший бит равен единице. В варианте для MS DOS содер жатся русские буквы, символы псевдографики (которые можно использовать для оформления таблиц), а также ряд других символов.
|
128 |
144 |
160 |
176 |
192 |
208 |
224 |
240 |
0 |
А |
Р |
а |
░ |
└ |
╨ |
р |
Ё |
1 |
Б |
С |
б |
▒ |
┴ |
╤ |
с |
ё |
2 |
В |
Т |
в |
▓ |
┬ |
╥ |
т |
Є |
3 |
Г |
У |
г |
│ |
├ |
╙ |
у |
є |
4 |
Д |
Ф |
д |
┤ |
─ |
╘ |
ф |
Ї |
5 |
Е |
Х |
е |
╡ |
┼ |
╒ |
х |
ї |
6 |
Ж |
Ц |
ж |
╢ |
╞ |
╓ |
ц |
Ў |
7 |
З |
Ч |
з |
╖ |
╟ |
╫ |
ч |
ў |
8 |
И |
Ш |
и |
╕ |
╚ |
╪ |
ш |
º |
9 |
Й |
Щ |
й |
╣ |
╔ |
┘ |
щ |
• |
10 |
К |
Ъ |
к |
║ |
╩ |
┌ |
ъ |
∙ |
11 |
Л |
Ы |
л |
╗ |
╦ |
█ |
ы |
√ |
12 |
М |
Ь |
м |
╝ |
╠ |
▄ |
ь |
№ |
13 |
Н |
Э |
н |
╜ |
═ |
▌ |
э |
¤ |
14 |
О |
Ю |
о |
╛ |
╬ |
▐ |
ю |
■ |
15 |
П |
Я |
п |
┐ |
╧ |
▀ |
я |
|
209
В.3 Кодовая таблица 1251 (MS Windows)
Вторая часть таблицы ASCII содержит символы с кодами от 128 до 255, при за писи кода в байт (8 бит) старший бит равен единице. В варианте для MS Windows наряду с русскими буквами содержится ряд других символов.
|
128 |
144 |
160 |
176 |
192 |
208 |
224 |
240 |
0 |
Ђ |
ђ |
|
º |
А |
Р |
а |
р |
1 |
Ѓ |
‘ |
Ў |
± |
Б |
С |
б |
с |
2 |
‚ |
’ |
ў |
І |
В |
Т |
в |
т |
3 |
ѓ |
“ |
Ј |
і |
Г |
У |
г |
у |
4 |
„ |
” |
¤ |
ґ |
Д |
Ф |
д |
ф |
5 |
… |
• |
Ґ |
µ |
Е |
Х |
е |
х |
6 |
† |
– |
|
¶ |
Ж |
Ц |
ж |
ц |
|
|
|
|
|
|
|
|
|
|
|
|
| |
|
|
|
|
|
7 |
‡ |
— |
§ |
· |
З |
Ч |
з |
ч |
8 |
€ |
□ |
Ё |
ё |
И |
Ш |
и |
ш |
9 |
‰ |
™ |
© |
№ |
Й |
Щ |
й |
щ |
10 |
Љ |
љ |
Є |
є |
К |
Ъ |
к |
ъ |
11 |
‹ |
› |
« |
» |
Л |
Ы |
л |
ы |
12 |
Њ |
њ |
¬ |
ј |
М |
Ь |
м |
ь |
13 |
Ќ |
ќ |
– |
Ѕ |
Н |
Э |
н |
э |
14 |
ћ |
ћ |
® |
ѕ |
О |
Ю |
о |
ю |
15 |
Џ |
џ |
Ї |
ї |
П |
Я |
п |
я |
Литература
По языкам Паскаль и Си существует необъятное число книг и учебников. Ин тересны книги автора языка Паскаль Н. Вирта [4, 12] и автора языка Си Д. Ритчи [14]. Книга [19] посвящена языку Си++, который является объектно-ориен тированным развитием Си. Для практической работы на компьютере потребуются книги или руководства по конкретному транслятору и операционной системе. Напри мер, для работы с транслятором Turbo Pascal можно использовать какую-либо из книг по языку и транслятору [10, 11, 20], а для работы с транслятором Turbo С –
книгу [17]. |
|
Об основных идеях доказательства правильности алгоритмов см. в книгах |
[1, |
4, 7, 8, 9]. Проблемы технологии программирования обсуждаются в книгах |
[2, 6, |
12, 16]. О рекуррентных последовательностях и алгоритмах см. в [1, 4, 5]. Об алго ритмах сортировки и поиска см. в [5, 14, 17]. О рекурсивных алгоритмах и бэктрекин ге см в. [1, 17]. Алгоритмы контекстного поиска имеются в [5, 15, 18]. Алгоритмы с графами имеются в [18]. Вычислительные алгоритмы линейной алгебры см., напри мер, в [3, 21].
1.Абрамов С. А. Математические построения и программирование. – М.: Наука, 1978. – 192 с.
2.Брукс Ф. П. мл. Как проектируются и создаются программные комплексы. Ми фический человеко-месяц: Пер. с англ. – М.: Мир, 1979. – 159 с.
3.Вержбицкий В.М. Основы численных методов. – М.: Высшая школа, 2002. – 840 с.
4.Вирт Н. Систематическое программирование. Введение: Пер. с англ. – М.: Мир, 1977. – 184 с.
5.Вирт Н. Алгоритмы + структуры данных = программы: Пер. с англ. – М.: Мир, 1985. – 406 с.
6.Гласс Р. Руководство по надежному программированию: Пер. с англ. – М.: Мир, 1982. – 280 с.
7.Грис Д. Наука программирования: Пер. с англ. – М.: Мир, 1984. –416 с.
8.Дал У., Дейкстра Э., Хоор К. Структурное программирование: Пер. с англ. – М.: Мир, 1975. – 245 c.
9.Дейкстра Э. Дисциплина программирования: Пер. с англ. – М.: Мир, 1978. – 275 c.
10.Епанешников А. М., Епанешников В. А. Программирование в среде Turbo Pascal 7.0. – 3-е изд., стер. – М: "ДИАЛОГ-МИФИ", 1995. – 288 с.