Lazarus

Other Languages => Russian => Topic started by: devisa_san on August 12, 2019, 11:51:37 am

Title: Неправильно исполняется код
Post by: devisa_san on August 12, 2019, 11:51:37 am
Добрый день!
Ситуация следующая - имеется вот такой простейший код, где мы вводим значение переменных и вводим операцию, необходимую для выполнения над переменными. Lazarus при компиляции выдаёт какую то дичь - уже на стадии ввода операции он выводит сообщение, которое должно выводиться при невыполнении всех условий. Код рабочий, проверен в мобильном Pascal N-IDE  и там всё работает как надо. Вопрос - что происходит и как сделать так, чтобы код работал? Пробовал версии лазаруса 2.0.4 и 1.8.4. Лазарусы из коробки, никаких настроек не было произведено. Скрин с окном выполнения прикладываю.
P.S. Такое поведение лазаруса вызывает шок - это очень мягко говоря.   :o 

program Project1;
var a,b:double;
    c:string;
begin
write ('a=');
read (a);
write ('b=');
read (b);
write ('Enter operation (+ - * /) : ');
read (c);

if c='+' then write (a+b) else
 if c='-' then write (a-b) else
  if c='*' then write (a*b) else
   if c='/' then write (a/b) else write ('Wrong');
readln;
readln;
readln;
end.
Title: Re: Неправильно исполняется код
Post by: julkas on August 12, 2019, 11:59:30 am
Try following -
Code: Pascal  [Select]
  1. write ('a=');
  2. readln (a);
  3. write ('b=');
  4. readln (b);
  5. write ('Enter operation (+ - * /) : ');
  6. readln (c);
  7.  
Замени read() на readln()
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 12, 2019, 01:36:39 pm
Спасибо за быстрый ответ. Работает как задумано, благодарю. Но тогда почему код работал в Pascal N-IDE?
Title: Re: Неправильно исполняется код
Post by: julkas on August 12, 2019, 01:41:33 pm
Спасибо за быстрый ответ. Работает как задумано, благодарю. Но тогда почему код работал в Pascal N-IDE?
Это для меня тоже загадка. Надо опробовать N-IDE. Давно хотел ...
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 12, 2019, 03:07:32 pm
Ну, и соответственно вопрос почему с Read не работает в Lazarus? Комп в любом случае должен дождаться ввода переменной c, а он этого не делает... Хотелось бы разобраться, а то такое поведение для меня показалось странным. Да, и вообще не первый раз в lazarus наблюдаю такое явление, когда порядок выполнения программы нарушен, но там это было зачастую в программах с графическим интерфейсом и сложной структурой, но тут то простейшая программа с несколькими IF - школьнику паскаль объяснял и тут такое западло вылезло.
Title: Re: Неправильно исполняется код
Post by: julkas on August 12, 2019, 03:25:29 pm
Я думаю, что если начнешь решать online задачки (если уже не начал), тебе будет легче.
Ты из России? Я так понял там популярен PascalABC. Это правда?
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 12, 2019, 03:35:54 pm
Так мне не надо online задачки решать. Я в pascal-delphi-lazarus программирую с 2002 года, я школьнику преподаю и вот такое поведение lazarus для меня оказалось неожиданным. Хотелось бы причину понять. Независимо от того, что использовать read или readln в данном коде, программа себя не должна была вести так, как вела. Я из России. PascalABC использовать не хочу, так как планирую школьника обучать в том числе и программированию приложений с GUI. Повторюсь - мне причину понять интересно, так как код так работать не должен был и другая среда разработки это подтверждает.
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 12, 2019, 05:10:43 pm
Я в pascal-delphi-lazarus программирую с 2002 года, я школьнику преподаю и вот такое поведение lazarus для меня оказалось неожиданным. Хотелось бы причину понять.
тонкости реализации read.

вот такой код:
Code: Pascal  [Select]
  1. program project1;
  2.  
  3. uses
  4.   SysUtils, Classes;
  5.  
  6. var
  7.   a,b: double;
  8.   c:  string;
  9. begin
  10.   try
  11.     read(a);
  12.     read(b);
  13.     read(c);
  14.     writeln(c);
  15.     writeln(byte(c[1]));
  16.     readln;
  17.   except
  18.     on e: exception do
  19.       writeln(e.message);
  20.   end;
  21. end.
  22.  
