PascalABC.NET версия 3.6

А тогда чье это “требование” - Ваше?

И это, на мой непросвещенный взгляд, совершенно правильно. Инициализация в программе должна быть! Хотя бы потому, что информатика должна учить умению писать программы, а не умению писать их на конкретном языке с его особенностями. Поэтому для динамических массивов можно использовать ArrFill, а статические - извольте инициализировать вручную. Статические массивы - архиаим и рудимент и незачем пытаться городить в языке новые средства для того, чтобы кто-то когда-то для лишь ему известных целей мог немножко поудобнее с ними работать. Чужеродны такие массивы для современных языков.

Так, если не важно, то, может, стоит попробовать динамические? Они, во всяком случае, обладают большей гибкостью. Но, если интересно, как работать со статическими - можете заглянуть ещё и сюда. Если нужна инициализация - можете объявить тип массива в type и написать функцию его заполнения каким-то значением. Синтаксиса, который предоставили Вы, на моей памяти не обсуждалось здесь для статических массивов. Но, почему бы, в принципе и не реализовать? Не мне решать, а разработчикам, но, на мой взгляд, идея хорошая, но, конечно, относительно тех же ошибок компилятора ниже по приоритету для создателей PascalABC.NET.

Речь о краткости. На ЕГЭ всё еще на листочке код пишут. Надеюсь последний год. Я сам на C# пишу и прекрасно понимаю, как можно проинициализировать массив разными способами. Хотелось бы именно синтаксический сахар.

Еще раз: статические массивы в языке - только для совместимости. Очень надеюсь, что пройдет немного времени - и их вместе со статическими строками вообще уберут из языка. Потому что только лишний груз. Повторюсь: не нужны они для ЕГЭ, зачем вообще вести про них речь?

Вам нужна процедура ЗанулитьСтатическийМассив(var ИмяМассива: ТипМассива; НижняяГраница, ВерхняяГраница: integer) ? Ну напишите!

Для статических массивов это сделать затруднительно - они устаревшие, и для них в PascalABC.NET очень мало средств. Наша рекомендация - использовать динамические массивы.

Вот как написать то, что вы хотите:

var a := Arr(0) * 10;

или

var a := ArrFill(10,0);

А в чём проблема использовать это в ЕГЭ?

Да нет никакой проблемы, обычная хотелка без обоснования. Реализовать которую - биться в стену. Надо иметь объявление типа для статического массива, чтобы передать его в процедуру инициализации. А в ней не иметь возможности проверить соответствие заданных в процедуре границ индексов описанным в типе.

Хотелки - это нормально.

Для статических придётся писать как-то так:

var a: array[1..10] of integer := (0,0,0,0,0,0,0,0,0,0);

Это единственное средство, которое мы делали для поддержки совместимости с Delphi.

Проблема статических в том, что каждый тип там уникальный. То есть, array[1..10] of integer и array[0..9] of integer - это разные типы.

Что касается реализации чего-то дополнительного для статических массивов, то конечно весь лейтмотив создание PascalABC.NET - обучение современному программированию. Статические массивы с этой точки зрения сильно устарели и не хотелось бы “реанимировать труп”.

Ну, я всё-таки от автора сообщения хотел бы это услышать.

И конечно хотелось бы понять глубинный смысл этой фразы. Почему не хочется использовать генераторы? И чем предполагаемая конструкция

var a: array [1..10] of integer := [0] * 10;

лучше и проще

var a := Arr(0) * 10;

?

Кроме того, не следует забывать, что в NET при выделении памяти под объект все поля инициализируются нулями. С этой точки зрения следующий код верно инициализирует массив:

var a := new integer[10];

И это - явная инициализация, поскольку вызван конструктор.

3 лайка

С этим не поспоришь, только массив-то динамический.

В оригинале, кажется, было “гальванизировать” ))

Спасибо за развернутый ответ. Обязательная инициализация переменных это требование ФИПИ. И, согласитесь, в контексте классического Си или Pascal разумное требование. И оно распространяется на все языки в решениях 27 задания ЕГЭ, даже если в языке переменные обнулены автоматически.

И конечно хотелось бы понять глубинный смысл этой фразы. Почему не хочется использовать генераторы?

