Почему Паскаль запрещает модификацию счетчика в для блока?

Это, потому что Паскаль был разработан, чтобы быть так или является там какими-либо компромиссами?

Или что за и против должны запретить или не запретить модификацию счетчика в для блока? По моему скромному мнению, существует мало использования для изменения счетчика в для блока.

Править:
Вы могли обеспечить один пример, где мы должны изменить счетчик в для блока?

Трудно выбрать между ответом wallyk и ответом cartoonfox, так как оба ответа так хороши. Анализ Cartoonfox проблема от аспекта языка, в то время как wallyk анализ проблема из истории и реального аспекта. Так или иначе спасибо за все Ваши ответы и я хотел бы выразить свою особую благодарность к wallyk.

7
задан Jichao 24 January 2010 в 13:24
поделиться

7 ответов

Веб-приложения являются преобладающими по многим причинам:

  1. Его легко защитить
  2. Это создает стандартную точку ссылки, которую каждый может получить доступ:
  3. не блокирует людей с использованием разных платформ.
  4. Легче людям к доступу от вне сети (оно ставит проблемы безопасности на маршрутизаторы / VPN и т. Д.)
  5. Менее техническую поддержку (стандартная бегущая платформа)
  6. проще для поддержки (если она спущена, то у вас есть Критическая команда реагирования, которая может исправить это, а не 1000-х из машин, которые случайным образом снижаются)
  7. центральная точка хранения данных (легче резервного копирования и доступа)
  8. могут масштабироваться лучше
  9. . Это легче построить или повторно использовать Франки предприятия, чем находить / создать распределенный компонент, установленный для работы с изменяющейся средой (LDAP, разные дб, разные резервные копии, синхронизации)
  10. , менее подверженных злоумышленникам (Worms, люди, изменяющие клиента и т. Д.)
  11. Иногда может иметь твердые закодированные среды или требуют определенных наборов инструментов, которые создают новых пользователей болей для настройки
  12. . Это дешевле, чтобы иметь дело с сервером, а не 1000-х годов клиентов. Вы можете настроить системы, чтобы быть восстановим и иметь быструю неспособность. Да, серверное оборудование стоит больше по фактору, но это стоит меньше, чтобы поддерживать в долгосрочной перспективе.
-121--1379513-

При теории языка программирования (и теории вычислимости) , в то время как и для петлей имеют различные теоретические свойства :

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

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

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

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

В строго теоретических терминах вам никогда не нужно модифицировать счетчик в рамках цикла. Если бы вы могли сойти с ним, вы бы просто имели альтернативный синтаксис для цикла в то время как.

Вы можете узнать больше о «во время вычислимости петли» и «для вычислимости петли» в этих лекциях CS: http://www-compsci.swan.ac.uk/~csjvt/jvtteaching/tpl. HTML

Другое такое свойство BTW заключается в том, что LOOPRATIMATION не определена после цикла. Это также облегчает оптимизацию

14
ответ дан 6 December 2019 в 05:06
поделиться

UPDATE

Как указано в другом ответе, приведенное ниже решение является «избыточным», поскольку удаляет MacPorts из вашей системы, что, как я думал, уже было сделано ранее. Продолжайте осторожно. Возможно, путь использовать MacPorts для обновления установки libxml2.


Я решил эту проблему (по крайней мере, на моей машине).

Как только я понял, что ничто в этом следе не говорит об отсутствии libxml2, а скорее о проблеме с обнаруживаемой версией, я посмотрел вокруг на подтверждение этого факта. Конечно, сайт nokogiri (где многие похожие сообщения о жучках указывали на меня) утверждает в неопределенных терминах, что Snow Leopard поставляется с хорошей рабочей версией libxml2.

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

$ libxml2-2.7.1 tfwright$ sudo find / -type d -name "libxml2" 
find: /dev/fd/3: Not a directory
find: /dev/fd/4: Not a directory
/Developer/SDKs/MacOSX10.4u.sdk/usr/include/libxml2
/Developer/SDKs/MacOSX10.5.sdk/usr/include/libxml2
/Developer/SDKs/MacOSX10.6.sdk/usr/include/libxml2
/opt/local/include/libxml2
/opt/local/share/gtk-doc/html/libxml2
/opt/local/var/macports/distfiles/libxml2
/opt/local/var/macports/receipts/libxml2
/opt/local/var/macports/software/libxml2
/opt/local/var/macports/software/libxml2/2.6.30_0/opt/local/include/libxml2
/opt/local/var/macports/software/libxml2/2.6.30_0/opt/local/share/gtk-doc/html/libxml2
/opt/local/var/macports/sources/rsync.macports.org/release/ports/textproc/libxml2
/usr/include/libxml2
/usr/share/gtk-doc/html/libxml2

Сын... просто сдув /opt/local/var/macports , который я пытался прежде всего, похоже, не исправить проблему, поэтому я пошел к большим пушкам .

sudo rm -rf \
/opt/local \
/Applications/DarwinPorts \
/Applications/MacPorts \
/Library/LaunchDaemons/org.macports.* \
/Library/Receipts/DarwinPorts*.pkg \
/Library/Receipts/MacPorts*.pkg \
/Library/StartupItems/DarwinPortsStartup \
/Library/Tcl/darwinports1.0 \
/Library/Tcl/macports1.0 \
~/.macports