падает с AccessViolation.

ВНИМАНИЕ! в Delphi 10.3 он точно так же падает с Access Violation!

upd а падает он с AccessViolation потому что я сам дурак.
в данном примере Read(c) возвращает пустую строку. Причём оставшиеся в символы переноса, пудут прочитаны в следующем readln();
а тк я без проверки обращаюсь к c[1] - происходит тот самый AccessViolation

Независимо от того, что использовать read или readln в данном коде, программа себя не должна была вести так, как вела.
это вопрос к реализации процедуры read().
догадываюсь, что read просто пытается прочитать всё, с командной строки (игнорируя знак переноса), и в итоге, читает не то и ни туда.
по-этому использовать readln() безопаснее.
(а ещё раньше read умел читать в PChar, но функционал запретили)

... и другая среда разработки это подтверждает.
не думаю, что N-IDE будет авторитетом для FPC.
Т.к. N-IDE это интерпретатор, и у него вполне могут быть свои особенности.
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 12, 2019, 05:27:18 pm
проблема в следующем:
Read() не очищает символы переноса строки в INPUT буфере.

по-этому каждый следующий read() вынужден сам разбираться с ними.

когда ты делаешь read(a) (или read(b)) где "a" и "b" double; то FPC игнорирует пустые строки, и продолжает ожидать ввод числа. (ты можешь это проверить сам. просто запусти программу, не вводя число, нажми "enter". Программа не будет падать, и будет настойчиво продолжать ввода числа).

НО, read(c) рабоатет подругому. Увидев символ конца строки (который остался ещё от ввода числа "b"), он код принимает решение о том, что ввели пустую строку, и тут же её возвращает.

В твоём коде, это приводит к выводу "Wrong" (потому пустая строка, не являеится символом операции).

т.е. нужно использовать именно ReadLn(), чтобы после прочтения значения, символы переноста строки подчищались;
Очевидно, что в N-IDE такими вещами не заморачивались. (надо думать, что у них своя обработка "командной строки", где нет симоволов переноса строк)

FPC работает правильно.
Title: Re: Неправильно исполняется код
Post by: julkas on August 12, 2019, 05:38:20 pm
Quote
(а ещё раньше read умел читать в PChar, но функционал запретили)
@skalogryz   Причина известна?
Я вообще новичок в FPC и просто исходил из опыта чтения входных данных на разных онлайн ...
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 12, 2019, 05:45:18 pm
Quote
(а ещё раньше read умел читать в PChar, но функционал запретили)
@skalogryz   Причина известна?
конечно. у PChar невозможно проверить границы памяти

https://www.freepascal.org/docs-html/current/rtl/system/read.html
Quote
In earlier versions of FPC, it was also allowed to read Pchar null-terminated strings, but this has been removed, since there is no buffer checking possible.
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 12, 2019, 07:10:45 pm
проблема в следующем:
Read() не очищает символы переноса строки в INPUT буфере.

по-этому каждый следующий read() вынужден сам разбираться с ними.

когда ты делаешь read(a) (или read(b)) где "a" и "b" double; то FPC игнорирует пустые строки, и продолжает ожидать ввод числа. (ты можешь это проверить сам. просто запусти программу, не вводя число, нажми "enter". Программа не будет падать, и будет настойчиво продолжать ввода числа).

НО, read(c) рабоатет подругому. Увидев символ конца строки (который остался ещё от ввода числа "b"), он код принимает решение о том, что ввели пустую строку, и тут же её возвращает.

В твоём коде, это приводит к выводу "Wrong" (потому пустая строка, не являеится символом операции).

т.е. нужно использовать именно ReadLn(), чтобы после прочтения значения, символы переноста строки подчищались;
Очевидно, что в N-IDE такими вещами не заморачивались. (надо думать, что у них своя обработка "командной строки", где нет симоволов переноса строк)

FPC работает правильно.

Благодарю за развёрнутый ответ! Теперь всё на свои места встало. Но тогда у меня ещё один вопрос, а зачем Read() реализован так? Это же вот такие странные ситуации вызывает и, получается, делает невозможным ввод строк при помощи этого оператора.
Например в нижеприведённом коде мы сможем ввести только одну строку a. b окажется пустой.

