 |
DumpList (myList,Count); dumplist(myList,count);
Read(Kbd,Ch); ch = getch();
SortList(myList,Count); sortlist(myList,count);
DumpList(myList,Count); dumplist(myList,count);
Read(Kbd,Ch) ch = getch();
end.(* of DoSort *) } /* main */
---------------------------------------------------------------
Остановимся на наиболее важных моментах:
# В Паскаль-версии, мы помещаем процедуру SwapItem внутрь про-
цедуры SortList; в Си нельзя вкладывать функции, поэтому мы
вынесли swapitem "вне" sortlist.
# В Си массивы начинаются с индекса 0 и располагаются до <раз-
мерность>-1. Например,первый элемент myList - это myList[0],
a последний - myList[LMAX - 1]. Поэтому цикл for учитывает
это.
# Мы не использовали адресные операции и указатели, когда пе-
- 127,128 -
редавали myList[] в sortlist. Почему? Потому что Си всегда
передает адреса массивов, используемых как параметр, поско-
льку невозможно передать все значения массива не встречаясь
с трудностями. Как видно, когда мы определяем формальный па-
раметр list l в dumplist и sortlist, Си знает, что это мас-
сив с адресной передачей; так мы избавляемся от необходимос-
ти в операции адреса.
# Мы не нуждаемся в прототипах функций, так как все функции
описаны до их использования. Если мы захотим, мы можем рас-
положить прототипы после определения типов данных item и
list, и они будут выглядеть так:
void swapitem (item * i, item * j);
void sortlist (list l, int c);
void dumplist (list l, int c);
Снова отметим, что использование прототипов функций не тре-
бует изменения определения функций.
ОБЗОР СТРУКТУР ДАННЫХ
В этом разделе мы дадим вам обзор того, как структуры данных
в Си соотносятся со структурами данных Турбо Паскаля. Элементы, о
которых мы будем говорить - это указатели, массивы, строки,
структуры и объединения (смеси).
Pointers (Указатели).
-----------------------------------------------------------------
Можно длительное время программировать на Турбо Паскале и
никогда не использовать указатели; в Си не так. Почему? Потому
что, как отмечалось ранее, в Си используется передача параметров
функции только по значению. Так, если вы хотите изменить формаль-
ный параметр и сохранить изменение в фактическом параметре, то
вам досточно передать адрес формального параметра, причем описать
его как указатель на тип фактических данных. Другой ответ - реа-
лизация строчных переменных в Си как указателей на char, вследс-
твии чего любые операции с ними нуждаются в указателях.
- 129,130 -
Приведем несколько примеров описания и использования указа-
телей при программировании на Си и Паскале.
Турбо Паскаль Турбо Си
----------------------------------------------------------------
описание: :^<тип>; <тип> *;
IntPtr :^Integer; int *intptr;
Buff1 :^Intarray; int buff1[];
Buff2:array(0..N) of IntPtr; int *buff2[];
PHead :^Node; node *phead;
Head :Node; node head;
применение: ^ := <знач.>; * = <знач.>;
IntPtr^ := 22; *intptr = 22;
Buffer^[152] := 0; buff1[152] = 0;
PHead^.Next := nil; (*phead).next = NULL;
/* или phead->next=NULL; */
----------------------------------------------------------------
Отметим использование круглых скобок в последнем примере
(*phead), что тождественно специальному символу (->) во второй
версии phead.
- 131,132 -
Еще несколько примеров:
1. Buff1^[152] := 0; buff1[152] = 0;
2. Buff2[152]^ := 0; *buff2[152] = 0;
3. Head.Data^ := 0; *head.data = 0;
4. Head.Next := nil; head.next = NUll;
5. PHead^.Next := nil; (*phead).next = NUll;
/*or phead -> next = NULL;*/
В первом примере buff1 указывает на массив целых чисел.
Второй пример показывает, что buff2 это массив указателей на
целое.
В 3-ем примере head является записью (структурой в Си) с по-
лем data, которое указывает на целое.
В 4-ом head, также имеет поле next, которое указывает на не-
которую переменную.
В последнем phead является указателем на запись и запись
имеет поле next, которое, в свою очередь, является указателем.
Символ -> используется как короткое указание; выражение
pname -> fname = value;
говорит, что pname - указатель на некоторый тип записи,
fname - имя поля этой записи, а value передает значение этому по-
лю.
- 133,134 -
Arrays (Массивы).
-----------------------------------------------------------------
Массивы в Си значительно проще, чем в Паскале. Массивы в Си
могут иметь целый, символьный или перечислимый тип индексов, в то
время как в Паскале используется любой перечислимый тип. Все об-
ласти индексов начинаются от 0 и идут до n-1 (где n - размер мас-
сива). Это сильно отличается от Паскаля, где вы устанавливаете
границы индекса, как вам удобно. В Си массив индексируется сог-
ласно арифметике ссылок, и следующие выражения идентичны:
a[i] в Паскаль, a[i] и *(a + i) в Си.
Основной формат описания массивов следующий:
Турбо Паскаль Турбо Си
----------------------------------------------------------------
<имя>:array[<низ>..<верх>] of <тип>; <тип> <имя>[<размер>];
где <размер> равен (1 + <низ> - <верх>).
Многоразмерные массивы в Си определяются так же, как в Пас-
кале: <тип> сам является массивом какого-либо типа, или вы добав-
ляете значения размеров в конец:
<тип> <имя> [<размер1>] [<размер2>] [<размер3>];
Отметим, что в отличие от Паскаля, вы не имеете возможности
применять короткую запись, т.е. [] скобки с запятыми (см. Ошибку
#5).
|