Студопедия
Главная страница | Контакты | Случайная страница

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатика
ИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханика
ОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторика
СоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансы
ХимияЧерчениеЭкологияЭкономикаЭлектроника

А) Ссылочные переменные б) Параллельные массивы

Читайте также:
  1. Б) Параллельные массивы
  2. Вложенные циклы. структурированные типы данных - массивы. объявление и использование массивов в программе. одномерные и многомерные массивы.
  3. Внешние и статические переменные, особенности их реализации.
  4. Внутренняя среда организации и ее основные переменные.
  5. Вопрос 23. Сложные типы данных. Массивы. Операторы ввода-вывода.
  6. Динамические переменные
  7. Издержки производства в краткосрочном периоде. Постоянные и переменные издержки. Общие, средние, предельные издержки, их графический анализ.
  8. Когда средние переменные затраты имеют минимальное значение?
  9. Логические основы ЭВМ. Логические функции и логические переменные

free (i); osvob(i);

Пример 16.5. Включение элемента *j в начало списка с указателем p (рис. 15.2):

j->uk = p; /* Соединить *j с первым элементом списка p */

p = j; /* Прицепить *j к указателю списка */

 
 

 


 

Рис. 16.2. Включение элемента *j в начало списка p

Эта операция выполняется правильно и для пустого списка.

Пример 16.6. Включение элемента *j в список после элемента *i (рис. 15.3). В примере 15.5 указатель списка p заменится на i->uk:

 
 

 


 

 

Рис. 16.3. Включение элемента *j в список после *i

j->uk = i->uk; /* Соединить *j с преемником элемента *i */

i->uk = j; /* Прицепить *j к элементу *i */

Эта операция выполняется и в конце списка, когда элемент *i не имеет преемника.

Пример 16.7. Исключение первого элемента из списка p:

if (p!= NULL) /* Cуществует первый элемент */

{ j = p; /* Запомнить адрес исключаемого эл-та */

p = p->uk; /* Соединить p со вторым элементом */

free(j); /* Освободить память *j */

}

else... /* Исключение невозможно: список пуст */

 

Пример 16.8. Исключение из списка преемника элемента *i (в примере 15.7 p заменится на i->uk):

if (i->uk!= NULL) /* Существует преемник элемента *i */

{ j = i->uk; /* Запомнить адрес преемника *i */

i->uk = i->uk->uk; /* Соединить *i с преемником его преемника */

free (j); /* Освободить память */

}

else... /* Исключение невозможно */

Если исключаемый элемент не требуется уничтожать (он может, например, входить еще и в другой список), память не освобождают.

Пример 16.9. Проход по списку p (в том числе пустому) с обработкой всех его элементов:

i = p;

while (i!= NULL) /* Существует *i (не конец списка) */

{... /* Обработка текущего элемента *i */

i = i->uk; /* Переход к следующему элементу списка */

}

Вариант с оператором for:

for (i = p; i!= NULL; i = i->uk)

... /* Обработка текущего элемента *i */

 

 

Задача 16.1. Дана последовательность из n идентификаторов. Длина каждого идентификатора не более 8 символов. Напечатать идентификаторы в лексикографическом порядке.

 

Пример теста:

n=7

 

Исх.посл-ть: Результат:

SIMV A

X A1

A1 SIMV

SL SL

Z20 TEXT

A X

TEXT Z20

 

Задачу можно решить, сцепляя идентификаторы в список в лексикографическом порядке по мере их ввода. В приведенной ниже

программе 16.1 после чтения очередного идентификатора сразу происходит добавление его в список, сформированный из предшествующих идентификаторов. На рис. 16.4 показано, как изменяется список в процессе включения в него очередных идентификаторов.

Еще несколько пояснений к программе. Идентификаторы поочередно вводятся в массив t_id с помощью функции gets(). Сравнение двух идентификаторов производится с помощью функции strcmp(), которая возвращает значение 0, если идентификаторы равны, и разность кодов двух соответствующих несовпавших символов, если идентификаторы не равны. Значит, значение функции будет < 0, если первый идентификатор в лексикографическом порядке должен следовать раньше второго, и значение будет > 0 в противном случае.

