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

Ваш аккаунт

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

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

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

Указатели в Паскале

311
30 января 2016 года
plastictown
309 / / 08.01.2006
Здравствуйте, господа форумчане! Мой вопрос почему-то удалили, но я спрошу еще раз.
Если:
я создаю запись
 
Код:
type some_type=record
    x:integer;
    y:integer;
и тип указателя на запись
 
Код:
type Psome_type=^some_type;
некоторую переменную
 
Код:
var arr:Psome_type;
      i:integer;
И создаю массив
 
Код:
GetMem(arr, 10*sizeof(some_type));
Как мне получить значение, находящееся по адресу arr[ i ] в Turbo Pascal 7.0, кроме способа с инкрементом указателя до места назначения? Неужели в Паскале нет адекватного способа работы с адресами? Мне никто не может ответить на этот вопрос уже месяц.
Всем заранее спасибо!
10
04 февраля 2016 года
Freeman
3.2K / / 06.03.2004
Цитата:
Как мне получить значение, находящееся по адресу arr[ i ] в Turbo Pascal 7.0, кроме способа с инкрементом указателя до места назначения? Неужели в Паскале нет адекватного способа работы с адресами?

Инкремент до места назначения -- и есть адекватный способ работы с указателями в TP, если включен расширенный синтаксис флагом {$X+} или в настройках компиляции.

 
Код:
type
  Psome_type=^some_type; { ваше определение }
var
  ArrayItem: Psome_type;
begin
  Inc(ArrayItem, 5); { передвигает указатель вперед на 5 some_type-ов }
end;
TP под рукой нет, сам проверить не могу. Расширенный синтаксис появился в TP 6.0.
8
30 января 2016 года
mfender
3.5K / / 15.06.2005
Одного не понял: почему структуру Psome_type* arr ты в данном случае считаешь массивом? Это должен быть как минимум array of Psome_type
311
31 января 2016 года
plastictown
309 / / 08.01.2006
Цитата: mfender
Одного не понял: почему структуру Psome_type* arr ты в данном случае считаешь массивом? Это должен быть как минимум array of Psome_type

Я примерно так себе это представляю:

Код:
//type arr=record...
typedef struct{
    int x;
    int y;
} arr;

//----------------//

    //GetMem()
    arr* pArr=(arr*)malloc(10*sizeof(arr));

    //Этого мне не хватает. Хотя бы одного из вариантов.
    (pArr+3)->x=5;
    int xx=(*(arr*)(pArr+3)).x;
Я в данном случае воспринимаю указатель как адрес массива, состоящего хотя бы из одной записи (а может и вовсе без них, т.к. в программе массив будет многократно пересоздаваться). В FreePascal работают варианты и с адресной арифметикой и с индесом arr. А в турбе как-то нет, а это принципиально.
327
02 февраля 2016 года
UserNet2008
748 / / 03.04.2010
Говорите Turbo Pascal 7.0 1992 года
 
Код:
GetMem(arr, 10*sizeof(some_type));
В TP 7.0 функция SizeOf - определяет размер памяти, которую занимает переменная
Не знаю для чего умножать на 10?
Выделить память
 
Код:
GetMem(@arr, sizeof(some_type));
Цитата:
Как мне получить значение, находящееся по адресу arr[ i ] в Turbo Pascal 7.0

Адрес в памяти можно узнать с помощи оператора @ or функция Addr.

 
Код:
Var P: POINTER;
P :=@arr;
Вы получите два hex слова BA:BS. BA-сегментный адрес,BS-смещение.
p/s типа от маски
Всё выше сказанное относится к Turbo Pascal 7.0 1992 года.
311
02 февраля 2016 года
plastictown
309 / / 08.01.2006
Цитата: UserNet2008

Не знаю для чего умножать на 10?
Адрес в памяти можно узнать с помощи оператора @ or функция Addr.

Умножать на десять затем, что это массив элементов типа some_type, причем в недрах программы это будет не константа.
Как получить адрес я знаю. Я не знаю, как получить адрес i-го элемента либо сам его, то бишь arr[ i ] либо (arr+i)^.
Либо я чего-то не понимаю. Может быть эти массивы делаются еще как-то, чтобы с ними по-людски работать, хотя обидно, если так, потому что я уже реализовал все боксингом/анбоксингом того времени как Вы и написали через pointer.

20K
02 февраля 2016 года
ellor!
198 / / 24.05.2012
По-людски с массивами работают так:
Код:
var
  arr     : array of some_type;         {динамический массив записей}
  arr10   : array [0..9] of some_type;  {статический массив записей}
  arr_p   : array of Psome_type;        {динамический массив указателей на записи}
  arr10_p : array [0..9] of Psome_type; {статический массив указателей на записи}
  i       : Integer;
begin
  SetLength(arr, 10);
  for i := 0 to Length(arr) - 1  do
  begin
    arr[i].x := i;
    arr[i].y := i;
  end;
  for i := Low(arr10) to High(arr10)  do
  begin
    arr10[i].x := i;
    arr10[i].y := i;
  end;
end;
311
03 февраля 2016 года
plastictown
309 / / 08.01.2006
Цитата: ellor!

arr : array of some_type; {динамический массив записей}
[/code]

Это не работает в TP 7.0

20K
03 февраля 2016 года
ellor!
198 / / 24.05.2012
Ну тогда либо так:
Код:
type
  TDynArr = array [1..$FFFF div SizeOf(some_type)] of some_type;
  PDynArr = ^TDynArr;
var
  myarr : PDynArr;
  i, Count, Size : Integer;
begin
  Count := 10;
  Size  := SizeOf(some_type) * Count;
  GetMem(myarr, Size);
  for i := 1 to Count do
  begin
    myarr^[i].x := i;
    myarr^[i].y := -i;
  end;
  FreeMem(myarr, Size);
 end;
Либо так:
Код:
{$R-}  {отключение проверки диапазона}
type
  TDynArr = array [1..1] of some_type;
  PDynArr = ^TDynArr;
var
  myarr : PDynArr;
  i, Count, Size : Integer;
begin
  Count := 10;
  Size  := SizeOf(some_type) * Count;
  GetMem(myarr, Size);
  for i := 1 to Count do
  begin
    myarr^[i].x := i;
    myarr^[i].y := -i;
  end;
  FreeMem(myarr, Size);
end;
311
03 февраля 2016 года
plastictown
309 / / 08.01.2006
Я не знаю как это относится к теме, но я знаю, что такое указатель и что с ним можно делать. У меня одна проблема - я никогда не использовал их в Паскале, отчего испытываю непонимание, почему то, что по логике вещей должно работать, не работает. И если у меня типизированный указатель, почему он не может указывать на массив объектов?
311
05 февраля 2016 года
plastictown
309 / / 08.01.2006
Цитата: Freeman

Инкремент до места назначения -- и есть адекватный способ работы с указателями в TP, если включен расширенный синтаксис флагом {$X+} или в настройках компиляции.

{$X+} не включал, и так все работает. Мне на RSDN тоже сказали что-то в этом духе, я не поверил. Раньше догадывался, теперь точно знаю - говененький язык этот Паскаль:)
Спасибо за помощь!

327
06 февраля 2016 года
UserNet2008
748 / / 03.04.2010
Не очень ясен ответ про{$X+}. Т.к {$X+} это есть работа с функциями и т.п.
И зачем это делать:
 
Код:
Inc(ArrayItem, 5); { передвигает указатель вперед на 5 some_type-ов }
оператор @ or функция Addr и так показывает сегментный адрес и смещение.

Если проследить хронологию Ваших вопроса и ответов, то не очень ясно, что Вам нужно:
Что Вам нужно получить адрес массива or массива объектов?
Цитата:
как получить адрес i-го элемента либо сам его, то бишь arr[ i ] либо (arr+i)^.

 
Код:
Var P: POINTER;
P :=@arr[i];
{Вы получите два hex слова BA:BS. BA-сегментный адрес,BS-смещение.}
{~567:~096 не помню может быть знак $ | $567:$096}
Цитата:
почему он не может указывать на массив объектов?

Объект в TP 7.0 это типа Класса. Можно порождать, а вот создать массив объектов не знаю.

Цитата:
говененький язык этот Паскаль

Да и мы через 25 годов то будем говененьки, если будем.

p/s Вы лучше показали массив в реальном коде, а не бестолковые куски кода.
Ну решено так решено.

311
06 февраля 2016 года
plastictown
309 / / 08.01.2006
• Я когда спрашивал первый раз и привел пример кода чуть побольше, тов. модератор мой вопрос удалил нах@р, за что ему огромное спасибо!
• Вы знаете, я к C# так же отношусь примерно. Читаешь книжку про C#, потом про Java. И дежавю постоянно. Единственное, что радует, так это WFP. Так что не думаю, что в возрасте дело. Просто строгая типизация и корявая работа с динамической памятью, хотя во Free Pascal все работает вполне удобно.
• Получать указатель на элемент через нетипизированный указатель я, насколько я понимаю, должен буду путем калькуляций при каждом обращении к массиву, а у меня предполагаются тысячи и тысячи итераций в программе, и злой препод скажет мне "а какого это черта ты сюда написал калькуляции? иди переделывай!", хотя сам он на мой вопрос не ответил:)
• Адрес массива мне не нужен, ибо указатель суть адрес. Мне нужен(был) i-й элемент без лишних действий. Как в Си. Выделил память и обращаешься по индексу.
• Я счел вопрос решенным. т.к. реализовал все через инкремент, хотя и выглядит это коряво.
Всем спасибо!
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог