Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Array of String


Автор: Nic442 5.4.2006, 00:50
Надо создавать массив, но неисвестно его количество. Т.е. количество элементов будет наращиваться по одному и неизвестно конечное. Я бы, конечно мог, ограничить его 1000 но просто его надо будет очищать, причем очень часто. И если в массиве будет один элемент, то нецелессообразно гнать цикл до 1000. Я понимаю, что нужны указатели, но плохо их знаю. Можите привести пример заполнения массива? smile

Код

struct_name: array of String;

Автор: Poseidon 5.4.2006, 00:57
Код

procedure MyProcedure;
const col = 10; // количество элементов массива
var
struct_name: array of String;
i: integer;
begin
for i:= 0 to col do
  begin
  SetLength(struct_name, Length(struct_name)+1); // увеличиваем размер массива на 1
  struct_name[i]:= IntToStr(i); // заполняем массив
  end;
end;


Массив будет от 0 до Length(struct_name)-1

Автор: Nic442 5.4.2006, 01:11

ВОТ СПАСИБО. Я даже не ожидал, что обойдётся без указателей. СПАСИБО smile . Я чуть не повесился, теперь буду дальше лопатить прогу.
А можно ещё вопрос: Как string запихнуть в буфер? (Вы просто так быстро ответили :-) )

Автор: Poseidon 5.4.2006, 01:17
Один топик - один вопрос!

Следуй этому правилу ;)

PS Как я понимаю "буфер" - это буфер обмена.
Добавь в uses Clipbrd
и вот так добавляй
Код

Clipboard.SetTextBuf(PChar(YouText));
понятно что YouText: string

Автор: Nic442 5.4.2006, 01:25
СПАСИБО
Тогда вопросов больше не имею. Ещё раз спасибо.

{Close Theme}

Автор: Alex 5.4.2006, 08:37
Хотелось бы сделать небольшое уточнение про заполнение массива, т.к. кол-во элементов в массиве перед выполнением цикла нам известно заранее, то нет необходимости увеличивать размер массива в цикле (это очень не эффективно на больших массивах), лучше выставить требуемый размер массива до цикла:
Код

const col = 10; // количество элементов массива
var
  struct_name: array of String;
  i: integer;
begin
  SetLength(struct_name, col+1); // Устанавливаем размер массива
  for i:= 0 to col do begin
    struct_name[i]:= IntToStr(i); // заполняем массив
  end;
end;

Автор: Marriage 5.4.2006, 08:45
Код

procedure TForm1.Button1Click(Sender: TObject);
var
sl:TstringLIst;
begin
 sl:=TstringList.Create;
 sl.Add('123');
 sl.Free;
end;


И обращаться как sl.Strings[0] ,sl.Strings[1] по индексам. smile)
При чем можешь сразу же сохранить фсе это в файл sl.SaveToFile или загрузить sl.LoadFromFile

Автор: Nic442 5.4.2006, 12:31
Я понимаю, что лучше выносить функции за цикл.
SetLength(struct_name, col+1);
Но в любом случае у меня получится в цикле. Дело в том что у меня цикл в цикле. Но вот опять возник вопрос по теме. А как мне очищать массив, чтобы количество элементов стало равно 0?

Код

var    
  struct_name: array of String;    
  i: integer;
begin 
 i:=Hight(struct_name);
 for i:=i downto -1 do begin
   struct_name[i]:='';
   SetLength(struct_name, Length(struct_name)-1);              // ВОПРОС вот так вот можно ?
   dec(i);
 end;
end;

Автор: Romikgy 5.4.2006, 12:43
Цитата(Marriage @ 5.4.2006, 07:45 Найти цитируемый пост)
TstringList

через это нельзя
Nic442, smile

Автор: Alexeis 5.4.2006, 12:49
Цитата

А как мне очищать массив, чтобы количество элементов стало равно 0?

struct_name := Nil;
для строки
struct_name[i] := '';
Добавлено @ 12:51
Вообще странный цикл
Цитата

for i:=i down
smile

Автор: ~FoX~ 5.4.2006, 12:57
Цитата(Nic442 @ 5.4.2006, 13:31 Найти цитируемый пост)

for i:=i downto -1 do begin
  struct_name[i]:='';
  SetLength(struct_name, Length(struct_name)-1);              // ВОПРОС вот так вот можно ?
  dec(i);
end;

НЕТ!
1. i:=i -> incompotibe types .......
2. dec(i) -> Assigment to FOR-Loop variable (i)
3.
Цитата(Nic442 @ 5.4.2006, 13:31 Найти цитируемый пост)
А как мне очищать массив, чтобы количество элементов стало равно 0?


Код

SetLength(struct_name, 0);


Автор: Moskalev 5.4.2006, 13:00
Я сам всегда делал:
Код

SetLength(struct_name, 0); //длина массива становится 0

но думаю, что это не правильно (не совсем правильно по нормам языка, ведь есть nil)

Автор: ~FoX~ 5.4.2006, 13:02
Moskalev,
Цитата(Nic442 @ 5.4.2006, 13:31 Найти цитируемый пост)
чтобы количество элементов стало равно 0?