program Project1;
var a,b:string;
begin
  read(a);
  read(b);
  writeln(a);
  writeln(b);
  readln;
  readln;
end.
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 12, 2019, 07:49:03 pm
Благодарю за развёрнутый ответ! Теперь всё на свои места встало. Но тогда у меня ещё один вопрос, а зачем Read() реализован так? Это же вот такие странные ситуации вызывает и, получается, делает невозможным ввод строк при помощи этого оператора.
потому что Read() и Readln() был сделан для чтения текстовых файлов (где символы переноса строки имеют свой смысл).
Консоль в данном случае рассматривается только как частный случай файлов.

Если использовать read() для консоли, то правильнее исползовать именно readln(), а не read().
Потому что readln() обрабатывает входную строку целиком.

Можно добавить, что именно N-IDE работает неправильно ;)

а зачем в коде:
Code: Pascal  [Select]
  1. readln;
  2. readln;
  3. readln;
????
почему их именно 3?
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 03:38:02 pm

а зачем в коде:
Code: Pascal  [Select]
  1. readln;
  2. readln;
  3. readln;
????
почему их именно 3?

Если оставить хотя бы два readln, то в исходной версии кода программа сразу по нажатии на enter на этапе ввода операции завершиться.

В исправленном коде с read заменёнными на readln хватает и одного readln, чтобы она не завершалась сразу по вводу операции.

Но вообще помимо вопроса по данному конкретному примеру у меня есть вопросы по другим случаям. Возможно ли их тут озвучить или надо новые темы создавать?  В общем то они все связаны с тем, что код выполняется не так как ожидалось.

Один всё таки озвучу. Например буквально на днях в проекте создавал класс который включал в себя массив записей. В записях планировал создать два поля типа boolean, последовательность действий была такая - сначала описал только одно поле с данным типом, проверил - всё работало, как только добавил второе поле с таким же типом, программа работать перестала. Убирал второе поле - работало, добавлял - переставало. Сам код не сохранился, так как я решил по другому действовать, а вот пример объявления остался (соответственно в полях StatData были объявлены поля типа boolean):

type StatData = record
     date:TDateTime;
     input:integer;
     output:integer;
     end;

type TStatistic = class
     SData:array of StatData;
     procedure StatDataFloat(firstdate,lastdate:TDateTime;Method:integer;UseCol:boolean);
     procedure StatDataToStringGrid(var StringGrid:TstringGrid);
     procedure StringGridAutoSize(Var StringGrid:TstringGrid);
     procedure StatDataToTabel(var tab:TTabel);
     procedure FinanceStatistic(firstdate,lastdate:TDateTime;Method:integer;UseCol:boolean);
end; 
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 14, 2019, 03:49:02 pm
Возможно ли их тут озвучить или надо новые темы создавать? 
конечно, можно здесь...

Один всё таки озвучу. Например буквально на днях в проекте создавал класс который включал в себя массив записей. В записях планировал создать два поля типа boolean, последовательность действий была такая - сначала описал только одно поле с данным типом, проверил - всё работало, как только добавил второе поле с таким же типом, программа работать перестала. Убирал второе поле - работало, добавлял - переставало.  Сам код не сохранился...
я бы предложил реализовать проект ещё раз, и проверить воспроизведётся ошибка или нет.
Без кода, разговор получится на пустом месте.

но я уже вижу тревожные звоночки в виде:
Code: Pascal  [Select]
  1.      procedure StatDataToStringGrid(var StringGrid:TstringGrid);
  2.      procedure StringGridAutoSize(Var StringGrid:TstringGrid);
  3.      procedure StatDataToTabel(var tab:TTabel);
а именно - тревожит наличие "var". Причём, я не думаю, что ошибка была в исползовании "var". Просто само его использование в данным случае излишне. "var" для класса имеет несколько иное значение, чем "var" для record-а.
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 04:59:43 pm
Один всё таки озвучу. Например буквально на днях в проекте создавал класс который включал в себя массив записей. В записях планировал создать два поля типа boolean, последовательность действий была такая - сначала описал только одно поле с данным типом, проверил - всё работало, как только добавил второе поле с таким же типом, программа работать перестала. Убирал второе поле - работало, добавлял - переставало.  Сам код не сохранился...
я бы предложил реализовать проект ещё раз, и проверить воспроизведётся ошибка или нет.
Без кода, разговор получится на пустом месте.

