Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ИДЗ 1 Вариант 8.doc
Скачиваний:
13
Добавлен:
20.06.2014
Размер:
131.58 Кб
Скачать

1.2. Строки

Стандартный Паскаль не определяет строки как отдельный тип данных. Турбо Паскаль определяет и поддерживает несколько процедур и функций для работы с ними. Си (и Турбо Си) не определяют отдельный строковый тип данных; однако, строки могут быть определены как массив char или указатель на char. Приведем для сравнения несколько описаний:

Турбо Паскаль

<имя> : string[<размер>];

type

BigStr = string[255];

StrPtr = ^BigStr;

var

Line : string[80];

Buffer: BigStr;

Word : string[35];

Ptr : StrPtr

Турбо Си

char <имя>[<размер>];

typedef char bigstr[256];

typedef char *strptr;

char line[81];

bigstr buffer;

char word[36];

strptr ptr;

Различия между строками в Турбо Паскаль и в Турбо Си связаны с различиями между массивами в двух языках.

В Турбо Паскале описание s : string [N] эквивалентно s : array of [0..N] of char. Строка имеет максимальную длину N символов; текущая длина хранится в S[0], в то время как сама строка располагается начиная с S[1]. Вы можете использовать операцию присваивания между строкой литералов или константой и строковой переменной. Паскаль побайтно передаст переменные и скорректирует длину.

В Турбо Си вы можете описать строку как char strarr [N] или как char *strptr. Первое описание выделит N байт для строки и запишет адрес в strarr. Второе описание только выделит несколько байт для strptr, которая указывает на char.

В Си длина строки не хранится; вместо этого используется строчный разделитель для маркировки конца строки. Этим разделителем является нулевой символ (ASCII 0), который определяет конец строки; строка начинается с strarr[0].

Поэтому, строка strarr может содержать только N-1 "реальных" символов, причем один байт должен быть отведен для разделителя. Вот почему Си-определения в сравнительной таблице имеют длину на один больше, чем соответствующие Паскаль - определения.

Далее, strarr не является фактической последовательностью байт, вы не можете прямо присвоить строку литералов. Вместо этого, вы должны использовать подпрограмму strcpy (или подобные) для побайтной передачи из одной строки в другую:

strcpy(strarr, "Hello, world!");.

Однако вы можете напрямую читать в strarr, используя функции scanf или gets.

Другой метод определения строк, char *strptr, потребует от вас больше забот. В этом случае, strptr только указывает на char: пространство для содержимого строки не распределяется, только несколько байт для указателя непосредственно.

Вы можете прямо присвоить strptr значение строки литералов; так как эти литералы создаются, как область с их объектным кодом, то вы просто присвоите их адрес переменной strptr. Если вы присвоите strptr значение strarr, то обе переменные будут указывать на одну и ту же строку. То же произойдет, если вы дадите strptr значение другого указателя на строку.

Каким же образом вы разместите strptr так, чтобы он указывал именно на свою собственную строку вместо еще чего-нибудь? Посредством выделения пространства:

strptr = (char*) malloc(N);

Это выделит отдельно N байт имеющейся памяти, с помощью процедуры malloc, и присвоит strptr адрес этой области. Вы можете затем использовать strcpy для переписывания строк (литералов или переменных) в эти выделенные байты.

В Паскале существует аналог этому (StrPtr, Ptr), но это очень грубый эквивалент.Вместо того, чтобы написать ^Char, StrPtr определяют как ^BigStr. При этом Турбо Паскаль узнает, что ptr является строкой . Это также помогает избежать любых проблем по проверке принадлежности к диапазону (контроль границ). Запись в следующем примере показывает, что только запрос пространства является действительным размещением ptr.

Вот список приблизительно подобных по действию операторов; обратитесь к Справочному руководству по Турбо Си для пополнения этих списков строковых функций Турбо Си. Эти операторы исходного описания типов, заданы в соответствии с предыдущим сравнением.

Турбо Паскаль Турбо Си

var main ()

Line,Name : BigStr; {

First,Temp: String #C; bigstr line,name;

Ptr : StrPtr; char first[81],temp[81];

I,Len,Err : Integer; char *ptr;

int i,len;

extern char*str char(char*s,char ch);

begin

Write('Enter name: '); printf("Enter name: *);

Readln(Name); gets(name);

I := Pos('',Name); ptr = strchr(name,'.');

if (ptr == NULL)

if I = 0 then strcpy(first,name);

First := Name else

else strncpy(first,name,ptr-name-1);

First := Copy(Name,1,I-1); Len=strlen (first);

Len:=Length(First); printf("len = \d\n",len);

Writeln('Len=',Len); strcpy(temh,"Hi,");

Temp:=Concat('Hi,'Name); strcat(temp,name);

puts(temp);

Writeln(Temp); if (strcmp(name,first))

if Name < > First strcpy(name,first);

then Name:=First; i=823;sprintf(temp,"\d", i);

I:=823;Str(I,Temp); i=atoi(temp);

Val(Temp,Err); ptr=(char*)malloc(81);

GetMem(Ptr,81); strcpy(ptr,"This is a test.");

printf("ptr=\s\n",ptr);

Ptr^:='This is a test.'; free(ptr);

Writeln('Ptr= ',Ptr^);

FreeMem(Ptr,81);

end. }

Использование Ptr в исходной программе, написанной на Паскале - это одна из вариантных записей и служит для того, чтобы получить эквивалент Си кода.

Последний пункт: прототипы функции для подпрограмм Си, вызываемых в этом примере, перечислены в заголовке файлов; так для обнаружения ошибки вам нужно расположить следующие #include операторы в начале программы Турбо Си.

# include<stdio.h>

# include<string.h>

# include<stdlib.h>

# include<alloc.h>