Приходится балансировать между “хочется рассказать всё” и “дать достаточный минимум для успешной сдачи ЕГЭ”. Если давать “всё”, многие не воспринимают и уходят, оптимизируя своё время подготовки к ЕГЭ. Приходится давать минимум, позволяющий кратко записать алгоритм. Если использовать генераторы, тогда надо бы рассказывать про Yield, что для ЕГЭ избыточно. Иначе инструкции превращаются в магию.

var a := Arr(0) * 10;

Вот этого не знал. Завтра попробую так рассказать. А сегодня с динамическими массивами плохо пошло. Вернулся на статические: https://www.youtube.com/watch?v=VKokPE-GZsI

Посмотрите личные сообщения.

С чего вдруг? Чтоб использовать ArrGen надо знать только про лямбды, а с ArrFill - вообще ничего заранее знать не надо. Ну а в SeqFill можно предложить не лезть, тем кто хочет только здать ЕГЭ и забыть.

Остальным - киньте эту ссылку:
http://pascalabc.net/downloads/Presentations/Tutorials/Sequences.pdf
Это с главной страницы сайта pascalabc.net

Да уж. Попробовал посмотреть стрим. Образец того, как не нужно писать в PascalАВС.NЕТ, извините за прямоту.

1 лайк

Что сразу из замечаний - глобальные переменные (var до begin) ещё хуже статических массивов.

  1. Они ещё больше влияют на производительность.
    Статические массивы это оболочка динамических, то есть, к примеру, чтение данных из них - это то что сделает динамический массив + что то поверх.
    Ну а глобальные переменные - это статические поля. Они хранятся в совершенно другой части памяти, нежили локальные переменные, поэтому (в зависимости от кеширования процессора) локальные переменные всегда в несколько раз быстрее.
begin
  var i1: integer := ReadInteger;
  var i2 := ReadInteger; // автоопределение типа переменной
end.
  1. Со стороны логики программы - переменные надо оптисывать не в 1 куче, а там где они понадобятся. То есть:
begin
  var k: integer;
  for var i := 1 to 5 do
  begin
    k := i*i;
    k.Println; // или ещё какое использование
  end;
  // дальше k не используется, но его всё равно видно
end.

Это плохо, лучше так:

begin
  for var i := 1 to 5 do
  begin
    var k := i*i;
    k.Println;
  end;
  // теперь тут k вообще не доступно
end.

Это помогает избегать множества ошибок ещё до запуска программы.

Как вариант, могу начать объяснять на C# ))))

Уже страшно, потому что в C#, по сути, действуют те же основные правила.

1 лайк

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

Потому что PascalАВС.NЕТ - по сути упрощенный C# в паскалевском синтаксисе.

Я понимаю и принимаю эти правила. Сам на C# 15 лет. И даже сертифицированный разработчик Microsoft. Но все упомянутые оптимизации не имеют отношения к ЕГЭ. Отчасти использую “старый” стиль Pascal, т.к. местами более кратко и более понятно для оставшихся в школе учителей. Мой канал не только школьники смотрят, но и учителя начальных классов и биологии, работающие учителями информатики.

Про более понятно - это миф. Если потратить пол часа на то чтоб узнать о нескольких основных функциях, как ReadArrInteger - код становится на много понятнее кода в старом стиле.

Обратите внимание - я говорю узнать а не заучить, потому что все такие функции не надо знать. Потому что:

  1. Ctrl+Space
  2. Описания функций.

Я пока учился - часто перелистывал функции с похожими на то что мне надо названиями и читал их описания. И на самом деле даже так - скорость написания программ уходит в плюс относительно старого стиля.


А про краткость - откуда вы вообще это взяли? Старый стиль наоборот известен своей громоздкостью. А в новом большинство задач решается в 1 строчку, даже если не стараться прибегать к таким извращениям.

Сергей, попробуйте написать на 4 балла №119 в правильном стиле. Я с интересом посмотрю. И минимум функций из библиотек!

PS: В конце концов, я же на вашей стороне. Много ли ютуберов поддерживают PascalABC? )))

PascalABC это другой язык. И вы не его поддерживаете, когда пишете в таком стиле.

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

begin
  var a := ReadArrInteger(ReadInteger);
  
  var c := 0;
  for var i1 := 0 to a.Length-2 do
    for var i2 := i1+1 to a.Length-1 do
      if ( (a[i1]+a[i2]) mod 10 = 0 ) and ( a[i1]*a[i2] mod 7 = 0 ) then
        c += 1;
  
  c.Println;
end.