Тема: Вказівники та посилання, goto та конструкції контролю виконання і т.п.
поясніть для...
Ви не увійшли. Будь ласка, увійдіть або зареєструйтесь.
Ласкаво просимо вас на україномовний форум з програмування, веб-дизайну, SEO та всього пов'язаного з інтернетом та комп'ютерами.
Будемо вдячні, якщо ви поділитись посиланням на Replace.org.ua на інших ресурсах.
Для того щоб створювати теми та надсилати повідомлення вам потрібно Зареєструватись.
Український форум програмістів → Алгоритми та структури даних, технології → Вказівники та посилання, goto та конструкції контролю виконання і т.п.
Для відправлення відповіді ви повинні увійти або зареєструватися
поясніть для...
Посилання недоречне. В C++ посилання - це синтаксичний цукор для константних покажчиків.
Ну тоді вже...
рілі?
рілі?
Ну якщо пан естет, то хай замість GOTO JMP буде, суть же не змінюється.
Q-bart написав:рілі?
Ну якщо пан естет, то хай замість GOTO JMP буде, суть же не змінюється.
вибачте це дуже смішно тоді. Історія складається так:
- юзаєм goto
- то надто важко розуміти
- введемо більш поверхневі конструкції,
які будуть юзати goto під капотом, але про це вже ніхто знати не буде
- a goto заборонимо
Так, тільки не goto важко розуміти, а за допомогою goto можна створити конструкції, які важко розуміти, тому заборонімо усі goto, крім таких обрізаних варіантів. Але зі покажчиками та посиланнями та сама історія: в покажчиках надто легко заплутатися і розіменувати щось не те, тому введемо посилання, з якими можна робити лише ті операції, в яких не заплутаєшся. І взагалі всі історія програмування - це історія заборон, Heil Rust!
ІМНО проблема сішних вказівників у тому, що операції *a та &a префіксні, тоді як споріднені з ними операції доступу до елементів (a[n], a.fld, a->fld) — постфіксні, що відкриває можливість легко щось наплутати. Сюди ж — оголошення типів, де ці префікси-постфікси групуються між собою не менш неінтуїтивно. Чи рятує ситуацію посилання замість вказівника? Не бачу, які принципові зміни це з собою несе.
Якби у взяття об'єкта за вказівником був постфіксний синонім... Технічно, він є — можна робити a[0] замість *a, оголошувати вказівники як безрозмірні масиви. Але таке постфіксне вирівнювання не є загальноприйнятим.
Зовсім не в цьому. Префікс і постфікс - то лише синтаксис. Тим більше, що посилання не вимагає розіменування.
Проблема вказівників у тому, що надто легко прострелити собі ногу. Змінився розмір масиву, видалили щось із купи, передали від'ємну змінну замість додатної - і все, маємо UB, вказівник показує казна-куди, і компілятор того не помітить, і програма має добрі шанси не впасти на тестуванні, але впасти в продакшені. Додавати купу перевірок на початку кожної функції? Складно, нудно, гальмівно і засмічує текст. Посилання (майже) гарантовано вказують на щось, що існує, і це покриває щонайменше 90% випадків використання вказівників.
Посилання недоречне. В C++ посилання - це синтаксичний цукор для константних покажчиків.
Це правдиво лише частково, те, як реалізують посилання компілятори не є останньою інстанцією. Так більшість з них (принаймні найвідоміші), реалізовують посилання через константні вказівники, але це не означає, що це синтаксичний цукор саме для С++, як мови.
Посилання також мають свою семантику:
1. Посилання завжди створює псевдонім чинного об’єкта, на відміну від вказівника, який може мати значення nullptr;
2. Посилання не можна встановити повторно, воно завжди вказує на той самий об’єкт протягом усього свого життя;
3. Посилання може продовжити термін життя об’єкта;
Таким чином, на мовному рівні посилання є власною сутністю. Решта – деталі реалізації.
Власне, ще раз, внутрішньо посилання може бути реалізовано як вказівник, але стандарт ніколи цього не гарантує.
поясніть для...
А що...
Що коли я скажу вам, що функція int main() в C++ не є "справжньою" точкою входу в програму?...
koala написав:Ну якщо пан естет, то хай замість GOTO JMP буде, суть же не змінюється.
вибачте це дуже смішно тоді. Історія складається так:
- юзаєм goto
- то надто важко розуміти
- введемо більш поверхневі конструкції,
які будуть юзати goto під капотом, але про це вже ніхто знати не буде
- a goto заборонимо
Ну і що тут дивного, в цих концепціях чи в такому розвитку?, як ще виконати елементарні засоби контролю потоку виконання програми окрім як експлуатувати ці спеціальні (для того й вигадані) інструкції і створювати надбудови на них, - умовні переходи(if\else) й цикли(for\while, що згадано вище) теж надбудови/конструкції на jmp-ерах (je, jg, jl і т.п.)
І ніхто з "майстрів", наскільки мені відомо, не писав "не вживай GOTO взагалі", лише "не зловживай тим інструментом і вживай коли точно знаєш що робиш", те ж саме можна сказати про будь що від рекурсії й до коментарів. Це щось що спотворилось і поширилось як мем, який вважають за закон, видається мені.
Іноді GOTO допомагає зі швидкістю в вузьких/рідкісних випадках, коли обережно вживати, може стати простим і елегантним рішенням для проблеми. Сам юзав, хоч і убер-рідко (один-два рази коли притисло, а іншого не винайти без втрати мілісекунд), в людей (один раз пригадаю) бачив на критичних участках, й не один раз читав подібне у авторів.
І взагалі вся історія програмування - це історія заборон
Оце доволі дивна лінза для окуляр.
Не певен що вжив би слово "заборон", краще "уточнень" чи "строгіше/конкретніше визначення" а не заборона, так якось точніше.
Баланс між гнучкістю/універсальністю й безпекою/потенційною плутаниною, не остання річ, важко просто взяти й віддати цілком щось одне в обмін на інше.
Коли одного занадто, потім цим над-спеціалізованим будеш в поті чола збочуватися щоб чогось простого утнути, ще далі в той бік то взагалі річ скоріше стане практично непотребом (чи безпорадним агрегатом, допоміжною насадкою для іншого).
▼Прихований текстmamkin haker написав:поясніть для...
А що...
Що коли я скажу вам, що функція int main() в C++ не є "справжньою" точкою входу в програму?...
Звісно. Здається, навіть Прата бігцем згадує про якісь ініціалізуючі дії, що відбуваються перед main(). Або, наприклад, хто писав програми на асемблері під ДОС, пам'ятає, що точка входу і завершення оформлюються взагалі не як елементи функції. Сішний main() — це просто уніфікований інтерфейс, який, по-перше, незалежний від платформи і, по-друге, дозволяє оформлити основний блок програми як рядову функцію.
І ніхто з "майстрів", наскільки мені відомо, не писав "не вживай GOTO взагалі", лише "не зловживай тим інструментом і вживай коли точно знаєш що робиш", те ж саме можна сказати про будь що від рекурсії й до коментарів. Це щось що спотворилось і поширилось як мем, який вважають за закон, видається мені.
Іноді GOTO допомагає зі швидкістю в вузьких/рідкісних випадках, коли обережно вживати, може стати простим і елегантним рішенням для проблеми. Сам юзав, хоч і убер-рідко (один-два рази коли притисло, а іншого не винайти без втрати мілісекунд), в людей (один раз пригадаю) бачив на критичних участках, й не один раз читав подібне у авторів.
Автор мему - Дейкстра, і хоча він робить в оригінальній статті обережну обмовку, утім навіть вона досить однозначна для goto. Хоча багато інших не погоджувалися, так.
Ну і кінець-кінцем, підхід "от станеш майстром - будеш використовувати goto" означає, що нових майстрів з goto не з'явиться, а отже, його зрештою і не вживатимуть.
koala написав:І взагалі вся історія програмування - це історія заборон
Оце доволі дивна лінза для окуляр.
Не певен що вжив би слово "заборон", краще "уточнень" чи "строгіше/конкретніше визначення" а не заборона, так якось точніше.
Так, це дещо саркастично, але має і раціональне зерно. В цілому цикл розвитку виглядає так: пишемо багато коду - вигадуємо певні засоби для спрощення написання/читання коду - забороняємо щось, що не вписується в ці засоби.
Байт-код -> мнемоніка -> заборона використання кодів операцій.
Фіксація точок входу/виходу -> структури управління -> заборона goto.
Процедури -> проголошення власних операцій -> заборона прямого використання інструкцій процесора.
Функції -> функціональне програмування -> заборона побічних ефектів.
Типи даних -> створення наборів операцій для роботи з окремими типами -> заборона використовувати інші функції для цих даних.
Позначення змінних загального використання (великими літерами, скажімо) -> введення модифікатора const -> заборона змін -> borrow checker.
Поділ коду між розробниками -> введення модифікаторів доступу.
RAII -> заборона виходу без виклику деструктора.
C++ часто із заборонами додає засоби для того, щоб їх обійти (const_cast, reinterpret_cast, goto), але вони далеко не такі зручні, як робота без обмежень, і виглядають переважно огидно.
Байт-код -> мнемоніка -> заборона використання кодів операцій.
Це в теорії, а на практиці, у часи MS-DOS, коли асемблер мав найвищу силу, то вбудований асемблер у високорівневі мови(втім, окремий асемблер теж цим грішив) часто не підтримував всі навіть документовані хвункції процесора, тому доводилося писати в машинному коді у вбудованому асемблері. Окремі асмеблери принаймні мають макрозасоби, за допомогою яких можна додати нові мнемоніки, та не мучатися з машинним кодом весь час.
а на практиці, у часи MS-DOS
Той факт, що вам доводиться посилатися на минулі часи, про щось говорить, хіба ні?
0xDADA11C7 написав:а на практиці, у часи MS-DOS
Той факт, що вам доводиться посилатися на минулі часи, про щось говорить, хіба ні?
Не зовсім. Сучасний компілер сів та плюсів MSVC++ змушує мене городити такий город в 2022 році за допомогою мнемонік вбудованого асемблера, що додавання машинного коду в 90'му році здасться верхом раціоналізму та гарним смаком. Для х86 шелкодів (базонезалежного коду) доводиться такими милицями послуговуватися, бо не існує параметра компілера, з увімкненням якого б будь-який код ставав би базонезалежним, як це зроблено в gcc.
То не використовуйте вбудований асемблері. Турдукен-код - це все одно турдукен. Створюйте asm-файл як окрему одиницю збірки і буде вам щастя.
Турдукен-код - це все одно турдукен. Створюйте asm-файл як окрему одиницю збірки і буде вам щастя..
Ззовні це все одно виглядатиме як люта індусія. Тобто ви пропонуєте створити хвункції в окремому асм файлі, які, в якості результату, будуть видавати вказівники на функції в С файлі? Потім ще створити заголовковий .h файл та підключити його до С файлу.
І що найкумедніше, то така індусія потрібна лише для х86 коду, бо х86-64 код послуговується так званою RIP-адресацією(тобто вказівник на кід чи данні обчислюються відносно розташування поточної інструкції), тобто будь-який код стає базонезалежним.
То чи правильним буде твердження:
1. історія розвитку програмування - спрощення і абстракція;
2. одним з наступних етапв - no code;
3. фінальним - AI, який сам себе удосконалює!
?
Для відправлення відповіді ви повинні увійти або зареєструватися