Страницы

Поиск по вопросам

Показаны сообщения с ярлыком goto. Показать все сообщения
Показаны сообщения с ярлыком goto. Показать все сообщения

пятница, 31 января 2020 г.

Зачем нужны другие операторы если есть GoTo?

#алгоритм #ооп #goto


Задался вопросом, а зачем нужны другие операторы и циклы если есть мощное ключевое
слово GoTo?

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

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

На мой взгляд GoTo- это, что-то типа Базона Хигса, который считается частицей бога,
а GoTo оператор машинного бога.
    


Ответы

Ответ 1



Проблема в том, что код пишется не для компилятора, а для человека. Для ваших коллег и для вас самого через полгода. Безумная мощь оператора goto оборачивается его слабой выразительностью. При помощи goto вы можете выразить именно что всё: и итерирование по списку, и проверку логического условия, и вызов подпрограммы, что угодно. Вам, видя оператор goto, для понимания текста придётся восстанавливать логику каждый раз самому. А это трата времени и мысленных усилий, которые приходится применять каждый раз, когда вам нужно понять, правильный ли код, или, ещё хуже, найти ошибку и исправить её. Так что другие операторы в языках есть для людей, читающих и пытающихся понять логику программы. А компьютеру всё равно, он бы и с одним goto работал, железяка тупая.

Ответ 2



Это просто один из стилей 3-го поколения языков программирования. По-моему, возникший скорее для обучения новому мышлению, чем для реального выигрыша. Языки второго поколения (Ассемблеры) без GoTO (JMP) просто не могли работать. Переходные языки (Basic, Fortran) также нумеровали строки и использовали переходы. Стиль "без goto" - всего лишь стиль, не более. Иногда алгоритмы с goto работают быстрее, т.к. в полной мере используют возможности самого процессора Оператор Бога... Что-то в этом есть. Именно идея абстрактной универсальной алгоритмической машины Эмиля Поста содержала что-то типа goto. Всего лишь 6 операций, позволяющих реализовать любой алгоритм... Эта одна из них

Ответ 3



Не во всех языках есть этот оператор. Бездумное использование приводи к коду который очень сложно понимать и поддерживать (спагетти-код). Этот оператор плохо выражает намеренья программиста.

пятница, 13 декабря 2019 г.

Что происходит при безусловном переходе при помощи оператора goto?

#c #goto


Собственно, интересует, какие проблемы могут возникнуть при использовании этого оператора.

Для меня очевидно, что goto совершенно незаменим во множестве ситуаций:


построение конечных автоматов;
выход из глубоко вложенных циклов;
обработка ошибок и пр. 


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

Например:

goto A;
if (a() == 0)
{
    A:;
    b();// Вызов a() пропущен?
}


Или:

goto A;
// ...
for (int i = 0; i < 10; ++i)
{   
    A:;
    // i имеет неопределенное значение?
}


Или:

goto A;
int i;
// ...
i = a();
A:;
i = b();// Определение i пропущено, куда мы записываем результат работы b()?

    


Ответы

Ответ 1



В языке С время жизни автоматической переменной (кроме VLA) начинается в момент входа в блок, содержащий объявление этой переменной An object whose identifier is declared with no linkage and without the storage-class specifier static has automatic storage duration [...] For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way [...] Причем "момент входа в блок" - это чисто временнАя, а не пространственная характеристика - входить в блок можно любым способом, как через начало, так и прямо в середину. Как только управление попало внутрь блока - все автоматические переменные, объявленные в этом блоке уже существуют, независимо от того, видны ли в месте входа их имена. // Если мы попадаем в блок отсюда... { // <- ... то время жизни переменной `b` начинается уже здесь ... int b; // <- А здесь начинается лишь область видимости имени `b` ... } Таким образом для "создания" переменной (кроме VLA) совсем не обязательно, чтобы управление буквально проходило по определению этой переменной. Переменная уже существует с момента входа в блок. Поэтому передача управления при помощи goto через объявление с инициализацией в С приведет лишь к тому, что переменная не будет инициализирована. Однако на сам факт существования переменной и ее время жизни это не оказывает никакого влияния.

Ответ 2