но я уже вижу тревожные звоночки в виде:
Code: Pascal  [Select]
  1.      procedure StatDataToStringGrid(var StringGrid:TstringGrid);
  2.      procedure StringGridAutoSize(Var StringGrid:TstringGrid);
  3.      procedure StatDataToTabel(var tab:TTabel);
а именно - тревожит наличие "var". Причём, я не думаю, что ошибка была в исползовании "var". Просто само его использование в данным случае излишне. "var" для класса имеет несколько иное значение, чем "var" для record-а.


Понимаю, что без кода разговор скорее всего будет ни о чём. Попробую на днях восстановить то, что было.

По поводу var - хотелось бы знать отличие. В данном случае поставил var, чтобы процедура работала непосредственно с данными классами не создавая копию. Без них код не работал - данные из процедур не передавались далее. Кстати, процедура procedure StatDataToTabel(var tab:TTabel); у меня так и не заработала как надо. Почему опять таки я не понял.

Код её следующий:
procedure TStatistic.StatDataToTabel(var tab:TTabel); //не работает
var i:integer;
    tempTab:TTabel;
    new:TRow;
 begin
   tempTab:=TTabel.Create;
   new:=TRow.Create;
   SetLength(new.Cells,3);
   SetLength(tempTab.Rows,length(SData)+1);
   new.Cells[0]:=systoutf8('Дата');
   new.Cells[1]:=systoutf8('Приход');
   new.Cells[2]:=systoutf8('Уход');
   tempTab.AddRow(new);
   tempTab.Rows[0]:=new;
  // showmessage(tempTab.Rows[0].RowToUTF8String);
   for i:=1 to length(SData)+1 do
    begin
     //showmessage(tempTab.Rows[0].RowToUTF8String);
     new.Cells[0]:=DateToStr(SData.date,FormatSettings);
     new.Cells[1]:=IntToStr(SData.input);
     new.Cells[2]:=IntToStr(SData.output);
     tempTab.Rows:=new;   //tempTab.AddRow(new);
    // showmessage(tempRow.RowToUTF8String);
    end;
   tab:=temptab;
 end;

Коротко о том, что происходит - класс TTabel - это класс таблиц мною созданный. В TTabel имеется массив TRow, который является строками в таблицах, в TRow имеются массивы Cells. Т.е. для создания таблицы 3x3 мы задаем количество ячеек Cells в TRow равное 3-м и добавляем три таких Row в TTabel. Сам класс TTabel уже использовал в проекте и всё работало достаточно долго (проект начал в 2017).
Эта процедура должна записать данные из SData (Массив записей с полями текущей даты, прихода и ухода. Даты в массиве идут последовательно по дням например 01.01.2019, 02.01.2019 и т.д.) в таблицу Tab. По результату получается, что вся таблица Tab заполнена данными только за одну дату - последнюю. В классе TTabel есть процедура Add для добавления строк, изначально использовал её, по вышеозвученному результату предположил, что дело в ней (хотя в других случаях она всегда работала) и реализовал добавление строк к таблицу так как написано в коде выше. Но результат оказался идентичным. В комментариях стоят showmessage - таким образом следил за тем, что происхоидит - одно могу сказать точно - SData заполнен нужными данными и вопрос тут в том, как они записываются в TTabel.
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 14, 2019, 05:22:41 pm
По поводу var - хотелось бы знать отличие. В данном случае поставил var, чтобы процедура работала непосредственно с данными классами не создавая копию. Без них код не работал - данные из процедур не передавались далее. Кстати, процедура procedure StatDataToTabel(var tab:TTabel); у меня так и не заработала как надо. Почему опять таки я не понял.
Тип класс-а в Object Pascal-е (и FPC и Delphi) всегда ссылочный.
"var" для переменной класса, означает, что ссылка может быть изменена.
При наличии var, или без него, копии данных создаваться не будет (опять же потому что передаётся ссылка на объект класса)

В большинстве случаев нужды в var нет. Кроме тех случаев, когда нужно создать объект класса (или, реже, поменять ссылку на объект класса).

