Чи дійсно i, j = 1 вводить в оману? [зачинено]


11

Існує загальний аргумент про множинні ініціалізації змінної в одному вкладиші, тобто:

Розглянемо для прикладу int i, j = 1; що може призвести деяких людей до помилкової думки, що обидві змінні ініціалізуються

Можна стверджувати, що хтось повинен достатньо знати синтаксис його мови, щоб не помилитися з цим. Ще один аргумент може бути, оскільки розробники ми вивчаємо так багато мов, що можемо помилитися між особливостями між мовами.

Однак для цього дуже конкретного випадку мені цікаво, що чи існує навіть мова, де саме синтаксис i, j = 1 ініціалізує обидві змінні?

Якщо ні, то цей аргумент не застосовується.


2
Якщо ваша мова є розумною, потенційна плутанина нешкідлива, оскільки доступ до неініціалізованої змінної викликає помилку компілятора.
CodesInChaos

4
@CodesInChaos ти кажеш, що C не є здоровим?
Балдрік

2
Тільки тому, що мова щось дозволяє, це не означає, що ви не завдаєте людям непотрібного болю. Єдине місце, до якого вимагається цей код - це вікторини, призначені для покарання тих, хто не запам’ятав мовну специфікацію. Я завжди провалював такі питання. Bleh.
candied_orange

2
У Visual Basic 6 Dim Apple, Orange, Pear as Fruit- юридична декларація. Припустимо, ви не знаєте VB. Ваше перше враження, яке Appleє типовим Fruit? Це не так. Пам'ятайте, мови часто читають люди, які не є фахівцями з цієї мови; якщо ви фахівець, використовуйте мову з розумом, щоб чітко донести свої наміри навіть неекспертам. Я ніколи не використовую кілька ініціалізацій на будь-якій мові.
Ерік Ліпперт

13
Аналогічно: подумайте, var x = 1, y = 1.5; чи це те саме, int x = 1; double y = 1.5;чи це те саме, що double x = 1, y = 1.5;? Коли ми додали varдо C # 3.0, я зробив опитування і виявив, що приблизно половина людей вважає, що перша "очевидно" правильна, а друга половина вважає, що друга "очевидно" правильною, і тому ми зробили це незаконним. Особливість, яка повністю вводить в оману половину населення, є поганою ознакою.
Ерік Ліпперт

Відповіді:


37

Я думаю, що ні, але це не в тому. Справа в тому , що i, j = 0дуже легко переплутати i = j = 0, що робить ініціалізації обох. Чіткість - найважливіша вимога до вихідного коду поруч з правильністю, а той факт, що це питання навіть виникає, доводить, що ясність є неоптимальною.


3
Я також зауважу, що якщо таке твердження не ініціалізує обидва твердження, чому воно взагалі існує?
Берин Лорич

2
@BerinLoritsch залежить від мови. Це часто робиться в JavaScript через підняття декларації: багато хто вважає найкращою практикою оголошувати змінні у верхній частині області, в якій вони доступні, навіть якщо ви не ініціалізуєте їх до того місця, де вони використовуються в коді. . Практично всі засоби перетворення коду виходять таким чином.
Джаред Сміт

1
Я припускаю, що це одне, якщо це зробити інструмент виведення коду, оскільки це, як вважається, слід довіряти. Однак для людей я б рекомендував проти цього поєднувати оголошення та ініціалізацію останнього елемента лише в одному рядку. Це просто схоже на помилку, що чекає, що трапиться.
Берін Лорич

2
@JaredSmith Окрім Maple, я не можу придумати мову, де цього зараз бажано, навіть C зараз вважає за краще наблизитись до сфери застосування (як C ++ та більшість інших мов із напівпристойними статичними компіляторами), оскільки це дає перевагу зупинці потенційних помилок і дозволяє компілятор вирішить, що робити зі змінною до тих пір, поки функціональність не зміниться, що, можливо, дозволить покращити оптимізацію, враховуючи, що ви можете піти з меншими регістрами.
WHN

