2015-11-16 1 views
-1

Это будет первый вопрос, который я публикую здесь, пожалуйста, сообщите мне, если что-то не так.Странное поведение с логическим и оператором в цикле while

Так я получаю этот кусок кода C:

#include <string.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 

int main(int argc, char const* argv[]) { 
    char array[3][50] = { 
     "theoretical computer science", 
     "programming puzzles and code golf", 
     "ebooks" 
    }; 
    int randIdx = 0; 
    srand(time(NULL)); 

    int i; 
    for (i=0; i<10; i++) { 
     // discard everything longer than 27 
     while((randIdx = rand() % 3) && (strlen(array[randIdx]) >= 27)); 

     printf("outside while: randIdx = [%d]\tstrlen = [%ld]\n", 
       randIdx, strlen(array[randIdx])); 
    } 

} 

Since the order of the logical and operator is left to right, я надеялся, что пустое время цикла будет иметь возможность отказаться от первого и второго элемента массива. Тем не менее, выход программы (петельные 10 раз) выглядит следующим образом:

outside while: randIdx = [2] strlen = [6] 
outside while: randIdx = [0] strlen = [28] 
outside while: randIdx = [0] strlen = [28] 
outside while: randIdx = [0] strlen = [28] 
outside while: randIdx = [2] strlen = [6] 
outside while: randIdx = [2] strlen = [6] 
outside while: randIdx = [2] strlen = [6] 
outside while: randIdx = [2] strlen = [6] 
outside while: randIdx = [0] strlen = [28] 
outside while: randIdx = [0] strlen = [28] 

Любая идея, почему randIdx = [0] strlen = [28] может избежать время цикла?

+3

Возможно, точка с запятой после вашего 'while' цикла есть что-то делать это. –

+0

Вы спрашиваете, почему while цикл прекращается, когда условие ложно ....... может быть потому, что 'strlen = [28]' dosent удовлетворяют второму условию 'And'' strlen (array [randIdx])> = 27'. – wrangler

+0

@wrangler - Вы правы, я допустил ошибку и не понял: (randIdx = rand()% 3) 'равно' (randIdx = rand()% 3)! = 0'. Пустое тело было предназначено пропустить элемент randIdx, который указывает на элементы массива дольше 27. – user224234

ответ

0

Это потому, что инструкция while петли, пока условие является правдивым. В случае randIdx == 0 & strlen(array[randIdx]) < 27 выражение равно false (0), а цикл while остановлен.

Итак, если вы хотите, чтобы только randIdx значения, такие, что randIdx != 0и что strlen(array[randIdx]) < 28, вы можете полностью изменить логику и использовать логическое ИЛИ вместо:

while(!(randIdx = rand() % 3) || (strlen(array[randIdx]) >= 27)); 

Это будет продолжать генерировать новые случайные значения до тех пор, пока randIdx составляет 0 ИЛИ длина => 27.

Фактически, только randIdx = [2] strlen = [6] будет проходить.

+0

Также цикл while не имеет тела, поэтому он ничего не делает, кроме изменения значения 'randIdx'. –

+0

@ JonnyHenly - Я подозреваю, что это намерение – Amit

+0

Спасибо! Я заметил ошибку, которую я сделал в коде сразу после того, как я разместил вопрос. '(randIdx = rand()% 3)' равно '(randIdx = rand()% 3)! = 0'. что я не собираюсь здесь делать. – user224234

0
for (i=0; i<10; i++) 
    { 
     // discard everything longer than 27 
     while((randIdx = rand() % 3) && (strlen(array[randIdx]) < 27)) 
     { 
      printf("outside while: randIdx = [%d]\tstrlen = [%ld]\n", randIdx, strlen(array[randIdx])); 
     } 
    } 

Возможно, вы можете изменить свой код.

0

У вас есть точка с запятой (;), непосредственно соответствующая вашей петле while. Создание цикла while не делает ничего, кроме изменения значения randIdx. Вы должны изменить свой код:

for (i=0; i<10; i++) { 

    // discard everything longer than 27 
    while((randIdx = rand() % 3) && (strlen(array[randIdx]) >= 27)) { 
     printf("outside while: randIdx = [%d]\tstrlen = [%ld]\n", 
      randIdx, strlen(array[randIdx])); 
    } 

} 
0

время ((randIdx = рандов()% 3) & & (STRLEN (массив [randIdx])> = 27));

В этом случае randIdx = [0] strlen = [28], если проверить состояние внутри цикла в то время как то randIDX равно 0. Что означает, в то время как (0 & & 1) ----> Здесь 1 возвращается для STRLEN (массив [randIdx ]) = 28, которое больше, чем 27.

поэтому я считаю, что это отвечает на вопрос

почему randIdx = [0] = StrLen [28] может избежать время цикла?

1

Я думаю, что это один из тех случаев, когда вы на самом деле хотите использовать оператор запятой:

while (randIdx = rand() % 3 , strlen(array[randIdx]) >= 27)) 
    ; 

для того, чтобы как выполнить задание и игнорировать его результат.

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

Это также хорошая идея, чтобы сделать намеренно пустые петли выглядят намеренно, либо точка с запятой по своей линии, или, будучи еще более явным:

while (randIdx = rand() % 3 , strlen(array[randIdx]) >= 27)) 
{ 
    /* Empty loop */ 
}