После чего все устанавливается нормально. верно. Никогда не доверяйте рекомендациям сообщений об ошибках! Мне не нужно было переустановлять libxml2 с макпортами, а нужно было удалить все следы макпортов из моей системы , которая преследовала меня из-за мусора.

-121--3747479-

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

Если вы хотите рассматривать пару каталогов как одну единицу, вы можете использовать «wordpress/wp-content» в качестве корня репо и использовать файл .gitignore на верхнем уровне, чтобы игнорировать все, кроме двух интересующих подкаталогов. Это, вероятно, наиболее разумное решение на данном этапе.

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

-121--1819849-

Это может облегчить некоторые оптимизации (например, запуск цикла): нет необходимости в сложном статическом анализе для определения предсказуемости поведения цикла.

3
ответ дан 6 December 2019 в 05:06
поделиться

Отказ от ответственности: Было десятилетиями, так как я в последний раз делал Паскаль, поэтому мой синтаксис может быть не совсем правильным.

Вы должны помнить, что Паскаль - это ребенок Никлауса Вирта, и Вирт очень сильно заботился о надежности и понятности, когда он спроектировал Паскаль (и все его преемники).

Рассмотрим следующий фрагмент кода:

FOR I := 1 TO 42 (* THE UNIVERSAL ANSWER *) DO FOO(I);

, не глядя на процедуру Foo, ответьте на эти вопросы: ли этот цикл закончится? Откуда вы знаете? Сколько раз процедура Foo вызывается в цикле? Откуда вы знаете?

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

1
ответ дан 6 December 2019 в 05:06
поделиться

Вероятно, можно сделать вывод, что Pascal был разработан для предотвращения модификации индекса for цикла внутри цикла. Стоит отметить, что Pascal далеко не единственный язык, который препятствует программистам делать это, еще одним примером является Fortran.

Есть две веские причины для разработки языка таким образом:

  1. Программы, в частности, для циклов в них, легче понять и, следовательно, легче написать, а также модифицировать и верифицировать.
  2. Петли легче оптимизировать, если компилятор знает, что счетчик пройденных циклов установлен до входа в цикл и инвариантен потом.

Для многих алгоритмов такое поведение является обязательным; например, обновление всех элементов в массиве. Если память обслуживает Pascal, то он также обеспечивает выполнение циклов do-while и повторное использование циклов. Большинство, наверное, алгоритмов, реализованных на языках в стиле Си с модификацией переменной индекса цикла или вырывами из цикла, можно было бы так же легко реализовать и с этими альтернативными формами цикла.

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

Regards

Mark

1
ответ дан 6 December 2019 в 05:06
поделиться

Из Для цикла

В некоторых языках (не C или C++) переменная цикла неизменна внутри сфера действия корпуса петли, с любыми попытка изменить его значение расценивается как семантическая ошибка. Такой изменения иногда бывают следствие ошибки программиста, что может быть очень трудно идентифицировать один раз. Однако только явный изменения, вероятно, будут обнаружены компилятор. Ситуации, в которых передается адрес переменной цикла в качестве аргумента к подпрограмме сделать так. очень трудно проверить, потому что поведение рутины в целом неизвестный компилятору.

Похоже, это поможет тебе не сжечь руку позже.

1
ответ дан 6 December 2019 в 05:06
поделиться

Паскаль изначально разрабатывался как язык обучения для поощрения блочно-структурированного программирования. Керниган (K из K&R) написал (по понятным причинам предвзятое) эссе об ограничениях Паскаля Почему Паскаль не мой любимый язык программирования .

Запрет на изменение того, что Паскаль называет управляющей переменной цикла for , в сочетании с отсутствием оператора break означает, что можно знать, сколько раз выполняется тело цикла, не изучая его содержимого.

Без оператора break и невозможность использовать управляющую переменную после завершения цикла является большим ограничением, чем невозможность изменить управляющую переменную внутри цикла, поскольку это предотвращает некоторую строку и алгоритмы обработки массивов от написания "очевидным" способом.

Эти и другие различия между Паскалем и C отражают разные философии, с которыми они были впервые разработаны: Паскаль для обеспечения соблюдения концепции «правильного» дизайна, C для обеспечения более или менее всего, независимо от того, насколько опасно.

(Примечание: в Delphi есть оператор Break , а также Continue и Exit , который похож на return в C.)

Очевидно, что нам никогда не понадобится , чтобы иметь возможность изменять управляющую переменную в цикле for , потому что мы всегда можем переписать, используя цикл while . Пример использования такого поведения на языке C можно найти в разделе 7.3 K&R, где представлена ​​простая версия printf () . Код, обрабатывающий последовательности '%' в строке формата fmt :

for (p = fmt; *p; p++) {
    if (*p != '%') {
        putchar(*p);
        continue;
    }
    switch (*++p) {
    case 'd':
        /* handle integers */
        break;
    case 'f':
        /* handle floats */
        break;
    case 's':
        /* handle strings */
        break;
    default:
        putchar(*p);
        break;
    }
}