По результату получается, что вся таблица Tab заполнена данными только за одну дату - последнюю
согласно приведённом коду, именно так и должно работать.
Т.к. строки в таблицу не добавляются, а добавляется всего одна строка всего один раз.

После чего один ряд перезаписывается N раз (где N соответствует количеству дат - 1); И в единственно добавленный ряд попадает последняя запись из SDate
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 05:41:30 pm

Тип класс-а в Object Pascal-е (и FPC и Delphi) всегда ссылочный.
"var" для переменной класса, означает, что ссылка может быть изменена.
При наличии var, или без него, копии данных создаваться не будет (опять же потому что передаётся ссылка на объект класса)

В большинстве случаев нужды в var нет. Кроме тех случаев, когда нужно создать объект класса (или, реже, поменять ссылку на объект класса).

Тогда непонятно почему данные не передавались без var...

По результату получается, что вся таблица Tab заполнена данными только за одну дату - последнюю
согласно приведённом коду, именно так и должно работать.
Т.к. строки в таблицу не добавляются, а добавляется всего одна строка всего один раз.

После чего один ряд перезаписывается N раз (где N соответствует количеству дат - 1); И в единственно добавленный ряд попадает последняя запись из SDate

Странно, почему-то код как-то криво скопировался. Мы присваиваем в цикле и присваивается не одни и те же данные, а разные. Берутся из массива SData по индексу i. Индекс меняется, соответсвенно и данные должны записываться разные.

procedure TStatistic.StatDataToTabel(var tab:TTabel); //не работает
var i:integer;
    tempTab:TTabel;
    new:TRow;
 begin
   tempTab:=TTabel.Create;
   new:=TRow.Create;
   SetLength(new.Cells,3);
   SetLength(tempTab.Rows,length(SData)+1);
   new.Cells[0]:=systoutf8('Дата');
   new.Cells[1]:=systoutf8('Приход');
   new.Cells[2]:=systoutf8('Уход');
   tempTab.AddRow(new);
   tempTab.Rows[0]:=new;
  // showmessage(tempTab.Rows[0].RowToUTF8String);
   for i:=1 to length(SData)+1 do
    begin
     //showmessage(tempTab.Rows[0].RowToUTF8String);
     new.Cells[0]:=DateToStr(SData.date,FormatSettings);
     new.Cells[1]:=IntToStr(SData.input);
     new.Cells[2]:=IntToStr(SData.output);
     tempTab.Rows:=new;   //tempTab.AddRow(new);
    // showmessage(tempRow.RowToUTF8String);
    end;
   tab:=temptab;
 end;
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 05:42:50 pm
Не хочет код правильно постить. В общем в цикле после SData идут квадратные скобки и индекс i внутри  них. SData - это массив записей.

Похоже, что здесь такой набор символов воспринимается как тег и весь последующий текст становится курсивом
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 14, 2019, 05:44:52 pm
правильно постить код, можно при помощи тэга:
Code: [Select]
[code=pascal]
  writeln('hello world');
[ /code]
(пробел в закрывающем тэге между "[" и "/code]" нужно убрать. здесь он для примера)

результат:
Code: Pascal  [Select]
  1.   writeln('hello world');

https://wiki.freepascal.org/Forum#Use_code_tags

В общем в цикле после SData идут квадратные скобки и индекс i внутри  них. SData - это массив записей.
это всё хорошо, но в цикле, в котором ты проходишь SData, ты не создаёшь новых рядов для TTabel.
У тебя даже закоментирован код tempTab.AddRow(new);
И он правильный, но только при условии, что "new" будет точно так же оздаваться внутри цикла, а не до него.
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 06:12:13 pm
правильно постить код, можно при помощи тэга:
Code: [Select]
[code=pascal]
  writeln('hello world');
[ /code]
(пробел в закрывающем тэге между "[" и "/code]" нужно убрать. здесь он для примера)

результат:
Code: Pascal  [Select]
  1.   writeln('hello world');

https://wiki.freepascal.org/Forum#Use_code_tags

В общем в цикле после SData идут квадратные скобки и индекс i внутри  них. SData - это массив записей.
это всё хорошо, но в цикле, в котором ты проходишь SData, ты не создаёшь новых рядов для TTabel.
У тебя даже закоментирован код tempTab.AddRow(new);
И он правильный, но только при условии, что "new" будет точно так же оздаваться внутри цикла, а не до него.

