Помощь новичкам

b переменная размерного типа и размещается на стеке, уничтожается обычым ассемблерным ret, а не сборщиком мусора.

Статические-переменные типа указатели указывают путь к адресу ячейки памяти динамических переменных. То есть по сути мы добиваемся динамических переменных с помощью статических-переменных указаталей. Возможно или скорее всего, я ошибаюсь. Но ладно. Сам попробую найти решения задачи другими способами. Так что, спасибо всем кто не потруднился написать. Насчет справки - я всегда читаю теорию, потом задаю вопросы. Но иногда выходит, что сколько не читай, трудно осваиваются данные. Либо мало понимания языка, либо сам текст трудно объяснен для “новичков”.

Да, действительно это превосходно! Спасибо. Первый шаг прошел, т.е. запись в ячейках EXCEL программно. Но пока у меня не получается чтение из ячеек EXCEL программно. Попробовал разные варианты, но пока результатов на счет чтения нет. Прилагаю последний файлProgram5.pas (1,1 КБ). Жду Вашей помощи

Да, действительно это превосходно! Спасибо. Первый шаг прошел, т.е. запись в ячейках EXCEL программно. Но пока у меня не получается чтение из ячеек EXCEL программно. Попробовал разные варианты, но пока результатов на счет чтения нет. Прилагаю последний файл Program5.pas (1,1 КБ). Может попробуем дальше и находим этот метод. Заранее благодарю!

Сделать меню с помощью модуля

  1. (Использовать готовый массив)
  2. (Использовать готовый запись)
  3. (Использовать готовый строка)
  4. (Использовать готовую подрограмму)
  5. Выход.
Unit Pr1;
 
interface
 
procedure sortirovka;
procedure zapis;
procedure stroka;
procedure summa;
 
implementation
 
procedure sortirovka;
var a:array [1..100] of integer;
    k,x,i,j,n:integer;
begin
  read(n);
  for i:=1 to n do begin
                      a[i]:=random(-15,25);
                      write(a[i]:4);
                   end;
   for i:=1 to n-1 do 
                      for j:=i+1 to n do
                                        if a[i]>a[j] then begin
                                                            x:=a[i];
                                                            a[i]:=a[j];
                                                            a[j]:=x;
                                                          end;
  for i:=1 to n do if a[i] mod 3=0 then k:=k+1;
  writeln;
  writeln('Количество элементов кратных 3=',k);
  write('По возрастанию ');
  write('Массив А:');
  for i:=1 to n do write(a[i]:5);
  writeln;
end;
 
procedure zapis;
const m: array[1..6] of string=('Сагаан','Демир-оол','Наксыл','Монгуш','Салчак','Донгак');
      pr:array[1..6] of string=('BMW','Audi','Ford','Toyota','Nissan','Mazda');
type mashina=record
  fam:string[10];
  marka:string[15];
  stazh:integer;
  vozrast:integer;
end;
var mn:array[1..2000] of mashina; 
    i,n,k:integer;
begin
  write('Введите количество машин: '); readln(n);
  for i:=1 to n do 
    with mn[i] do
   
      begin 
        fam:=m[1+random(6)];
        marka:=pr[1+random(6)];
        stazh:=random(30);
        vozrast:=random(28);
      end;
  writeln('Данные о машинах');                        
  writeln('-------------------------------------------------------');
  writeln('№ |Фамилия владельца | марка машины | стаж | возраст ');
  writeln('-------------------------------------------------------');
  for i:=1 to n do 
    with mn[i] do
      writeln(mn[i].fam:15, mn[i].marka:12, mn[i].stazh:14, mn[i].vozrast :9);
      writeln('-------------------------------------------------------');
      write;
    for i:=1 to n do if mn[i].stazh>10 then k:=k+1;
    writeln('самый молодой  k=',k);
    inc(k);
    writeln('Стаж>10');
    writeln('-------------------------------------------------------');
    writeln('№ | Фамилия владельца  | марка машины |  стаж  |  возраст ');
    writeln('-------------------------------------------------------'); 
    for i:=1 to n do
      begin
        if mn[i].stazh>10 then writeln(mn[i].fam:10, mn[i].marka:12, mn[i].stazh:14, mn[i].vozrast :16);
      end;
  writeln('-------------------------------------------------------');
end;   
   
procedure stroka;
var s,s1,s2:string;
Begin
write('Данное  слово: ');
    s:='Обществоведение';writeln(s);
write('Первое  слово: ');    
    s1:=(s[1]+s[2]+s[8]+s[11]) ;writeln(s1);
write('Второе  слово: ');   
    s2:=copy(s,1,8); writeln(s2);
End;
 
procedure summa;
var z,s:real;
function F(a,b:real):real; 
begin
 z:=(a+sqrt(b))/(b+sqrt(a));
 F:=z;
end;
begin
writeln('                        11+_/5   13+_/10   _/19+30 '); 
writeln('вычислить выражение F=  ------ + ------- + -------- ');
writeln('                        5+_/11   10+_/13   _/30+19 ');
writeln;
writeln;
s:=F(15,10)+F(11,5)+F(20,6);
writeln;
writeln('     11+_/5    13+_/10    _/19+30 '); 
writeln(' F= -------- + -------- + --------- = ',s:2:2);
writeln('    5+_/11     10+_/13     _/30+19');
end;
 
initialization 
  writeln('Загружен модуль!');        writeln;
finalization
  writeln;
  writeln('Программа завершена. Нажмите любую клавишу!');
  readln;
end.
Uses Pr1;
var k,r:integer;
begin
    while true do begin writeln;
                          writeln('Menu');
                          writeln('1:Массив');
                          writeln('2:Запись');
                          writeln('3:Строка');
                          writeln('4:Подпрограмма');
                          writeln('5:Выход');
                          read(k);
                      case k of
                      1: sortirovka ;
                      2: zapis;   
                      3: stroka;
                      4: summa;
                      5: Exit;
                      end;
                      end;
                      end.

Проверите код на исполняемость?

Мой (достаточно большой) опыт работы с MS Excel из внешней программы (Visual Basic, Visual FoxPro) показывает, что наиболее эффективная работа получается при следующей схеме:

  • в вызывающей программе создается объект Excel.Application;
  • генерируется программа на Excel VBA и вставляется в проект вызванного приложения;
  • программа (макрос) получает управление и выполняется, делая все необходимое;
  • вызывающая программа удаляет макрос из проекта и закрывает рабочую книгу.

На самом деле, MS Excel - это прекрасный пользовательский интерфейс, к тому же, визуальный) для любого универсального алгоязыка, в том числе, для PascalABC.NET. Удобный структурированный ввод данных, прекрасные возможности по оформлению вывода (хоть графики программно рисуй!).

Сейчас пока не получается, а позднее, раз уж вызвать Excel удалось (спасибо @Sun_Serega), попытаюсь разработать класс для полноценной работы с MS Excel.

Помогите пожалуйста, у меня возникает ошибка System.AccessViolationException как необработанное исключение на строчке if sqrt(sqr(Senter.X - CP1.X) + sqr(Senter.Y - CP1.Y) + sqr(Senter.Z - CP1.Z)) < Data^.CrLvls[lvl].LoadDistanse then, хотя до неё всегда вызывается Data^.CrLvls[lvl].LoadDistanse и все исключения в том потоке обрабатываются и записываются в файл Errors.txt. Левая часть неравенства никак не могла вызвать эту ошибку + ошибка начала возникать как раз после того как я покопался в правой части. Вот Исходники(108,4 КБ). Data тут поинтер на запись, CrLvls массив, а LoadDistanse - функция интерфейса. Ошибка возникает в PData, в Sector.Draw на строчке 146. Сборка 1590.

P.S. Такая ошибка возникает на Shift+F9 режиме, в просто F9 будет создавать файл Errors.txt и писать туда что ссылка на объект не указывает на экземпляр объекта, хотя это не может быть так, вся ссылочная часть строчки используется до этого.

Код большой конечно - трудно смотреть. Такие ошибки ищутся долго. Позволю высказать предположение, что тут проблема в совместном использовании управляемой и неуправляемой памяти. Управляемую сборщик мусора передвигает, а неуправляемая (Ваш указатель) продолжает указывать на старое место.

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

А передвигает он её - в смысле сдвигает всю информацию как то так чтоб заполнить освободившийся пробел после удаления чего то? Можете объяснить подробнее? И если я заменю массив на своё подобие массива основанное на указателях это всё исправит? Это конечно костыль но если что лучше держать на будущее такую возможность.

Основной смысл, почему я использовал указатель - доступ к данным о объекте Planet(настройки процедурной генерации) даёт всем объектам Sector. Если использовать функции - это получается криво, по моему, слишком много лишних действий, не такой быстрый доступ, класс имеет удобства как наследование но неэффективно хранит своё содержимое. Ну а если использовать запись без указателя то данные будут копироваться, мне это никак не подходит считая что объектов Sector может быть сотни тысяч на 1 Planet. Вы как я понял предлагаете заменить на класс?

И ещё, это ошибка паскаля, то есть если найти исток то вы исправите?

Это не ошибка Паскаля - это особенности управляемой и неуправляемой памяти.

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

Да, все верно, у меня, как опытного программиста и преподавателя, проблем использование EXCEL с другими языками (VFP, VB, VBA, C++, C#, Дельфи, …) пока нет. Проблема пока с PascalABC.NET, так как многим ученикам и студентам вначале обучаю их этим прекрасным языком программирования. База данных для названных языков у меня разработано много, многие разработанные программы и приложения баз данных пользуются в Банках, школах, …

Есть ли альтернатива этому кошмарику с прерыванием из внутреннего цикла с учетом того, что метки и goto ранее были преданы анафеме?

Суть задачи: найти в случайном целочисленном массиве тройку элементов, дающих в сумме ноль.

begin
  var n:=ReadInteger('n=');
  var a:=ArrRandom(n,-50,50); a.Println;
  var m:=n-1;
  var found:=false;
  for var i:=0 to m do begin
    for var j:=0 to m do
      if i=j then continue
      else begin
        for var k:=0 to m do
          if (k=i) or (k=j) then continue
          else
            if a[i]+a[j]+a[k]=0 then begin
              Println('Решение:',a[i],a[j],a[k]);
              found:=true;
              break
              end;
        if found then break
        end;
    if found then break
    end;
  if not found then Writeln('Нет нужной тройки чисел')
end.

Была мысль поставить Exit после Println, но это не конец программы, далее есть еще чем заняться.

ну, нормальный код, чего тут улучшать. флаговые переменные куда лучше меток. и с ними проще отлаживать код.

Да он какой-то “Си-образный” из-за этих брейков повсюду. И да, не сочтите предыдущий пост желанием вернуть метки )))

А что насчёт занести код нахождения результата в процедуру и выходить из неё через exit?

Спасибо, я пытался так сделать, но это была школьная задача из разряда “процедур еще не проходили”. Времени мало было, написал так, как показано выше. А теперь вот ищу решение покрасивее.

Используйте goto.

Вас обманули. Не мучьтесь и используйте goto. Один вместо трёх breakов

  var found:=false;
  for var i:=0 to m do 
  for var j:=i+1 to m do
  for var k:=i+j+1 to m do
    if a[i]+a[j]+a[k]=0 then 
    begin
      found:=true;
      goto 1
    end;
  1: if not found then Writeln('Нет нужной тройки чисел')

А для тех, кто спит и видит функциональные решения, - как-то так:

  var b := a.Numerate;
  var q := b.Cartesian(b).Cartesian(b).Select(t->(t[0][0],t[0][1],t[1]))
    .Where(t->(t[0][0]<t[1][0]) and (t[1][0]<t[2][0]));
  
  Println(q.Where(t->t[0][1]+t[1][1]+t[2][1]=0).FirstOrDefault);

В последнем решении даже индексы можно понаблюдать :slight_smile:

Если правильно помню - как только появляется ключевое слово Label в разделе описаний - прощаемся с лямбдами (их, правда, не тут, но все же…). А может и еще с чем-то надо прощаться? Но с лямбдами - это мне было в свое время отвечено или Вами, или @ibond

P.S. А функциональное решение - это, как говорится, “п-я-я-я-я-я-ть!”

Тогда можно уже и не выходить из цикла, чтоб все такие числа нашло, всё равно быстрее функционального решения будет работать)).

Почему быстрее? Найдёт First и закончит