Как задача поставлена, так ее и решают!
Добавлено @ 13:06
только вот я не понял, а чем собствено TStrings, TStringList не устраивает, зачем велосипед то изобритать?

Автор: Nic442 5.4.2006, 13:26
Romikgy
Код

через это нельзя 
Я не разу не использовал этот тип. Но сейчас попробую...Может не будет той ошибки которая внизу.

Код

struct_name := Nil;
Так и сделаю. Если это правильно.

А как передавать массив в функцию, и в функции добавлять к нему элементы?

Код

var 
 Slova: array of String;
...
   SetLength(Slova, Length(Slova)+1);
   Slova[0]:='тут ';
   SetLength(Slova, Length(Slova)+1);
   Slova[1]:='там ';
....
   My_Find(Slova);


Код

function TIndex_Form.My_Find(struct_name: array of String)
begin
   ....
    SetLength(struct_name, Length(struct_name)+1);          // Так выдаёт ошибку
    struct_name[High(struct_name)+1]:='проро ';
  ....
end;

Автор: ~FoX~ 5.4.2006, 13:35
В функцию ты не можешь передавать массив, только указатель на него....

Автор: Демо 5.4.2006, 13:57
Цитата(~FoX~ @ 5.4.2006, 13:35 Найти цитируемый пост)
В функцию ты не можешь передавать массив, только указатель на него....


Ну почему, по ссылке массив можно передать и работать с ним:

Код

type
  TStrArray=array of String;

procedure FillStrArray(var sa: TStrArray; Size: Integer);
var
  i: Integer;
begin
  SetLength(sa,Size);
  for i := 0 to Size-1 do
    sa[i] := IntToStr(i);
end;


procedure TForm1.Button2Click(Sender: TObject);
var
  SArray: TStrArray;
begin
  SetLEngth(SArray,0);
  FillStrArray(SArray,100);
  ShowMessage(SArray[1]);
end;


Автор: Alexeis 5.4.2006, 14:06
Демо,
Цитата

по ссылке массив можно передать и работать с ним:

а это разве не тоже самое что передавать указатель smile

Автор: Демо 5.4.2006, 14:09
Цитата(alexeis1 @ 5.4.2006, 14:06 Найти цитируемый пост)
а это разве не тоже самое что передавать указатель


Конечно, нет.

Автор: Nic442 5.4.2006, 14:10
Код

function TIndex_Form.My_Find(struct_name: array of String)
var
nomer_bukvi: Byte;
mas_slov: array of String;
begin
hight_mas:= High(struct_name);

    for nomer_bukvi:=0 to hight_mas do begin
       SetLength(mas_slov, Length(mas_slov)+1);
       mas_slov[nomer_bukvi]:= struct_name[nomer_bukvi];
    end;
   nomer_bukvi:=1;
...
    SetLength(mas_slov, Length(mas_slov)+1);          // А вот так работает!?
    mas_slov[High(mas_slov)+1]:='проро ';
end;

Автор: Демо 5.4.2006, 14:13
~FoX~,
Кстати, и возвращать массив из функции тоже можно.

Автор: ~FoX~ 5.4.2006, 14:22
Код

  procedure aaa(a: array of integer);

procedure TForm1.Button1Click(Sender: TObject);
var
  a: array of integer;
begin
  aaa(a);
end;

procedure aaa(a: array of integer);
begin
  SetLength(a, 10);
end;



Цитата(Демо @ 5.4.2006, 14:57 Найти цитируемый пост)
procedure FillStrArray(var sa: TStrArray; Size: Integer);

А что такое var????

Автор: Romikgy 5.4.2006, 14:23
Цитата(Nic442 @ 5.4.2006, 12:26 Найти цитируемый пост)
попробую

попробуй, узнаешь , что намного проще чем тебе изобретать велосипедsmile

Автор: Alexeis 5.4.2006, 14:31
Демо, Как же нет, при передаче через var парамет реально передается ссылка (т.е. указатель) на эту переменную, просто доступ к нему осуществляется как к уже к разименованному, а по сути это все одно и тоже.

Автор: Romikgy 5.4.2006, 14:38
~FoX~, procedure FillStrArray(var sa: TStrArray; Size: Integer);
это ?
если да то это обозначает что переменая может изменится и в измененом состоянии вернутся в основную программу

Автор: ~FoX~ 5.4.2006, 14:43
[OFFTOP]
Romikgy,
Цитата(alexeis1 @ 5.4.2006, 15:31 Найти цитируемый пост)
, при передаче через var парамет реально передается ссылка (т.е. указатель)

[/OFFTOP]

Автор: Nic442 5.4.2006, 14:45
Так мой код нормальный? В основную программу функция ничего не долна возвращать. Она должна принимать статический массив, и если что-то находит то дополнять его и осуществлять с ним нужные операции.
Код

function TIndex_Form.My_Find(struct_name: array of String)    
var    
nomer_bukvi: Byte;    
mas_slov: array of String;    
begin    
 hight_mas:= High(struct_name);    
 for nomer_bukvi:=0 to hight_mas do begin    
    SetLength(mas_slov, Length(mas_slov)+1);    
    mas_slov[nomer_bukvi]:= struct_name[nomer_bukvi];    
 end;    
 nomer_bukvi:=1;    
