Некалькі ўмоў ў C «для» завесы

I came across this piece of code. I generally use '&&' or '||' to separate multiple conditions in a for loop, but this code uses commas to do that.

Дзіўна, але калі змяніць парадак умоў на выхадзе змяняецца.

#include

int main() {
    int i, j=2;

    for(i=0; j>=0,i<=5; i++)
    {
         printf("%d ", i+j);
         j--;
    }
    return 0;
}

Выхад = 2 2 2 2 2 2

#include

int main(){
    int i, j=2;

    for(i=0; i<=5,j>=0; i++)
    {
         printf("%d ", i+j);
         j--;
    }
    return 0;
}

Выхад = 2 2 2

Можа хто-небудзь растлумачыць прычыну? Здавалася б, праверка толькі апошняе падзеленыя коскамі стану.

22
Дрэнны код. Ты маеш рацыю; некалькі ўмоў павінны быць злучаныя з && або ||.
дададзена аўтар Caleb, крыніца
Пяць адказаў, кожны прымаючы пытанне занадта літаральна і растлумачыць, што робіць коска, а не адзін адказ мяркуючы, што гэта жахліва, жахліва зламаная.
дададзена аўтар Edward Thomson, крыніца

7 адказы

Аператар коскі ацэньвае ўсе аперанды і дае значэнне апошняга. Такім чынам, у асноўным у залежнасці ад таго стану вы пішаце <�моцны> першы, гэта будзе ігнаравацца, а <�моцны> другі адзін толькі будзе значным.

for (i = 0; j >= 0, i <= 5; i++)

Такім чынам, эквівалентна

for (i = 0; i <= 5; i++)

which may or may not be what the author of the code intended, depending on his intents - I hope this is not production code, because if the programmer having written this wanted to express an AND relation between the conditions, then this is incorrect and the && operator should have been used instead.

45
дададзена
@Caleb На самай справе J> = 0 , магчыма, ніколі нават ацаніць, таму што кампілятар можа заўважыць, што яго значэнне ніколі не выкарыстоўваецца, і не мае ніякіх пабочных эфектаў, таму ён можа быць кінуты ў якасці мёртвага кода ...
дададзена аўтар twalberg, крыніца
Важным момантам тут з'яўляецца ТАТ код у пытанне некарэктнае.
дададзена аўтар Caleb, крыніца
Першая ўмова, J> = 0 , вылічаецца, але вынік ніколі не выкарыстоўваецца. Цыкл будзе працягвацца да таго часу, пакуль я не перавышае 5, нават калі J менш 0. знешні выгляд , як цыкл спыніцца J = -1, але гэта не будзе. Цяжка назваць гэта нічога, акрамя зламанай.
дададзена аўтар Caleb, крыніца
Гэта <�я> не </я> быць тое, што задумаў аўтар, бо яна не мае сэнсу. Я не стаў бы давяраць любы код гэтага аўтара.
дададзена аўтар Lee Daniel Crocker, крыніца
@Caleb У якім сэнсе? Я думаю, што я атрымліваю тое, што вы спрабуеце прапанаваць, я проста не ўпэўнены, што ён можа ці павінен быць уключаны ў адказ, як ёсць.
дададзена аўтар user529758, крыніца
Чаму downvote?
дададзена аўтар user529758, крыніца
Ды яго не вытворчасць кода. Я проста пераглядаю свае асновы C і наткнуўся на сайце, які меў некалькі пытанняў множнага выбару, дзе я натыкнуўся на гэта. Дзякуй за адказ.
дададзена аўтар Prateek, крыніца

Of course it is right what you say at the beginning, and C logical operator && and || are what you usually use to "connect" conditions (expressions that can be evaluated as true or false); the comma operator is not a logical operator and its use in that example makes no sense, as explained by other users. You can use it e.g. to "concatenate" statements in the for itself: you can initialize and update j altogether with i; or use the comma operator in other ways

#include 

int main(void) //as std wants
{
  int i, j;

 //init both i and j; condition, we suppose && is the "original"
 //intention; update i and j
  for(i=0, j=2; j>=0 && i<=5; i++, j--)
  {
       printf("%d ", i+j);
  }
  return 0;        
}
6
дададзена

Выраз коскі прымае значэння <�апошняга моцнага /> (самы правага, напрыклад.) Выразы.

So in your first loop, the only controlling expression is i<=5; and j>=0 is ignored.

In the second loop, j>=0 controls the loop, and i<=5 is ignored.


Што тычыцца прычына ... няма ніякіх падстаў. Гэты код проста <�моцны> няправільна . Першая частка косак выразаў робіць нічога акрамя блытайце праграмістаў. Калі сур'ёзны праграміст напісаў гэта, яны павінны быць сорамна за сябе і мець іх клавіятура ануляваны.

5
дададзена

Wikipedia tells what comma operator does:

«У C і C ++ мовы праграмавання, аператар коскі (прадстаўленае маркерам , ) уяўляе сабой бінарны аператар, які вылічае першы аперанд і адкідвае вынік, а затым ацэньвае другі аперанд і вяртае гэта значэнне (і тып) «.

3
дададзена
@Caleb, шчыра кажучы, я не лічу, што пытанне пытаецца, чаму. Таму што ён кажа: "Дзіўна, але калі я змяніць парадак умоў на выхадзе мяняецца». Таму цытую адказвае на яго.
дададзена аўтар tafa, крыніца
-1 Цытаванне з Вікіпедыі не дае адказ на пытанне, які не тое, што робіць коску рабіць, а чаму ён выкарыстоўваецца тут.
дададзена аўтар Caleb, крыніца

Не выкарыстоўвайце гэты код; той, хто напісаў гэта, відавочна, мае фундаментальнае неразуменне мовы і не заслугоўвае даверу. выраз:

j >= 0, i <= 5

evaluates "j >= 0", then throws it away and does nothing with it. Then it evaluates "i <= 5" and uses that, and only that, as the condition for ending the loop. The comma operator can be used meaningfully in a loop condition when the left operand has side effects; you'll often see things like:

for (i = 0, j = 0; i < 10; ++i, ++j) . . .

у якім выкарыстоўваецца коска красціся ў дадатковых заявах ініцыялізацыі і прырашчэння. Але код, паказаны не робіць гэтага, або што-небудзь яшчэ сэнс.

3
дададзена

There is an operator in C called the comma operator. It executes each expression in order and returns the value of the last statement. It's also a sequence point, meaning each expression is guaranteed to execute in completely and in order before the next expression in the series executes, similar to && or ||.

2
дададзена
@EricPostpischil Прабачце, выраз. Sheesh.
дададзена аўтар Robert S. Barnes, крыніца
Што робіць яго бескарысным у дадзеным выпадку - ён першая праверка стану не робіць нічога карыснага.
дададзена аўтар Caleb, крыніца

Завяршаючы адказ Крокер, будзь асцярожным ++ або - аператары, ці я не ведаю, можа быць, і іншыя аператары. Яны могуць паўплываць на цыкл. напрыклад, я бачыў код, падобны гэтаму ў курсе:

for(int i=0; i++*i<-1, i<3; printf(" %d", i));

Вынік будзе як $ 1 2 $. Такім чынам, першы аператар закрануў цыкл у той час як вынік наступнага мноства нулёў.

for(int i=0; i<3; printf(" %d", i));
0
дададзена