Почему это компилируется? [C++]

Я попытался найти ответ в Интернете, но не нашел его.

Сегодня я увидел эти строки кода:

    int main(){
    int n = 7;
    while(n /= 10);
    }

В этом нет особого смысла, но вопрос был только в том, будет ли он компилироваться? На что я ответил отрицательно, но ошибся.

У меня вопрос, а почему? Почему

    n /= 10

вести себя как bool (или int) здесь?

Любое ненулевое значение рассматривается как true в C++.

Algirdas Preidžius 17.12.2018 22:30

Оператор / = правильный и эквивалентен: (n = n / 10) Так же, как оператор + =, который эквивалентен: (n = n / 10)

YouneS 17.12.2018 22:31

В будущем вы будете в ужасе от того, сколько компилируется, когда вы этого не хотите.

user4581301 17.12.2018 22:32
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
145
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий

Присвоение (включая составное присваивание, такое как /=) - это выражение, которое дает значение, которое было присвоено 1.

Итак, вы можете сделать что-то вроде: x = y = z = 0;, который присваивает 0 z, берет результат этого (также 0) и присваивает его y, а результат этого (по-прежнему 0) присваивает x.

Оттуда он использует неявное преобразование из int в bool, при котором 0 преобразуется в false, а любое ненулевое значение преобразуется в true.


1. Note: that's what happens for built-in types. By convention, when/if you overload operator= for a class, you have it return *this;, so it works the same way, as a user would/will expect--but that part's not mandatory--you can overload your operator= to return a different value or an entirely different type--but this is almost always a bad idea and should usually be avoided.

C++ преобразует n / = 10 в bool. Целые числа = 0, преобразованные в логическое значение, оцениваются как ложные. Целые числа! = 0, преобразованные в логическое значение, оцениваются как истина. Это пока будет оцениваться как while(false).

Нет, он не будет работать вечно, потому что n будет изменять каждую итерацию цикла.

Mark Ransom 17.12.2018 22:33

Целые числа! = 0 ложны.

stark 17.12.2018 22:34

@stark: Нет, целые числа == 0 - ложь, целые числа! = 0 - истинные.

Fred Larson 17.12.2018 22:34

на самом деле он не будет запускаться ни разу

pm100 17.12.2018 22:35

Editet, целые числа! = 0 истинны.

Jaco Alberts 17.12.2018 22:35

Итак ... почему он не запускается?

Jaco Alberts 17.12.2018 22:36

@JacoAlberts 7/10 - 0, т.е. ложь.

eerorika 17.12.2018 22:37

@JacoAlberts Оператор /= "Итак ... почему он не запускается?" для встроенных типов возвращает присвоенное значение. Поскольку n - это 7 перед первой итерацией, n /= 10 вернет 0, который будет рассматриваться как false, и, следовательно, ни одна итерация тела цикла не будет оцениваться.

Algirdas Preidžius 17.12.2018 22:39

Он действительно работает, но не вечно. n - это int, 7/10 = 0,7, преобразовать в int = 0, результат будет ложным. Так запускается один раз. В этом примере нет тела цикла для выполнения. Бит Я согласен, если бы было тело цикла, оно бы не выполнялось. Сразу говорю, программа запускается.

Jaco Alberts 17.12.2018 22:42

Обновлен исходный ответ

Jaco Alberts 17.12.2018 22:48

@JacoAlberts "Бит Я согласен, если бы было тело цикла, оно бы не выполнялось." Есть тело цикла. Он состоит из одного пустого оператора.

Algirdas Preidžius 18.12.2018 06:01

Вот что у вас есть для цикла while:

while ( expression );

Если экспрессия - true или non 0, цикл будет продолжен; в противном случае, если он оценивается как false или 0, он будет завершен. Итак, оглядываясь на свой оригинал:

int n = 7;
while ( n /= 10 );

Тогда это становится:

while ( n = 7 / 10 ); 

Здесь полное выражение - n = 7 / 10; Это должно привести к 0 из-за усечения целочисленной арифметики. Значение неявного преобразования из int в bool становится false. В результате получился 0.

Здесь ничего не мешает компиляции. Поскольку это ничем не отличается от наличия:

while ( false );

Однако с присваиванием и арифметическими операциями; это может быть не всегда так, но в вашем случае это так. Рассмотрим следующий пример: он все равно будет компилироваться, но цикл не завершится:

int n = 5;
while( n + n );

Тогда это станет:

while( 5 + 5 );
...
while( 10 );
...
while( true );

Что по-прежнему будет компилироваться, но цикл будет продолжаться бесконечно.

Разве n = 7/10 не будет 0, поскольку значения целые? В остальном ответ довольно ясен.

auouo 18.12.2018 00:37

@auouo 7/10 зависит от компилятора и того, как он выполняет целочисленную арифметику. Если он усекает его, то да, это будут 0 и false, но если нет и увидит, что это не значение 0, он будет рассматривать его как true. Однако я думаю, что вы правы, говоря, что это 0.

Francis Cugler 18.12.2018 01:43

@auouo Я отредактировал свой ответ, чтобы отразить это, поскольку я забыл об усечении ....

Francis Cugler 18.12.2018 01:46

+= и -= работают так же, как *= и /=.

На самом деле есть еще &= и |=.

Все они оценивают новое значение, которое было присвоено.

И, как вы знаете, вам не нужно помещать логическое значение в условие while / for / if; вам нужно только поместить туда что-то, что может быть преобразованный для логического значения.

Например, if (42), или for (char* ptr = begin; ptr; ++ptr), или while (n /= 10).

Другие вопросы по теме