2014-10-30 4 views
0

Я не очень боюсь этого упражнения (святое дерьмо, после 1-20 до 1-24 ...), но мне интересно, если что-то не так с моим решением. В упражнении вам предлагается написать цикл, эквивалентный следующему:K & R Язык программирования C - Упражнение 2-2: Проверьте мою работу?

for (i=0; i<lim-1 && (c=getchar()) != '\n' && c!= EOF; ++i) 
    s[i] = c; 

без использования || или & &. Я предпочитаю не использовать какие-либо языковые функции, не представленные мне уже, и я серьезно отношусь к идее, что каждое упражнение размещается там, где оно есть, потому что целью является использование пользователем предоставленных концепций. Таким образом, я пришел с этим:

for (i=0; (i<lim-1) == ((c=getchar()) != EOF) == (c != '\n'); ++i) 
    s[i] = c; 

Там в много похорошела решение с простой, если/иначе, если тип условна, но я хотел бы использовать разговор этой секции о выражениях, имеющих числовые значения на основе их правду или фальшь и так далее. Дело в том, что мое решение не входит ни в один из сайтов, на которых я обычно проверяю правильные решения для упражнений, поэтому, несмотря на то, что он работает одинаково. Мне было интересно, если что-то не так с тем, как я это сделал, кроме того, что он был уродлив? Отличается ли функциональность каким-то образом?

+3

Вы можете изменить EOF и '\ п', если я могу видеть.И еще одна проблема заключается в том, что если все утверждения будут ложными, то результат будет истинным (false == false приведет к true). Поэтому я бы добавил «== true» в конце, тогда мне кажется, что это правильно. – Sekory

+0

Этот вопрос не соответствует теме, потому что он принадлежит [codereview.se] –

+0

Кажется труднее прочитать, чем [if/else solution] (https://github.com/thvdburgt/KnR-The-C-Programming -Language-Solutions/blob/master/Chapter% 202/2-2/loop.c) (что, вероятно, было предназначено.) –

ответ

1

Помимо всего прочего, это неопределенное поведение, поскольку оно зависит от порядка оценки. && и || определите сначала свои левые операнды, но == нет. Таким образом, нет гарантии, что второе использование c будет ссылаться на новое значение, а не на значение из предыдущего цикла (или унифицированного значения в первый раз).

Оценка короткого замыкания && является важной частью семантики исходного цикла. Тот факт, что && не оценивает свой второй операнд, если его первый операнд является ложным, означает, что исходный цикл гарантированно вызывает getchar не более lim-1 раз. Переписанный без &&, getchar будет называться дополнительным временем, когда i достигнет lim-1, а символ, который был прочитан (если он был там), затем опускается в ведро бит, что означает, что он будет отсутствовать при следующей попытке прочитать ввод.

И, наконец, a == b - это не то же самое, что и a && b. Он работает для (c != EOF) == (c != '\n'), потому что невозможно, чтобы оба этих условия были ложными - что интересно, но это не замена для (i < lim-1) && ....

0

Возможно, ваш код имеет неопределенное поведение. Компиляция под GCC и Clang дает мне подобные предупреждения:

test.cpp:14:31: warning: unsequenced modification and access to 'c' 
     [-Wunsequenced] 
    for (i=0; (i<lim-1) == ((c=getchar()) != EOF) == (c != '\n'); ++i) 

Чтение sequence points in c и c-faq question 3.8 Я не уверен, == точка последовательности, но && есть. Во-вторых, я не думаю, что ваш код делает то, что вы думаете. Если мы возьмем следующий пример:

Он выводит «Истинный». Так что это на самом деле не так. Я рекомендую попытаться избежать написания умного кода и вместо этого придерживаться «if/else» solution, на который вы ссылались.

while(i < lim-1) { 
    c = getchar(); 
    if (c == '\n') 
     lim = 0; /* We haven't encountered breaks yet. */ 
    else if (c == EOF) 
     lim = 0; 
    else 
     s[i++] = c; 
} 
0
// with the use of break statement and no else statements 

for(i=0; i<(lim-1); ++i) 
{ 
    c = getchar(); 
    if('\n' == c) break; 
    if(EOF == c) break; 
    s[i] = c; 
} 
+2

, пожалуйста, расширьте свой ответ, только код-ответы не являются хорошей идеей и труднее понять –