Мой косяк. Не тот код всё таки запостил. Там закомментированна строчка - это то, что должно было выполняться и оно не работало. А закомментировал я её просто потому что пробовал разные варианты и в текущем смотрел, что вообще запишется. Т.е. должно работать, если new создавать каждый новый цикл? Но почему? Потому что мы каждый раз при добавлении передаём ссылку на экземпляр класса в TTabel, а если этого не делать, то все записи в TTabel будут ссылками на один и тот же экземпляр и потому результат и получается таким, что таблица состоит только из того, что было в последней строке?
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 14, 2019, 07:01:35 pm
Т.е. должно работать, если new создавать каждый новый цикл?
да
Потому что мы каждый раз при добавлении передаём ссылку на экземпляр класса в TTabel, а если этого не делать, то все записи в TTabel будут ссылками на один и тот же экземпляр и потому результат и получается таким, что таблица состоит только из того, что было в последней строке?
нет. TTabel у тебя один.
у тебя на каждую итерацию нужно создавать новый TRow.
сколько рядов, столько раз TRow нужно создавать.
Code: Pascal  [Select]
  1. procedure TStatistic.StatDataToTabel(var tab:TTabel); //не работает
  2. var i:integer;
  3.     tempTab:TTabel;
  4.     new:TRow;
  5. begin
  6.   tempTab:=TTabel.Create;
  7.   new:=TRow.Create;
  8.   SetLength(new.Cells,3);
  9.   SetLength(tempTab.Rows,length(SData)+1);
  10.   new.Cells[0]:=systoutf8('Дата');
  11.   new.Cells[1]:=systoutf8('Приход');
  12.   new.Cells[2]:=systoutf8('Уход');
  13.   tempTab.AddRow(new);
  14.   tempTab.Rows[0]:=new;
  15.  
  16.   for i:=1 to length(SData)+1 do begin
  17.     new:=TRow.Create;
  18.     SetLength(new.Cells,3);
  19.     new.Cells[0]:=DateToStr(SData[i-1].date,FormatSettings);
  20.     new.Cells[1]:=IntToStr(SData[i-1].input);
  21.     new.Cells[2]:=IntToStr(SData[i-1].output);
  22.     tempTab.Rows[i]:=new;  
  23.   end;
  24.   tab:=temptab;
  25. end;
  26.  
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 08:38:38 pm
нет. TTabel у тебя один.
у тебя на каждую итерацию нужно создавать новый TRow.
сколько рядов, столько раз TRow нужно создавать.

Почему нет? Фишка в том, что в результате получается таблица в которой количество TRow правильное, но эти TRow одинаковые. Что тогда в данном варианте происходит? Получается на каждой итерации я присваиваю значение одному и тому же экземпляру класса, а в TTabel у меня храняться только ссылки на него. И тогда мне становится понятно, почему вся таблица была заполнена теми значениями, что в SData были последние. И тогда действительно всё должно заработать, если создавать в цикле каждый раз новый TRow.
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 14, 2019, 08:46:22 pm
Почему нет?
потому что ранее ты писал про "TTabel":
Потому что мы каждый раз при добавлении передаём ссылку на экземпляр класса в TTabel, а если этого не делать, то все записи в TTabel будут ссылками на один и тот же экземпляр
из контекста понятно, что ты говоришь про TRow.
Но т.к. ты создаёшь и TTabel и TRow тебе следует быть внимательнее.
Title: Re: Неправильно исполняется код
Post by: devisa_san on August 14, 2019, 08:55:18 pm
Почему нет?
потому что ранее ты писал про "TTabel":
Потому что мы каждый раз при добавлении передаём ссылку на экземпляр класса в TTabel, а если этого не делать, то все записи в TTabel будут ссылками на один и тот же экземпляр
из контекста понятно, что ты говоришь про TRow.
Но т.к. ты создаёшь и TTabel и TRow тебе следует быть внимательнее.

Прошу прощения, действительно по невнимательности написал TTabel имея ввиду TRow. В остальном размышления верны?
Title: Re: Неправильно исполняется код
Post by: skalogryz on August 14, 2019, 09:13:08 pm
В остальном размышления верны?
да