Рис. 16.4. Пример процесса формирования списка идентификаторов

 

 

Функция strcpy() служит для копирования строк символов, имеет два аргумента: указатель на строку, куда копировать, и указатель на строку, откуда копировать.

 

Программа 16.1:

 

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <conio.h>

#define MAXDL 9 /* макс.длина ид-ра (строки символов с

признаком конца '\0') */

 

struct EL_SP /* тип элемента списка */

{ char id [MAXDL]; /* идентификатор */

struct EL_SP *sled; /* ссылка на следующий элемент */

};

 

/*-------------------------------------------------------------------------------*/

/* функция включения очередного идентификатора в список */

/*-------------------------------------------------------------------------------*/

 

void Vkl (struct EL_SP **p, char t_id[])

/* Вх. данные: *p - указатель списка идентификаторов в

лексикографическом порядке,

t_id - включаемый в список (текущий) ид-р */

/* Вых. данные: *p */

{ struct EL_SP *pt, /* указатель включаемого эл-та */

*k,*j; /* указатели очередного и предыдущего

элементов списка */

/* выделение памяти для нового эл-та списка */

pt = (struct EL_SP *) malloc(sizeof(struct EL_SP));

strcpy(pt->id, t_id);

if (*p==NULL || strcmp(pt->id,(*p)->id) < 0)

{ /* включение ид-ра в начало списка */

pt->sled=*p; *p=pt;

}

else

{ /* поиск элемента списка, после которого нужно

включить идентификатор */

k=*p;

while (k!=NULL && strcmp(pt->id,k->id)>=0)

{ j=k; k=k->sled;

}

/* включение эл-та *pt после элемента *j */

j->sled=pt; pt->sled=k;

}

}

/*----------------------------------------------------------*/

/* функция печати списка */

/*----------------------------------------------------------*/

 

void PechSp (struct EL_SP *p)

/* Вх. данные: p - указатель начала списка */

{ struct EL_SP *i; /* указатель текущего элемента списка */

printf ("\nРезультат:\n");

for (i=p; i!=NULL; i=i->sled)

puts (i->id);

}

 

/*-----------------------------------------------------------*/

/* О С Н О В Н А Я П Р О Г Р А М М А */

/*-----------------------------------------------------------*/

 

main()

{ struct EL_SP *p; /* указатель начала списка */

unsigned n; /* количество идентификаторов */

unsigned i; /* параметр цикла */

char t_id[MAXDL]; /* текущий идентификатор */

 

printf ("\nВведите число идентификаторов\n n=");

scanf ("%u",&n);

getchar(); /* пропуск символа "перевод строки" */

p=NULL; /* список пока пуст */

printf ("Введите идентификаторы ");

printf ("(после каждого нажимайте клавишу <Enter>)\n");

for (i=1; i<=n; i++)

{ gets (t_id);

Vkl (&p,t_id); /* включение ид-ра в список */

}

PechSp (p); /* печать списка */

printf ("\n\nДля завершения нажмите любую клавишу\n");

getch();

}

 

Контрольные вопросы и упражнения

1. Как создать пустой список?

2. Как создать новый элемент списка?

3. Как включить в начало списка новый элемент, на который ссылается указатель i?

4. Напишите фрагмент включения элемента * i в конец списка.

5. Как удалить из списка 1-й элемент?

6. Приведите пример исходных данных для программы 15.1 и нарисуйте список, который сформирует программа.

7. Где в программе 16.1 происходит формирование списка?

8. Почему функции Vkl() передается адрес указателя списка p, а функции PechSp() – значение указателя p?

9. В функции Vkl() параметр p какого типа?

10. Как в функции Vkl() происходит обращение к указателю списка?

11. Изменится ли указатель списка p в главной программе, если функцию печати списка изменить следующим образом:

void PechSp (struct EL_SP *p)

{

printf ("\nРезультат:\n");

for (; p!= NULL; p =p -> sled)

puts (p -> id);

}

 




Дата добавления: 2015-02-16; просмотров: 100 | Поможем написать вашу работу | Нарушение авторских прав




lektsii.net - Лекции.Нет - 2014-2025 год. (0.013 сек.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав