Почему это компилируется?[C ++] - PullRequest
0 голосов
/ 18 декабря 2018

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

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

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

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

Мой вопрос: почему?Почему

    n /= 10

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

Ответы [ 4 ]

0 голосов
/ 18 декабря 2018

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

На самом деле, есть также &= и |=.

Этивсе оценивают новое назначенное значение.

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

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

0 голосов
/ 18 декабря 2018

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

0 голосов
/ 18 декабря 2018

Что у вас есть для цикла 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 );

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

0 голосов
/ 18 декабря 2018

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

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

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


1. Примечание: это то, что происходит для встроенных типов.По соглашению, когда / если вы перегрузите operator= для класса, у вас будет return *this;, поэтому он работает так же, как и ожидал бы пользователь - но эта часть не обязательна - вы можете перегрузите ваш operator=, чтобы вернуть другое значение или совершенно другой тип - но это почти всегда плохая идея, и ее обычно следует избегать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...