- •Директивы препроцессора
- •Определяющие директивы Символические константы
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
- •Void main(void)
Void main(void)
{
char far *vid_mem=(char far *)0xB8000000; //адрес начала видеопамяти
int x, y;
char attr=0x71; //атрибут для вывода символа
for(x=0; x<80; x++) //заполнение экрана фоном
for(y=0; y<25; y++)
{
*(vid_mem+y*160+x*2)=176; //код символа
*(vid_mem+y*160+x*2+1)=attr; //значение атрибута
}
}
ЗАДАНИЕ
Выполнить следующие задания с использованием прямого доступа к видеопамяти.
Вариант 1
Ввести число с десятичной точкой и вывести его на экране в каждой строке, постепенно смещая начало вывода на пять позиций вправо относительно предыдущей строки.
Вариант 2
Написать функцию очистки произвольным фоном окна произвольного размера. Используя эту функцию очистить весь экран голубым цветом, затем в центре экрана изобразить красное окно с черной тенью.
Вариант 3
Написать функцию вывода произвольной строки в окне произвольного размера с указанной позиции относительно текущего окна. Большую строку можно делить, но не допускать выхода ее за пределы окна.
Вариант 4
Написать функцию, вычерчивающую рамку (двойную или одинарную) вокруг окна произвольного размера. Само окно уже очищено нужным фоном, цвет которого требуется сохранить.
Вариант 5
Написать функцию сохранения содержимого окна произвольного размера в памяти.
Вариант 6
Написать функцию восстановления содержимого окна произвольного размера из памяти.
Вариант 7
Написать функцию вывода произвольной строки в окне произвольного размера с указанной позиции относительно текущего окна. Если строка выходит за пределы окна, она обрывается.
Вариант 8
Написать функцию очистки произвольным фоном окна произвольного размера. Используя эту функцию вывести на экран двумерную прямоугольную диаграмму какого-либо процесса.
Вариант 9
Для текущего состояния экрана изменить цвет символов на красный, не изменяя цвета фона.
Вариант 10
Для текущего состояния экрана изменить цвет фона на красный под каждым изображенным символом, исключая пробел и не изменяя текущий цвет символа.
/* ЛАБОРАТОРНАЯ РАБОТА 6 (DIR_FILE)
УПРАВЛЕНИЕ НАКОПИТЕЛЯМИ, КАТАЛОГАМИ, ФАЙЛАМИ
Управление накопителями
Прототипы функций описаны в заголовочном файле dir.h.
int getdisk(void); - функция возвращает номер текущего диска (0 - A, 1 - B, 2 - C и т.д.).
int setdisk(int drive); - функция устанавливает текущим диск в соответствии с drive (0 - A, 1 - B, 2 - C и т.д.).
Управление каталогами
Прототипы всех функций описаны в заголовочном файле dir.h.
В некоторых функциях используются строки, максимальная длина которых указана в макроопределениях с учетом '\0':
MAXPATH (значение - 80) - путь
MAXDRIVE (значение - 3) - диск, включая двоеточие
MAXDIR (значение - 66) - каталог, включая '\'
MAXFILE (значение - 9) - файл
MAXEXT (значение - 5) - расширение, включая '.'
int chdir(const char *path); - функция изменяет текущий каталог в соответствии с path. Поиск ведется на текущем диске. Имя каталога задается относительно текущего или корневого каталога. Возврат при ошибке: 1.
int mkdir(const char *path); - функция создает один каталог с именем, определенным path. Возврат при ошибке: -1.
int rmdir(const char *path); - функция удаляет один каталог с именем, определенным path. Каталог должен быть пустым, не текущим, не корневым. Возврат при ошибке: 1.
int getcurdir(int drive, char *directory); - функция читает имя текущего каталога на устройстве drive (0 - по умолчанию, 1 - A, 2 - B, 3 - C и т.д.). Результат - в directory. Имя каталога не включает имя корневого каталога. Возврат при ошибке: -1.
char *getcwd(char *buf, int buflen); - функция читает полное имя текущего каталога (включая диск) в buf размером не более buflen. Результат - указатель на строку вида: C:\FFF\YYY. Возврат при ошибке: NULL.
int findfirst(const char *path, struct ffblk *ffblk, int attrib);
Функция ищет первый файл или каталог с данным именем и аттрибутом. Имя с указанием пути и диска ( возможно использование ? и * в имени). Атрибут (attrib) может иметь значения (необходимо пдключить dos.h):
0 - файл для чтения и записи
FA_RDONLY - файл для чтения
FA_HIDDEN - скрытый файл
FA_SYSTEM - системный файл
FA_LABEL - метка тома
FA_DIREC - каталог
FA_ARCH - архив.
Для найденного файла или каталога заполняется структура ffblk, cодержащая*/
char ff_reserved[21];
char ff_attrib; /* атрибут */
unsigned ff_ftime; /* время */
unsigned ff_fdate; /* дата */
long ff_fsize; /* размер */
char ff_name[13]; /* имя */
/*Возврат при ошибке: -1.
int findnext(struct ffblk *ffblk); - функция возвращает следующий файл или каталог с заданным именем и атрибутом (см.выше).
char *searchpath(const char *file); - поиск файла по имени сначала в текущем каталоге, а затем по установленным путям поиска. Результат - адрес строки с полным именем файла, начиная с имени диска.
/*Возврат при ошибке: NULL.
void fnmerge(char *path,const char *drive,const char *dir, const char *name, const char *ext);
Функция создает полное имя файла (path) из отдельных компонент: имя диска, каталога (путь), файла, расширения.
int fnsplit(const char *path, char *drive, char *dir, char *name, char *ext);
Функция разбивает полное имя (path) на составляющие компоненты (обратная fnmerge), каждая компонента обязательна, но может быть нулевой строкой.
Управление файлами
Временный файл
Прототипы функций описаны в заголовочном файле stdio.h.
char *tmpnam(char *s); - функция генерирует имя временного файла и помещает его в строку с указателем s. Возврат при ошибке: NULL.
FILE * tmpfile (void); - создает и открывает временный файл в режиме "w+", возвращает указатель потока. После выполнения программы временные файлы удаляются. Возврат при ошибке: NULL.
int rmtmp(void) - функция удаляет временные файлы, созданные с помощью tmpfile, в текущем каталоге. Возвращает число удаленных файлов.
Генерация имени
char *mktemp(char *template); - прототип в dir.h.
Функция создает уникальное имя с помощью модификации заданного имени template вида baseXXXXXX, где base - задается пользователем, XXXXXX - формируется функцией.Результат - адрес строки с именем. Возврат при ошибке: NULL.
Доступ к файлу
Прототипы функций в заголовочном файле io.h.
int access(const char *path, int amode); - функция проверяет существование файла и режимы доступа к нему (amode): 00 - существование, 04 - чтение, 02 - запись, 06 - чтение/ запись). Возврат: 0 - доступ разрешен, 1 - доступ не разрешен.
int chmod(const char *path, int amode); - изменить права доступа (amode):
S_IWRITE - запись, S_IREAD - чтение, S_IWRITE | S_IREAD -запись и чтение.
Необходимо подключить sys\stat.h. Возврат при ошибке: 1.
Размер файла
Прототипы функций в io.h.
long filelength (int handle); - функция возвращает длину в байтах файла с дескриптором handle. Возврат при ошибке: -1.
int chsize(int handle, long size); - функция расширяет (дозапись '\0') или сужает (обрезает с конца) файл с дескриптором handle до длины size. Возврат при ошибке: -1.
Действия над файлом
Прототипы функций описаны в stdio.h.
int remove(const char *c); - функция удаляет файл с заданным именем.
Возврат при ошибке: -1.
int unlink(const char *path); - функция удаляет файл с заданным именем, прототип и в io.h. Возврат при ошибке: -1.
int rename(const char *oldname, const char *newname);
Функция переименовывает файл или каталог или перемещает файл. Имя включает путь, но диск текущий. Возврат при ошибке: не нуль.
Пример 1.
/* С помощью функции getcurdir формируется имя текущего ката лога включая и имя диска и имя корневого каталога */
#include <dir.h>
#include <stdio.h>
#include <string.h>
char *current_directory(char *path)
{
strcpy(path, "X:\\"); /* в строку path записывается X:\ */
path[0] = 'A' + getdisk(); /* замена X на текущее имя диска */
getcurdir(0, path+3); /* с четвертой позиции строки path записывается текущий каталог на текущем диске */
return(path);
}
int main(void)
{
char curdir[MAXPATH];
current_directory(curdir);
printf("Текущий каталог %s\n", curdir);
return 0;
}
/* Пример 2.
/* С помощью fnsplit поразбить имя на составляющие части. */
#include <stdio.h>
#include <dir.h>
int main(void)
{
char *s="\autoexec.bat";
char drive[MAXDRIVE];
char dir[MAXDIR];
char file[MAXFILE];
char ext[MAXEXT];
int flags;
/* flags указывает заданы ли все компоненты в строке s */
flags=fnsplit(s,drive,dir,file,ext);
printf("Command processor info:\n");
if(flags & DRIVE) /* сформировано ли имя диска */
printf("\tdrive: %s\n",drive);
if(flags & DIRECTORY) /* сформировано ли имя каталога */
printf("\tdirectory: %s\n",dir);
if(flags & FILENAME) /* сформировано ли имя файла */
printf("\tfile: %s\n",file);
if(flags & EXTENSION) /* сформировано ли расширение */
printf("\textension: %s\n",ext);
return 0;
}
/* ЗАДАНИЕ
Вариант 1
Определить имена существующих дисков.
Вариант 2
Создать каталог внутри личного. Объявить его текущим. Переместить все файлы с расширением exe из личного каталога в созданный. Удалить файлы, запрашивая разрешение на удаление для каждого файла.
Вариант 3
Имя файла . Установить на каком диске, в каком каталоге записан файл. Создать файл (пустой) с таким же именем, но с расширением my в родительском каталоге.
Вариант 4
Из текущего каталога прочитать и выдать на дисплей файлы, предназначенные только для чтения и их размеры.
Вариант 5
Определить на каком диске существует каталог с именем , определить его размер, дату создания, объявить его текущим.
Вариант 6
У всех файлов в текущем каталоге с расширением exe изменить права доступа - разрешить только чтение. Попытаться удалить один из файлов.
Вариант 7
Создать каталог в корневом каталоге. Объявить его текущим, создать несколько пустых файлов (количество по запросу) с именами, созданных с помощью модификации имени file. Определить длину этих файлов.mktemp
Вариант 8
Найти самый длинный файл в каталоге (имя - по запросу).
Вариант 9
Создать каталог внутри личного. Переместить туда все файлы с расширением bak и выдать на дисплей информацию о них: время, дату создания, размер.
Вариант 10
Ввести с дисплея имя диска, каталога, файла и расширения. Создать указанный файл (пустой). Если каталог не существует -создать его. Исходные данные: С, \MMPP\PPUT, file5, mtm.
/* ЛАБОРАТОРНАЯ РАБОТА 7 (PROCESS)
УПРАВЛЕНИЕ ПРОЦЕССАМИ
Термин "процесс" относится к программе, которая выполняется под управлением операционной системы.
Используя функции управления процессом можно запустить, остановить и управлять процессом из программы.
Прототипы функций описаны в заголовочном файле process.h.
Запуск нового процесса
Функции exec... и spawn... используют для вызова одного процесса (дочернего) из другого (родительского). В функциях exec... дочерний процесс перекрывает родительский, поэтому возврат управления в родительский процесс невозможен. В функциях spawn... первый параметр mode определяет, что происходит с родительским процессом:
P_WAIT (значение 0) - приостановить на время работы дочернего,
P_OVERLAY (значение 2) - перекрыть родительский процесс дочерним (аналогично exec...). При нормальном завершении функции spawn... возвращают 0, при ошибке все функции возвращают -1.
int execl(char *path, char *arg0, ...,char *argN, NULL);
int spawnl(int mode, char *path, char *arg0, ...,char *argN, NULL);
int execle(char *path, char *arg0, ...,char *argN, NULL,char **env);
int spawnle(int mode, char *path, char *arg0, char *argN, NULL, char **env);
int execlp(char *path, char *arg0, ...,char *argN, NULL);
int spawnlp(int mode, char *path, char *arg0, ... char *argN, NULL);
int execlpe(char *path, char *arg0, ...,char *argN, NULL, char **env);
int spawnlpe(int mode, char *path, char *arg0, ..., char *argN, NULL, char **env);
int execv(char *path, char *argv[]);
int spawnv(int mode, char *path, char *argv[]);
int execve(char *path, char *argv[], char **env);
int spawnve(int mode, char *path, char *argv[], char **env);
int execvp(char *path, char *argv[]);
int spawnvp(int mode, char *path, char *argv[]);
int execvpe(char *path, char *argv[], char **env);
int spawnvpe(int mode, char *path, char *argv[], char **env);
При составлении имени функции к основе (exec и spawn) добавляются суффиксы: v,l,p,e, которые имеют следующие значения: v - вызываемому процессу список аргументов передается в виде массива указателей на строки символов (argv[0]-обязат.). Режим используется, когда число и значения аргументов определяются во время работы. l - вызываемому процессу список аргументов передается в виде отдельных строк (arg0 - обязателен). Режим используется, когда число аргументов постоянное и аргументы известны заранее. p - используется переменная окружения PATH для поиска файла. e - вызываемому процессу передается массив ссылок на переменные окружения env. Path - имя файла, или имя файла с указанием пути от корневого каталога, или имя файла с указанием пути от текущего каталога.
Если имя файла без расширения и не заканчивается точкой ищется файл .exe, .com, иначе - ищется файл без расширения.
Выполнение команды системы
int system(char *command); - дополнит.описана в stdlib.h.
Строка рассматривается как директива командному процессору. Возврат при ошибке: -1, иначе: 0.
Завершение процесса
void exit(int status); - дополнит. описана в stdlib.h.
Завершается процесс после скидывания буферов потоков.
status - код возврата (0 - норм.завершение).
Примеры
Нижеприведенная программа находится в файле c:\user\arg_main.c
и используется для запуска дочернего процесса из родительского.
/* Программа распечатывает на экране аргументы функции main и
окружение среды.
*/
#include <stdio.h>
int main( int argc, char *argv[], char **envp )
{
int i;
printf("аргументы:\n");
for (i=0; i < argc; ++i)
printf("[%2d] %s\n", i, argv[i]);
printf("окружение среды:\n");
for (i=0; envp[i]!=NULL; ++i)
printf("[%2d] %s\n", i, envp[i]);
return 0;
}
Файлы последующих программ находятся в каталоге c:\user\i41, он же является текущим.
Пример 1.
/* Функция execve. Аргументы дочернему процессу передаются через массив указателей на строки, среда окружения роди тельского процесса передается без изменения.
*/
#include <process.h>
#include <stdio.h>
#include <errno.h>
void main(int argc, char *argv[], char **envp)
{
int i;
printf("Аргументы командной строки:\n");
for (i=0; i<argc; i++)
printf("[%2d] : %s\n", i, argv[i]);
printf("функция arg_main...\n");
execve("\\user\\arg_main.exe", argv,envp);
/* оказываемся здесь только в случае ошибки при запуске
дочернего процесса */
perror("exec error");
exit(1);
}
Пример 2.
/* Функция execlpe. Аргументы дочернему процессу передаются как набор строк (последняя обязательно NULL), среда окру жения передается измененная (переменная PATH). Поиск файла arg_main.exe производится с использованием путей, определенных в PATH. */
#include <process.h>
#include <stdio.h>
#include <conio.h>
int main(int argc, char *argv[ ], char *envp[ ] )
{
int result,i= -1;
/* поиск строки окружения, начинающейся на PATH */
while(strncmp(envp[++i],"PATH",4)) ;
/* переменной PATH устанавливается новое значение */
strcpy(envp[i],"PATH=c:\\user");
clrscr();
puts("программа arg_main");
result = execlpe("arg_main.exe", "arg_main.exe", "арг1",NULL, envp);
perror("Error from execlpe");
exit(1);
return 0;
}
Пример 3.
/* Функция spawnvp. Путь до файла arg_main.exe указан относительно текущего каталога. Родительский процесс ожидает окончания дочернего, после чего выполняется функция system.
*/
#include <process.h>
#include <stdio.h>
#include <conio.h>
int main(int argc, char *argv[])
{
int result;
char str[80]="dir";
clrscr();
puts("программа arg_main");
result = spawnvp(P_WAIT, "..\\arg_main.exe", argv);
if (result == -1) /* ошибка при запуске */
{
perror("Error from spawnvp");
exit(1);
}
puts("выполняется команда системы dir");
system(str);
return 0;
}
ЗАДАНИЕ
На основе программы-меню написать программу, запускающую в качестве дочернего процесса несколько ранее написанных программ (одна из них (функции ввода-вывода системного уровня) использует аргументы функции main).
Выбор запускаемой программы организовать с помощью меню. После выполнения дочернего процесса управление возвращается в родительский процесс с предложением дальнейшего выбора. Окончание программы - по выбору пункта меню "выход". Файлы в разных каталогах.
Примечание. Для выполнения программы выгрузить TC.
/* ЛАБОРАТОРНАЯ РАБОТА 10 ГРАФИКА (GRAFIC)
Основные функцииinitgraph - инициализация графической системы closegraph - выход из графики
graphresult - контроль правильности выполнения графической функции (0 - верно)
grapherrormsg - описание ошибки при неверном выполнении функции
setviewport - установить графическое окно
getmaxx - максимальное значение по оси х
getmaxy - максимальное значение по оси y
getx - текущее значение х
gety - текущее значение y
moveto - установить курсор в позицию x, y
moverel - сместить текущую позицию курсора на вектор (x,y)
clearviewport - очистить текущее окно
cleardevice - очистка текущей страницы
getmaxcolor - максимальное значение цвета
setbkcolor - установить цвет фона
setcolor - установить значение рисующего цвета
getpixel - чтение пикселя
putpixel - запись пикселя
imagesize - определить размер памяти для сохранения фрагмента страницы
getimage - сохранить в памяти прямоугольный фрагмент страницы
putimage - восстановить на странице сохраненный фрагмент
line - вычертить линию между двумя точками
linerel - вычертить линию от текущей точки до другой, указанной как приращение относительно текущей
lineto - вычертить линию от текущей точки до другой, указанной явно
rectangle - вычертить прямоугольник по координатам верхнего и нижнего углов
drawpoly - ломанная линия, соединяющая последовательно ряд точек
circle - окружность по радиусу и координатам центра
arc - дуга окружности
ellipse - дуга эллипса
setlinestyle - установка вида линии
bar - заполненный прямоугольник
bar3d - заполненный параллелепипед
fillpoly - заполненный замкнутый многоугольник
fillellipse - заполненный эллипс
pieslice - заполненный круговой сектор
sector - заполненный эллиптический сектор
floodfill - заполнение области, замкнутый контур которой уже существует
setfillstyle - вид (шаблон и цвет) заполнения
settextstyle - инициализация знакогенератора
settextjustify - расположение выводимых строк
outtext - вывести текст относительно текущей опорной точки
outtextxy - вывести текст относительно опорной точки x,y.
ПРИМЕРЫ
Пример 1.
/* Графические примитивы, контурные фигуры.
Пока не нажата клавиша программа рисует случайные линии,
прямоугольники и окружности. */
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
int main(void)
{
int gdriver=DETECT,gmode,errorcode,wr,x,y;
/* инициализация графики, драйвер в тек.каталоге*/
initgraph(&gdriver,&gmode,"");
/* проверка правильности инициализации */
errorcode=graphresult();
if (errorcode !=grOk)
{
printf("ошибка:%s\n",grapherrormsg(errorcode));
printf("нажмите клавишу для возврата.");
getch();
exit(1);
}
/* максимальные значения x,y */
x=getmaxx();y=getmaxy();
randomize();
while(!kbhit()) /* пока не нажата клавиша */
{
switch(random(3)) /* возможные значения 0,1,2 */
{
case 0: /* рисует линию */
line(random(x),random(y),random(x),random(y));
break;
case 1: /* рисует прямоугольник */
rectangle(random(x),random(y),random(x),random(y));
break;
case 2: /* рисует окружность */
circle(random(x),random(y),random(y/2));
break;
}
delay(100); /* временная задержка */
}
delay(800);
getch();
closegraph (); /* выход из графики */
return 0;
}
Пример 2.
/* Графические примитивы, площадные фигуры. На экране рисуется заполненный эллипс */
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
int main(void)
{
int gdriver = DETECT, gmode, errorcode;
int midx, midy;
int radius = 100;
/* инициализация графики */
initgraph(&gdriver, &gmode, "");
/* проверка правильности инициализации */
errorcode = graphresult();
if (errorcode != grOk) /* ошибка */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1);
}
midx = getmaxx() / 2; /* поиск центра экрана */
midy = getmaxy() / 2;
setbkcolor(15); /* цвет фона */
setcolor(1); /* рисующий цвет */
/* нарисовать эллипс с установленным заполнением */
setfillstyle(1,4);
fillellipse(midx, midy, 100,50);
/* выход из графики */
getch();
closegraph();
return 0;
}
Пример 3.
/* вывод текста разными шрифтами разным размером */
#include <graphics.h>
#include <stdlib.h>
#include <stdio.h>
#include <conio.h>
/* названия шрифтов */
char *fname[] = { "DEFAULT font",
"TRIPLEX font",
"SMALL font",
"SANS SERIF font",
"GOTHIC font"
};
int main(void)
{
int gdriver = DETECT, gmode, errorcode;
int style, midx, midy;
int size = 1;
/* инициализация графики */
initgraph(&gdriver, &gmode, "");
/* проверка правильности инициализации */
errorcode = graphresult();
if (errorcode != grOk) /* ошибка */
{
printf("Graphics error: %s\n", grapherrormsg(errorcode));
printf("Press any key to halt:");
getch();
exit(1);
}
midx = getmaxx() / 2; /* поиск центра экрана */
midy = getmaxy() / 2;
/* местоположение текста относительно опорной точки */
settextjustify(CENTER_TEXT, CENTER_TEXT);
/* перебор шрифтов */
for (style=DEFAULT_FONT; style<=GOTHIC_FONT; style++)
{
cleardevice(); /* очистка видеостраницы */
size++ ; /* увеличение размера текста */
/* выбор режима знакогенератора */
settextstyle(style, HORIZ_DIR, size);
/* вывод сообщения */
outtextxy(midx, midy, fname[style]);
getch();
}
/* выход из графики */
closegraph();
return 0;
}
Пример 4.
/* Движение объекта.
рисуется картинка скачущего мячика, высота подъема уменьшается и он останавливается. Выводится горизонтальная и вертикальная надписи. */
#include<graphics.h>
#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<dos.h>
