Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > Скобки и порядок выполнения


Автор: Brutaller 25.7.2008, 18:36
Решил вот освоиться в сях для общего развития. До этого имел дело с Delphi и ассемблером, особых трудностей не возникало. По советам многих взял книгу http://www.books.ru/shop/books/3898 Дошел до 34-й страницы, пункт 1.5.3 "Подсчет строк" и... грабли.

Вот собственно код примера из книжки:
Код

#include <stdio.h>

main()
{

    int c, nl;

    nl = 0;
    
    while  ((c = getchar())!=EOF)
        if (c == '\n')
            ++nl;

    printf ("%d\n", nl);

}



Если его скомпилить как есть, то я вообще не понимаю как эта консоль может завершиться при вводе чего либо. Может это какие то *nix особенности? smile Решил немного преобразовать строчку с проверкой условия, заменил:

while  ((c = getchar())!=EOF)

на 

while ( ((c = getchar())!=EOF)  && (c!='q') )

Всё гуд, теперь после ввода "q" и нажатия Enter программа нормально завершается и выводит кол-во введённых строк.
Решил усложнить немного, чтобы теперь программа завершалась ни только при вводе "q", но и при вводе "Q" (в верхнем регистре).

И попробовал два варианта:

1-й: while ( ((c = getchar())!=EOF)  && (c!='q') && (c!='Q') )
2-й: while ( ((c = getchar())!=EOF)  &&  ((c!='q') && (c!='Q'))  )


Всё работает, программа завершается и при вводе "q" и при вооде "Q" , но...
Вопрос вот в чем. Почему и в первом и во втором случае результат один и тот же, т.е. оно даже компилируется одинаково (в отладчике смотрел). Хотя по моему мнению, 2-й вариант(в котором два последних условия заключены в общие скобки) вообще не должен принимать истинное значение никогда. Проясните пожалуйста ситуацию, может быть я просто во что то не въезжаю?

Автор: JackYF 25.7.2008, 18:39
Цитата(Brutaller @  25.7.2008,  17:36 Найти цитируемый пост)
Проясните пожалуйста ситуацию, может быть я просто во что то не въезжаю? 

Ну, (5+6+7) и (5+(6+7)) мало чем отличаются smile Аналогично и в твоём случае - скобки не добавляют и не убавляют ничего.

Автор: Partizan 25.7.2008, 18:40
Brutaller, о.О

оба варианта совершенно идентичны

по-вашему выражения:
1) А && B
2) (A && B)

различны?

Автор: Brutaller 25.7.2008, 19:01
Странно. Ведь первое выражение всегда "истина" в конкретном примере.

А вот во втором случае, если я ввожу например маленькую "q", то что получается?

(c!='q') - FALSE
(c!='Q') - TRUE

((FALSE)  && (TRUE))  что будет в итоге?  Не FALSE ли случаем ? Вроде как FALSE.


А первое выражение, то которое у нас ((c = getchar())!=EOF) является TRUE. Соответственно ((TRUE)  && (FALSE)) что даст?

Как вообще вычисляются выражения, в какой последовательности?

Или это я до такой степени не въезжаю в смысл СИ, или не знаю тогда smile

Автор: Partizan 25.7.2008, 19:30
Brutaller, с чем связан вопрос - не понятно...здесь же всё очевидно....

выражения 

1-й: while ( ((c = getchar())!=EOF)  && (c!='q') && (c!='Q') )
2-й: while ( ((c = getchar())!=EOF)  &&  ((c!='q') && (c!='Q'))  )

эквивалентны

В чём по-вашему отличие первого выражения от второго???

Автор: Brutaller 25.7.2008, 19:45
Вроде и так уже довольно подробно расписал всё. Хорошо, попробую еще раз.

В 1-м варианте выражение состоит из трёх частей и вычисляются они последовательно слева направо, так? Не вопрос, всё понятно.

Но во 2-м то случае два последних выражения заключены в скобки и вроде как должно вычисляться "логическое И" между этими двумя выражениями, а уже над полученным результатом производится "логическое И" между самой первой частью и тем что получилось, так?

И во втором то случае я ввожу только один из символов "q" или "Q" и результатом не может быть TRUE. Соответственно и всё выражение целиком тоже не может быть TRUE. В чем подвох ? smile

Автор: Partizan 25.7.2008, 19:55
Brutaller, так когда вы в первом случае вводите q или Q выражение тоже принимает значение False

например q

первое выражение: TRUE && TRUE && FALSE == FALSE
второе выражение: TRUE && (TRUE && FALSE) == FALSE;


если вы вводите Q, то

первое выражение: TRUE && FALSE && TRUE == FALSE;
второе выражение: TRUE && (FALSE && TRUE) == FALSE;


могу лишь вам сказать что при вводе Q, вычисление этих выражений будет несколько быстрее =)

Автор: Brutaller 25.7.2008, 20:10
Во блин! Как это я сразу не заметил? smile Всё так просто оказалось! 

Partizan, огромное спасибо! Вывел на свет smile

Вот если бы сразу сам расписал так логику по составляющим, то и проблемы не возникло бы. smile

Еще раз спасибо.

Partizan +3

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)