Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Работа с массивом

375
07 января 2006 года
dominator
199 / / 16.10.2003
Здравствуйте!
Подскажите, пожалуйста, как мне получить доступ к следующему элементу массива, используя указатель на первый элемент массива?
Ситуация в упрощенном виде примерно такая:

procedure Execute();
var
i :Integer;
p_RecordsetFields :^String;
_RecordsetFields :array of String;
begin
SetLength(_RecordsetFields, nRecordsetCount);

for i := 0 to Length(_RecordsetFields) - 1 do
begin
_RecordsetFields := 'Элемент ' + IntToStr(i);
end;

p_RecordsetFields := @_RecordsetFields;
//Здесь пытаюсь действовать так:
ShowMessage(p_RecordsetFields^);
//Получается имя массива не является указателем на первый элемент массива?
p_RecordsetFields := @_RecordsetFields[0];
//Теперь все нормально:
ShowMessage(p_RecordsetFields^);
end;

А как обратиться к элементу _RecordsetFields[1]?
В Си достаточно инкрементировать указатель. Например:
p_RecordsetFields++;
Теперь получаем следующий элемент массива.
Пробую так:
p_RecordsetFields := p_RecordsetFields + 1;
Ошибка...
Как это делается в Delphi?
5
07 января 2006 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by dominator
Здравствуйте!
Подскажите, пожалуйста, как мне получить доступ к следующему элементу массива, используя указатель на первый элемент массива?
Ситуация в упрощенном виде примерно такая:

procedure Execute();
var
i :Integer;
p_RecordsetFields :^String;
_RecordsetFields :array of String;
begin
SetLength(_RecordsetFields, nRecordsetCount);

for i := 0 to Length(_RecordsetFields) - 1 do
begin
_RecordsetFields := 'Элемент ' + IntToStr(i);
end;

p_RecordsetFields := @_RecordsetFields;
//Здесь пытаюсь действовать так:
ShowMessage(p_RecordsetFields^);
//Получается имя массива не является указателем на первый элемент массива?
p_RecordsetFields := @_RecordsetFields[0];
//Теперь все нормально:
ShowMessage(p_RecordsetFields^);
end;

А как обратиться к элементу _RecordsetFields[1]?
В Си достаточно инкрементировать указатель. Например:
p_RecordsetFields++;
Теперь получаем следующий элемент массива.
Пробую так:
p_RecordsetFields := p_RecordsetFields + 1;
Ошибка...
Как это делается в Delphi?


1) Для начала нужно понимать, как реализуются динамические массивы в делфи. Переменная типа динамического массива уже по своей сути является указателем на ПЕРВЫЙ элемент массива. Если ты пишешь p_A:=@A где A - это динамический массив, то ты получаешь указатель на указатель. Лучше получать арес таким вот макаром: p_A:=@A[index]; - в этом случае никаких проблем не будет.
2) если указатель типизированный, то можно для него использовать оператор inc() или dec().

Но зачем тебе указатели? Всегда можно обойтись индексами. К томуже указатель на string в Делфи - это не самый хороший тон программирования.

375
08 января 2006 года
dominator
199 / / 16.10.2003
Цитата:
Originally posted by hardcase
1) Для начала нужно понимать, как реализуются динамические массивы в делфи. Переменная типа динамического массива уже по своей сути является указателем на ПЕРВЫЙ элемент массива. Если ты пишешь p_A:=@A где A - это динамический массив, то ты получаешь указатель на указатель. Лучше получать арес таким вот макаром: p_A:=@A[index]; - в этом случае никаких проблем не будет.
2) если указатель типизированный, то можно для него использовать оператор inc() или dec().

Но зачем тебе указатели? Всегда можно обойтись индексами. К томуже указатель на string в Делфи - это не самый хороший тон программирования.



Спасибо за ответ!

Цитата:
Но зачем тебе указатели? Всегда можно обойтись индексами.


Может быть и можно... Вообще ситуация вот какая.
Есть необходимость выполнять последовательность запросов к базе данных. Причем не всегда известно, сколько записей будет возвращено.
Построено следующим образом:
В процедуре формируется запрос и передается в функцию, где этот запрос исполняется. Получается набор записей. Количество полей будет текущим количеством элементов данного массива. Теперь значение каждого поля присваивается соответствующему элементу массива. Далее, я хочу вернуть из этой функции указатель на первый элемент массива и уже потом считывать значения его элементов инкрементируя указатель вплоть до последнего элемента.
И далее для следующего запроса.
Может можно проще как-то?

Цитата:
если указатель типизированный, то можно для него использовать оператор inc() или dec().


Не знал, попробую.

5
08 января 2006 года
hardcase
4.5K / / 09.08.2005
Цитата:
Originally posted by dominator
Далее, я хочу вернуть из этой функции указатель на первый элемент массива и уже потом считывать значения его элементов инкрементируя указатель вплоть до последнего элемента.
И далее для следующего запроса.
Может можно проще как-то?


В делфи реализация дин. массивов очень интереснна: она использует СЧЁТЧИК ССЫЛОК на динамический массив. Т.е. ты можешь возвращать из функции сам массив, не заботясь о возврате ресурсов - система сама уничтожит массив, когда ссылки на на пропадут.
Т.е. если A - динамисесий массив, то A:=nil - убивает ссылку на массив. А когда ты возвращаешь указатель на элемент массива - это не является ссылкой на массив, и есть возможность получить кучу проблем тиа AccessViolation.

Кстати получить количество ссылок можно следующмим образом:

 
Код:
Count:=PInteger( cardinal( pointerer( A ) ) - 8 ) ^;

а количество элементов (то что делает Length):
 
Код:
Len:=PInteger( cardinal( pointerer( A ) ) - 4 ) ^;


Вопрос по базам данных: а разве нельзя использовать стандартые классы TDataSet или ему подобные?
375
09 января 2006 года
dominator
199 / / 16.10.2003
Большое спасибо. Вроде разобрался, реализовал:)
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог