Использование указателей bc++, страница 4

// Список был пуст - это последний элемент

target->next = NULL;

target->value = value;

count++;

}

}

// Удалить выбранный элемент

void delete_any(int pos)

{

if(pos<0) return;

// Это предыдущий за удаляемым элемент

LIST * previous;

int i = 0;

// Если список пуст - удалять нечего

if(head!=NULL)

{

// Различные алгоритмы для удаления первого и следующих элементов

if(pos==0)

{

// Сохраняем следующий элемент

LIST * next_item = head->next;

// Освобождаем память

free(head);

// Восстанавливаем связность

head = next_item;

}

else

{

previous = head;

// Поиск элемента (пока не нужный номер или не вышли за список)

//Нужно найти ПРЕДЫДУЩИЙ перед удаляемым элемент

pos--;

while((i<pos)&&(previous!=NULL))

{

previous = previous->next;

i++;

}

if(i!=pos) return;

// Сохраняем следующий элемент

LIST * next_item = previous->next->next;

//Освобождаем память

free(previous->next);

// Восстанавливаем связность

previous->next = next_item;

}

}

count--;

}

// Выбрать элемент

int select_element(char color)

{

int number = 0;

char key = 0;

dvid.puttext(15, 42, 15, "Выберите элемент");

dvid.puttext(17, 42, 15, "Клавиши '8' и '2' перемещают указатель");

dvid.puttext(18, 42, 15, "ПРОБЕЛ - завершение выбора");

dvid.puttext(19, 42, 15, "ESC - отмена");

dvid.flip();

while((key!=' ')&&(key!=27))

{

dvid.fillarea(0,25,24,26,' ',7);

dvid.puttext(number+2,25,color,"<-");

dvid.flip();

key = getch();

switch(key)

{

case '8' : if(number>0) number--; break;

case '2' : if(number<(count-1)) number++; break;

}

}

if(key==' ')

return(number);

else

return(-1);

}

void main(void)

{

// Инициализация DIRECT_VIDEO

if(!dvid.init())

{

printf("Невозможно инициализировать DIRECT_VIDEO\nВозможен некорректный видеорежим\n");

exit(0);

}

show();

char key = 0;

long index = 0;

int position;

// Начало основного цикла программы

while(key!='0')

{

key = getch();

switch(key)

{

case '1' :

if (count<22) add_to_head(index++);

break;

case '2' :

if (count<22) insert(count-1, index++);

break;

case '3' :

if (count<22) {

if(count==0) break;

position = select_element(10);

if((position>=0))

insert(position, index++);

}

break;

case '4' :

if(count==0) break;

delete_any(select_element(12));

break;

}

show();

}

// Завершение работы DIRECT_VIDEO

dvid.fill(' ',7);

dvid.flip();

dvid.done();

}

Вывод на экран реализован при помощи класса DIRECT_VIDEO, обеспечивающего прямой доступ к видеопамяти текстового режима адаптеров CGA, EGA и VGA:

Файл "dvideo.h": // Описывает класс, обеспечивающий прямой доступ к видеопамяти в

// текстовом режиме 80x25

#if !defined(_DIRECT_VIDEO)       // Проверка на включение файла

#define _DIRECT_VIDEO

#include <alloc.h>

#include <mem.h>

struct CGA_RAM_ELEMENT          // Описание элемента видеопамяти CGA

{

char ch, attr;

};

struct CGA_RAM                  // Описание структуры памяти CGA

{

CGA_RAM_ELEMENT data[25][80];

};

class DIRECT_VIDEO              // Класс доступа к видеопамяти CGA

{

public:                     // Общий блок

CGA_RAM * work_page;

int init(void);    // Инициализация

void done(void); // Завершение работы

void fill(char ch, char attr); // Заполнение страницы

void fillarea(char r1,char c1,char r2,char c2,char ch,char attr); // Заполнение области

void flip(void); // Обновление страницы на экране

void puttext(char row, char col, char attr, char* text); // Вывод текста

private:

CGA_RAM far * video_ram;

};

int DIRECT_VIDEO::init(void)

{

char far *bios_video_mode = (char*)(0x00000449); // Видеорежим BIOS

asm {    // Попытка инициализировать видеорежим 3

mov ax, 0x03;

int 0x10;

}

switch(*bios_video_mode)    // Проверка видеорежима и инициализация видеопамяти

{

case 3 : video_ram = (CGA_RAM*)(0xB8000000); break; // Цветной видеорежим

case 7 : video_ram = (CGA_RAM*)(0xB0000000); break; // ЧБ видеорежим

default : return(0);

}