2015-04-02 8 views
0
type 
TS = record 
    FN, RN: String; 
end; 
var 
Sy: array of TS;  
S: ^String; 

... 

      SetLength(Sy,2); 
      begin 
      Sy[0].FN:='123'; 
      Sy[0].RN:='bad'; 
      Sy[1].FN:='345'; 
      Sy[1].RN:='000'; 
      end; 


... 

S := @(Sy [i].FN); 

Как подражать логике Паскаля на языке C? Следующий код не работает:c язык. SetLength, массив структур

typedef struct 
{ 
     char FN[256];//char FN[] /*isn't allowed by compiler*/ 
     char RN[256];//char RN[] /*isn't allowed by compiler*/ 
} TS; 
TS Sy[]; 
main() 
{ 
    Sy=malloc(2*sizeof(TS)); 
    strcpy(Sy[1].FN,"1234"); 
} 

ВОПРОС 1

Я получаю ошибку компилятора error C2106: '=' : left operand must be l-value. Что я должен сделать, чтобы подражать логике Паскаля в случае SetLength?

ВОПРОС 2

Как указать строку неизвестного размера (AnsiStrings является Паскаль). Когда я установил char FN[];, я получаю ошибку error C2229: struct '<unnamed-tag>' has an illegal zero-sized array. Что я должен сделать, чтобы подражать логике Паскаля в случае Ансистринга?

+0

Должно быть, это просто C, а не, например. C++? C++ по крайней мере имеет std :: string. –

+0

Это должен быть ANSI C. ** Не C++. ** – testnameC04

+0

Как я вижу в отладчике, SetLength (Sy, 2) Паскаля выделяет память из 6 слов: 01 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00. 1-й dword всегда $ 00000001 (мало-Endian порядка) (я не знаю, для чего он предназначен). 2nd dword - количество элементов, уменьшенных на 1. 3rd - это Sy [0] .FN адрес (указатель на строку, которая будет нажата в FN). Четвертый - адрес Sy [0] .RN. 5-й адрес Sy [1] .FN. 6-й - адрес Sy [1] .RN. И длина Паскаля (Sy) будет просто получать адрес выделенного 6 слов в качестве параметра, увеличить его на 4 (так что это второй dword), извлечь значение, увеличить его на 1. – testnameC04

ответ

0

Вопрос 1: malloc() возвращает указатель на void (void *), поэтому я думаю, что Sy должен быть типом указателя. Самый прямой способ - изменить TS Sy[] на TS *Sy. Затем при использовании malloc вам нужно будет направить указатель на указатель TS, например: Sy = (TS *) malloc (2 * sizeof (TS));

Вопрос 2: Насколько я знаю, единственным подходящим типом, который будет работать, будет c-строка. В этом случае решение аналогично решению вопроса 1, измените FN[] и RN[] на *FN и *RN. Однако я не очень разбираюсь в C, и это может быть не самый эффективный способ обработки вещей, тем более, что с тех пор я полагаю, что структура не займет смежного пространства памяти. Другая проблема заключается в том, что вам нужно будет указать размер c-строки в какой-то момент, но вы сможете делать это динамически, а не во время компиляции.

(Изменить) В качестве дополнительной заметки вы также должны использовать free(), чтобы освободить память, выделенную malloc, когда вы закончите с ней.

+0

Как я могу видеть в OllyDBG, Visual Studio генерирует идентичный код в обоих случаях: Sy = (TS *) malloc (2 * sizeof (TS)); 'и' Sy = malloc (2 * sizeof (TS)); '. Таким образом, приведение типов не требуется. – testnameC04