6
Незалежно від мови, слід запитати : «Що таке перевага написання int i, j=1проти int i; int j = 1(або навіть краще, окремі лінії)?»
чепнер

2

Я думаю, ви можете сперечатися для будь-якої сторони:

  • Контра i, j = 0:
    Математики використовують це, щоб означати, що і те, iі інше jповинно бути нульовим.

  • Про i, j = 0:
    Просте питання знати перевагу ваших операторів. І якщо ви сумніваєтесь у їхньому перевазі, зараз саме час це шукати.

    Це та сама причина, чому ми пишемо речі, як a.b += c[i]*d[i];без дужок. Звичайно, це рівнозначно (a.b) += ((c[i])*(d[i]));, але можна очікувати, що програмісти знають пріоритет найбільш використовуваних операторів напам'ять і зможуть шукати перевагу операторів, коли вони не впевнені. Таким чином, круглі дужки, як правило, вважаються марними затрудненнями, якщо вони не застосовують інший порядок оцінки, ніж прописаний оператором пріоритет.

    Звичайно, є винятки. Пріоритет <<і, +як правило, вважається досить неоднозначним, щоб зробити круглі дужки в будь-якому випадку. Але це виняток, який підтверджує правило.

Я, наприклад, більше впаду на сторону Pro, але я готовий дотримуватися будь-якого стильового керівництва, що забороняє такі декларації. Це просто справа, з якою не варто боротися.


7
Зауважу, що в int i, j = 0;ньому немає операторів . Єдиним виразом у цьому твердженні є, 0і тому пріоритет оператора не входить у нього. Аналізатор не розглядає ,як оператор коми або =оператор присвоєння; скоріше, це граматичні частини заяви заяви.
Ерік Ліпперт

@EricLippert Що стосується правил пріоритету, то ця різниця не має значення: Будь-яка мова, яку я знаю у стилі С, використовує ті самі пріоритети в декларації, як і в інших виразах. Все інше запросило б катастрофу.
cmaster - відновити моніку

but programmers can be expected to know the precedence of the most used operators by heart, ти кажеш. У наведеному прикладі я не впевнений, що більшість (середніх) програмістів сприймають оператора доступу членів або оператора індексу масиву як операторів у математичному сенсі, але замість цього вважають їх більше як іменниками природної мови та множенням оператор як дієслово. Ось чому int i, j, k = 0;така нахабна конструкція, бо вона представляє природний мовний аналог "int змінних i, j, k і оголошується і встановлюється на 0"!
Стів

@Steve Як ви пам'ятаєте правила пріоритетності як програміста, повністю залежить від вас. Якщо це допоможе вам уявити їх як іменники мови, зробіть це. Однак у такому випадку у вас виникнуть проблеми, коли ви побачите подібні речі *a[i], я не думаю, що ви зможете достатньо розібратися з аналогією "іменників". Що стосується int i, j, k = 0;, це може означати що завгодно, якщо ви не шукаєте правила: Третє тлумачення було б оголосити int i, потім оцінити jі нарешті призначити k = 0. Якщо ви не знаєте синтаксис вашої мови, ви не можете розбирати такі конструкції. Це ваша проблема, якщо ви все-таки зробите це.
cmaster - відновити моніку

@cmaster, я не висловлював свою конкретну стратегію запам'ятовування ха-ха. Я не програміст на C, тому моє знайомство з перевагою оператора в C є другосортним. Але те, що я зазначив, коли я дивився на ваш приклад, це те, що я навіть не вважав оператора множення таким, що має відносне перевагу перед оператором індексу масиву. Тобто я не читав a[i]як застосований до нього індексний оператор a, а читав обидва разом як невідводячий синтаксичний елемент, що вказує операнд оператора множення, і, отже, мені навіть не запропонували оцінити пріоритет. (1/2)
Стів
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.