...    
    SetLength(mas_slov, Length(mas_slov)+1);          // А вот так работает!?    
    mas_slov[High(mas_slov)+1]:='проро ';    
end;

Автор: Romikgy 5.4.2006, 14:48
~FoX~, ну и что я не правильно сказал?

Автор: Демо 5.4.2006, 14:48
alexeis1,
Разименуй плиз здесь и выполни те же функции, что и в FillStrArray выше:

Код

procedure FillStrArray1(p: Pointer; Size: Integer);
var
  sa: TStrArray;
  i: Integer;
begin
//???
end;


Автор: Poseidon 5.4.2006, 14:53
Цитата(Nic442 @ 5.4.2006, 13:45 Найти цитируемый пост)
Так мой код нормальный?
не нормальный! Во первых ругнется компилятор на то, что нет результата у функции. Во вторых не обьявлена hight_mas. В-третьих послушай совета Алекса и выдели память под массив до начала его заполнения, а не в цикле.

Это так, при первом осмотре...

Автор: ~FoX~ 5.4.2006, 14:59
Цитата(Nic442 @ 5.4.2006, 15:45 Найти цитируемый пост)
2:
function TIndex_Form.My_Find(struct_name: array of String)

Попробуй откомпили и посмотри.....что скажет компилятор.....
Добавлено @ 14:59
ой, не успел smile

Автор: Демо 5.4.2006, 15:37
Цитата(alexeis1 @ 5.4.2006, 14:31 Найти цитируемый пост)
Демо, Как же нет, при передаче через var парамет реально передается ссылка (т.е. указатель) на эту переменную, просто доступ к нему осуществляется как к уже к разименованному, а по сути это все одно и тоже.


Параметр передается по-ссылке, но ссылка и указатель - суть разные вещи.

Ссылка - адрес.
Указатель - переменная.

т.е. Указатель может содержать ссылку, но не наоборот, и тождества между ними нет.

PS.

Забыл добавить - это мое мнение-)

Автор: Yanis 5.4.2006, 16:01
Цитата(alexeis1 @ 5.4.2006, 12:49 Найти цитируемый пост)
struct_name := Nil;

Так же это можно сделать ещё двумя способами:
Код

Finalize(some_din_array);
SetLength(some_din_array, 0);


Цитата(alexeis1 @ 5.4.2006, 12:49 Найти цитируемый пост)
Вообще странный цикл

Цитата

for i:=i down
Здесь нет ничего странного. Delphi (да и Pascal кажется тоже) позволяет использовать циклы "наоборот", т.е. с уменьшением счётчика. А на месте слова down должно в твоём случае быть downto smile

Цитата(~FoX~ @ 5.4.2006, 12:57 Найти цитируемый пост)
1. i:=i -> incompotibe types .......
Интересно было бы узнать откуда у вас такая информация, потому что у меня есть подозрения, что ты неправ.

Цитата(Moskalev @ 5.4.2006, 13:00 Найти цитируемый пост)
но думаю, что это не правильно (не совсем правильно по нормам языка, ведь есть nil)
Ты все правильно. Тут никаких норм нету.

Цитата(Nic442 @ 5.4.2006, 13:26 Найти цитируемый пост)
Так и сделаю. Если это правильно.
Как я уже сказал можно и SetLength использовать.

Цитата(~FoX~ @ 5.4.2006, 13:35 Найти цитируемый пост)
В функцию ты не можешь передавать массив, только указатель на него....

Цитата(Демо @ 5.4.2006, 13:57 Найти цитируемый пост)
Ну почему, по ссылке массив можно передать и работать с ним:
Цитата(alexeis1 @ 5.4.2006, 14:06 Найти цитируемый пост)
а это разве не тоже самое что передавать указатель
Цитата(Демо @ 5.4.2006, 14:09 Найти цитируемый пост)
Конечно, нет.
Демо прав. Ссылка это не тоже самое, что и указатель. Кто хочет попорить, прошу.

Цитата(Демо @ 5.4.2006, 14:13 Найти цитируемый пост)
Кстати, и возвращать массив из функции тоже можно.
Можно возвращать ссылку или указатель!

Цитата(Romikgy @ 5.4.2006, 14:38 Найти цитируемый пост)
если да то это обозначает что переменая может изменится и в измененом состоянии вернутся в основную программу
Просто о существовании переменной "знают" две процедуры, поэтому если они что записывают в эту переменную, то записывают по одному адресу. Соответственно отсуда и эффект того, что "переменная может изменяться".

Цитата(Nic442 @ 5.4.2006, 14:45 Найти цитируемый пост)
Она должна принимать статический массив, и если что-то находит то дополнять его и осуществлять с ним нужные операции
А сам передаешь динамический... smile
Добавлено @ 16:01
2 Демо
Блин опередил
Добавлено @ 16:02
Редиска smile

Автор: Nic442 5.4.2006, 17:55
Буду исправлять код. Будут вопросы обязательно напишу.
Код

А сам передаешь динамический...

Это исправлю.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)