2015-06-23 5 views
0

Я работаю над прокси-программой linux, и я застрял в этой проблеме. Это код, с которым я борюсь.Почему изменяется значение возвращаемой переменной?

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){ 
    printf("%d\n", n); 
    Rio_writen_w(serverfd, buf, n); 
} 

Эта функция обертка 'Rio_readlineb_w'

ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen) 
{ 
    ssize_t rc; 
    if((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0) 
    printf("Rio_readlineb error"); 
    printf("%d\n", rc); 
    return rc; 
} 

Variable 'гс' означает количество символов, считанных функции rio_readlineb. Используя printf внутри функции wrapper, я проверил, что rc - это точно количество прочитанных символов. Однако переменная «n» верхнего оператора while всегда 1. Я не могу понять, что не так. Считаете ли вы, что возвращаемое значение каким-то образом изменилось?

+0

Избегайте использования оператора присваивания в условиях, так как это является хорошо известная причина многочисленных ошибок. Редко бывает ситуация, когда вам нужно это делать. – Lundin

+0

@ Lundin: Я нахожу это более читаемым, чем 'while (true) ... if() break;'. Однако сравнение должно быть заменено, поэтому присваивание находится справа от оператора сравнения, и назначение должно быть заключено в скобки. – Olaf

+0

@Olaf В качестве альтернативы вы можете добавить дополнительный вызов за пределы цикла, что, возможно, немного странно. 'П = FUNC(); в то время как (n> 0) {... n = func();} 'Нет идеального способа обработки таких циклов, вы столкнетесь с одной плохой практикой или другой. – Lundin

ответ

9

Это проблема приоритета оператора.

while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){ 

должно быть:

while((n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0){ 

В противном случае, вы присваиваете результат сравнения (0 или 1) в n.

1
while(n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0){ 
    printf("%d\n", n); 
    Rio_writen_w(serverfd, buf, n); 
} 

То же самое, как:

while (n = /* assignment has low priority */ 
      (Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0) 
     ) { 
    printf("%d\n", n); 
    Rio_writen_w(serverfd, buf, n); 
} 

Я подозреваю, что вы хотите:

while ((n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0) { 
    printf("%d\n", n); 
    Rio_writen_w(serverfd, buf, n); 
} 
0
n = Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0 

обрабатывается как

n = (Rio_readlineb_w(&rio_client, buf, MAXLINE) > 0) 

, поскольку = имеет более низкий приоритет, чем >, поэтому n получает результат сравнения, который будет либо 0, либо 1. Вы должны явно группе назначение:

(n = Rio_readlineb_w(&rio_client, buf, MAXLINE)) > 0 

как то, как это делается в функции Rio_readlineb_w.

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

a = b && c; 

присваивает результат b && c к a. Если вы хотите присвоить результат b к a и сравните, что c, то вам нужно использовать круглые скобки, чтобы указать, что:

(a = b) && c 
Смежные вопросы