Вызов a() пропущен? Да i имеет неопределенное значение? Да goto A; int i; A: i = b();// Определение i пропущено, куда мы записываем результат работы Не зависимо от местоположения определения, время жизни обычной переменной — целый блок. Также не важно, как произошёл вход в блок — в процессе обычного исполнения или через goto — компилятор должен обеспечить место хранения для данного объекта. Я не совсем понимаю, что происходит, если goto переводит выполнение в тело цикла или другого блока. На уровне языка это не важно. Можно, пожалуй руководствоваться сентенцией: выделять ресурсы под объекты с автоматическим временем жизни — забота компилятора, а инициализировать их — программиста. Так же мне не совсем понятно, являются ли переменные, через определение/объявление которых мы перепрыгнули, доступными для использования. Да, являются; единственное, что явно запрещено — это пересекать объявление массива переменной длины в его же области видимости: size_t n=getSize(); if (n<=0) { goto A; } // ошибка else if (n==1) { goto B; } // ок { int a[n]; A: a[n-2] = doSomething(); } B:; Также, строго говоря, когда управление проходит через объявление, значение переменной становится неопределённым: int j=0; goto assign; start: int i; j = foo(i); // здесь значение i, строго говоря, не определено. assign: i=-1; if (j==0) {goto start;} В остальном возможно практически всё, а семантика «так как оно и выглядит». Скользких мест, на вскидку, нет.

Ответ 3



Весь скомпилированный код испещрён goto. Как всё это выглядит в скомпилированном коде: /* goto A; if (a() == 0){ A:; b();// Вызов a() пропущен? } */ goto A; ax:= call a(); if ax == 0 goto A ; else goto Next ; A:; call b(); Next:; Для команды if вы привыкли, что некоторые участки кода НЕ выполняются, а тут вдруг пропущенный вызов a() у вас производит страх. /* goto A; // ... for (int i = 0; i < 10; ++i) { A:; // i имеет неопределенное значение? } */ goto A; стек[-4] := 0 ; ForBody:; if стек[-4] < 10 goto A; else goto Next; A:; ++ стек[-4]; goto ForBody; Next:; Здесь переменная не инициализирована, эта лажа уже на совести программиста. Будет неопределённое поведение. Но иногда, значение переменных не влияют на ход алгоритма, поэтому на совести программера будет: это фишка алгоритма или баг. /*goto A; int i; // ... i = a(); A:; i = b();// Определение i пропущено, куда мы записываем результат работы b()? */ goto A; stack[-4] := call a(); A:; stack[-4] := call b(); Значение переменной i хранится в стеке, и место уже выделено при старте функции заранее. Так-что фактическое исполнение программы желательно знать. Это очень помогает разобраться как работает комп.

Ответ 4



Любую программу с goto можно эквивалентными преобразованиями превратить в программу без goto, и тогда поддерживать ее встанет намного проще. Когда я вижу в чужом коде метку, я очень сильно настораживаюсь - а вдруг на эту метку прыгают из кода, который находится в другом файле, который прицеплен сюда при помощи #include? Количество WTF в секунду катастрофически возрастает, что в нашей работе и так неприемлемо. Решение - почитайте программную статью Дейкстры и ее критику. Для меня очевидно, что goto совершенно незаменим во множестве ситуаций: построение конечных автоматов; выход из глубоко вложенных циклов; обработка ошибок и пр. Очевидно как раз обратное: Использовать процедуры или классы с полиморфизмом - не нужен goto return/throw return/throw, RAII

среда, 27 ноября 2019 г.

Почему const и goto не используются в java?

#java #синтаксис #константа #goto


Давайте поговорим о двух зарезервированных, но неиспользуемых ключевых словах языка
Java — const и goto. Почему они не используются? Как я понял const можно заменить на
public static final, но как быть с goto?
    


Ответы

Ответ 1



Обновление В спецификации Java (§3.9. Keywords) указана причина резервирования const и goto, не связанная с планами на будущее: The keywords const and goto are reserved, even though they are not currently used. This may allow a Java compiler to produce better error messages if these C++ keywords incorrectly appear in programs. Ключевые слова const и goto зарезервированы, хотя на данный момент не используются. Это позволит компилятору Java выводить более ясные сообщения об ошибках если эти ключевые слова C++ будут неправильно использоваться в программах. Т.о. разработчики Java изначально не имели планов использовать эти слова, а зарезервировали их чтобы отловить ошибки при копировании кода, написанного на C++ (если бы переменные можно было бы назвать goto либо const, то скопированный код C++ мог ошибочно пройти компиляцию и привести к неожиданным результатам при исполнении). Эта часть спецификации не изменялась с первого издания JLS. Ниже первоначальная версия ответа, в которой рассматриваются попытки найти применение для const и goto в Java. Многа букав: const и goto перешли из C++. Ключевым словам не нашли применения в Java. Функции, которые они выполняют в C++, в Java реализованы по-другому. История Исторически синтаксис Java основан на C++, поэтому разработчики приняли решение зарезервировать ряд ключевых слов C++, чтобы: отловить ошибки при копировании кода, написанного на C++; использовать их в дальнейшем при расширении языка; упростить переход на Java для C++-разработчиков. const и goto Таким образом вопрос сводиться к следующему: «Есть ли в Java необходимость в const и goto и что они должны делать?» const Одно из предложений ввести const по аналогии с C++ можно посмотреть по ссылке: JDK-4211070 : Java should support const parameters (like C++) for code maintainence Предложение было закрыто в 2005 году. По ссылке можно посмотреть разбор, в выводах которого отмечаются проблемы, связанные вводом const: Adding const is too late now. Had this been added from 1.0, the situation could have been different. Const pollution: the C++ approach requires all const methods to be marked with a const keyword. This means that most methods will have to be marked const explicitly. This tend to clutter all methods in C++. Compatibility is a very important feature of the JDK. Arguably, the collection classes should be modified to indicate that the elements are const. That would require all existing implementations to be updated in the same way, effectively breaking all existing non-JDK implementations of the collection interfaces. Similarly, hashCode would have to be const, breaking the current implementation of String. Создание константных переменных/полей в Java уже обеспечивается с помощью final. Ввод механизмов из C++ посчитали неоправданным. goto У goto плохая репутация (см. «Go To Statement Considered Harmful» Дейкстры). В Java имеются альтернативные операторы перехода: break, continue, return, которые покрывают большую часть области применения. Единственный довод в пользу goto состоит в том, что в отдельных случаях использование goto позволяет упростить код. По-видимому, сторонники goto не смогли оказать достаточного влияния на разработчиков, чтобы добавить новое ключевое слово. Похожие обсуждения в англиской версии: Why is there no Constant feature in Java? Is there a goto statement in Java?

Ответ 2



goto считается "плохим оператором", ухудшает читаемость и увеличивает запутанность кода, порождает трудноподдерживаемый "спагетти-код" (также нарушает очень важные концепции программирования, можно ознакомиться по ссылке в конце ответа). Некоторые серьезные люди считают, что ему нет места в языках программирования, и пишут об этом целые книги. Так вот, пока кто-то говорит об этом, создатели Java - делают. Они искренне считают, что без безусловного перехода мир станет чуточку добрее, и по совокупности проблем и преимуществ с ними можно согласиться. Подробнее Само же слово было зарезервировано на этапе создания языка, перекочевав из других популярных в то время. Так и болтается до сих пор... PS: в Java все же есть безусловные переходы, реализуемые через операторы break и continue с метками. Как часто вы ими пользовались и знали ли об этой возможности вообще (это по поводу нужности этого оператора)?

Ответ 3



Например они могут не использовать, но быть в языке, как задел на будущее, что бы в последующих версиях можно было легко добавить этот оператор и не пересечься с названием переменных/объектов в уже написанном(Legacy) на старой версии языка коде. В JavaScript, вроде, такая же практика. Касательно const, который можно заменить public static final: Ничего не мншает разработчикам JAVA в будущем реализовать const и добавить так называемых "синтаксический сахар", когда можно делать и так и так, и в итоге программа будет одинаково выполняться. Например, в C# много синтаксического сахара: Можно объявлять переменные по алиасу(int) или по самому типу(Int32) Есть LINQ, который позволяет в простых случаях обходится без циклов и т д...

вторник, 2 апреля 2019 г.

Зачем нужны другие операторы если есть GoTo?

Задался вопросом, а зачем нужны другие операторы и циклы если есть мощное ключевое слово GoTo?
GoTo можно заменить любой цикл, а так же GoTo дает простор для творчества, так как можно называть метки тем, что в голову взбретет .
Так же, все равно в конечно итоге красивый код превращается в последовательность GoTO на машинном языке.
На мой взгляд GoTo- это, что-то типа Базона Хигса, который считается частицей бога, а GoTo оператор машинного бога.


Ответ

Проблема в том, что код пишется не для компилятора, а для человека. Для ваших коллег и для вас самого через полгода.
Безумная мощь оператора goto оборачивается его слабой выразительностью. При помощи goto вы можете выразить именно что всё: и итерирование по списку, и проверку логического условия, и вызов подпрограммы, что угодно. Вам, видя оператор goto, для понимания текста придётся восстанавливать логику каждый раз самому. А это трата времени и мысленных усилий, которые приходится применять каждый раз, когда вам нужно понять, правильный ли код, или, ещё хуже, найти ошибку и исправить её.
Так что другие операторы в языках есть для людей, читающих и пытающихся понять логику программы. А компьютеру всё равно, он бы и с одним goto работал, железяка тупая.