Хотя здесь используется указатель в качестве переменной цикла, он также мог быть записан с целочисленным индексом в строку:

for (i = 0; i < strlen(fmt); i++) {
    if (fmt[i] != '%') {
        putchar(fmt[i]);
        continue;
    }
    switch (fmt[++i]) {
    case 'd':
        /* handle integers */
        break;
    case 'f':
        /* handle floats */
        break;
    case 's':
        /* handle strings */
        break;
    default:
        putchar(fmt[i]);
        break;
    }
}
7
ответ дан 6 December 2019 в 05:06
поделиться

Паскаль был впервые реализован для CDC Cyber ​​- мэйнфрейма 1960-х и 1970-х годов - который, как и многие современные процессоры, имел отличную производительность последовательного выполнения инструкций, но также значительно снижал производительность для ветвей. Эта и другие характеристики Cyber-архитектуры, вероятно, сильно повлияли на разработку Паскаля для контуров .

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

Длинный ответ

Семейство 6600 Control Data Corporation, которое включает Cyber, представляет собой архитектуру RISC, использующую 60-битные слова центральной памяти, на которые ссылаются 18-битные адреса. Некоторые модели имели (дорогостоящую, поэтому редко встречающуюся) опцию Compare-Move Unit (CMU) для прямой адресации 6-битных символьных полей, но в остальном поддержка «байтов» любого вида отсутствовала. Поскольку в целом на CMU нельзя было рассчитывать, большая часть Cyber-кода была сгенерирована из-за его отсутствия. Десять символов на слово были обычным форматом данных, пока поддержка строчных символов не уступила место предварительному 12-битному представлению символов.

Инструкции имеют длину 15 или 30 бит, за исключением инструкций CMU, длина которых фактически составляет 60 бит. Таким образом, в каждое слово помещается до 4 инструкций, или две 30-битные, или пара 15-битных и одна 30-битная. 30-битные инструкции не могут охватывать слова.Поскольку пункты назначения ветвления могут ссылаться только на слова, цели перехода выравниваются по словам.

В архитектуре нет стека. Фактически, инструкция вызова процедуры RJ по сути не является реентерабельной. RJ изменяет первое слово вызываемой процедуры, записывая переход к следующей инструкции после того, где находится инструкция RJ. Вызываемые процедуры возвращаются к вызывающей стороне, перескакивая в свое начало, которое зарезервировано для обратной связи. Процедуры начинаются со второго слова. Для реализации рекурсии большинство компиляторов использовали вспомогательную функцию.

Регистровый файл имеет восемь экземпляров каждого из трех типов регистров: A0..A7 для управления адресами, B0..B7 для индексации и X0..X7 для общей арифметики. Регистры A и B имеют размер 18 бит; Регистры X - 60 бит. Установка от A1 до A5 имеет побочный эффект загрузки в соответствующий регистр с X1 по X5 содержимым загруженного адреса. Настройка A6 или A7 записывает соответствующее содержимое X6 или X7 по адресу, загруженному в регистр A. A0 и X0 не связаны. Регистры B могут использоваться практически в каждой инструкции в качестве значения для добавления или вычитания из любого другого регистра A, B или X. Следовательно, они отлично подходят для небольших прилавков.

Для эффективного кода для переменных цикла используется регистр B, поскольку с ними могут использоваться инструкции прямого сравнения (B2 <100 и т. Д.); сравнения с регистрами X ограничены отношением к нулю, поэтому сравнение регистра X, скажем, со 100 требует вычитания 100 и проверки результата на значение меньше нуля и т. д.Если присвоение переменной цикла было разрешено, 60-битное значение должно быть проверено по диапазону перед присвоением регистру B. Это настоящая неприятность. Г-н Вирт, вероятно, решил, что и хлопоты, и неэффективность не окупились - программист всегда может использовать , а или повторять ... до петля в этой ситуации.

Дополнительная странность

Некоторые уникальные особенности языка Pascal имеют прямое отношение к аспектам Cyber:

  • ключевое слово pack : либо один «символ» занимает 60-битное слово, либо или оно упаковано десятью символами на слово.
  • (необычный) alfa тип: упакованный массив [1..10] char
  • внутренних процедур pack () и unpack () для работы с упакованными символами. В современных архитектурах они не выполняют никаких преобразований, а только преобразовывают типы.
  • странность текстовых файлов по сравнению с файлом char
  • без явного символа новой строки. Управление записями было явно вызвано с помощью Writeln
  • Хотя набор char был очень полезен на CDC, он не поддерживался на многих последующих 8-битных машинах из-за избыточного использования памяти (32-байтовые переменные / константы для 8-битного ASCII). Напротив, одно слово Cyber ​​могло управлять собственным 62-символьным набором, опуская новую строку и что-то еще.
  • оценка полного выражения (по сравнению с сокращениями). Они были реализованы не путем перехода и установки единицы или нуля (как это делают сегодня большинство генераторов кода), а с помощью инструкций ЦП, реализующих логическую арифметику.
12
ответ дан 6 December 2019 в 05:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: