2013-04-29 9 views
5

I seguenti due blocchi di codice sono esattamente uguali e ottenere la stessa cosa? Esso mostra la stessa cosa quando ho eseguito il programma, ma mi apprezzerebbe qualche spiegazione rigorosa.È qualcosa come "per (i = 1; i <= 10; printf ("% d n "; i), i ++) valido e UB-free in C?

for(i=1;i<=10;i++) 
{ 
printf("%d\n",i); 
} 

e

for(i=1;i<=10;printf("%d\n",i),i++); 

il for ciclo prevede dichiarazioni C valide come argomenti, doesn vero? Ma anche se ho verificato su StackOverflow che affermazioni come x+=4,y=x*2; sono sicure in quanto la virgola funge da sequenza punti qui, è la stessa verità per la dichiarazione printf("%d\n",i),i++) passata come argomento nel ciclo for sopra?

E se sì, la briga di rispondere alla domanda minore che ne derivano:

  • fa il comma agire come punti di sequenza in un comunicato che coinvolge molti separati da virgola

    chiamate di funzione, come di seguito:

    printf("Enter number\n"),scanf("%d",&number),printf("You entered %d",number);

+4

Sì, ma perché vuoi scrivere codice come questo? (La virgola è il punto di sequenza, purché non sia la virgola all'interno di una chiamata di funzione). – nhahtdh

+0

Sì, è Ok. L'operatore virgola introduce un punto di sequenza. – wildplasser

+0

Fa parte dello standard C .. fammi trovare il riferimento. –

risposta

3

Ciò è perfettamente valido e entrambe le istruzioni sono uguali al compilatore. Per il lettore il secondo è quasi illeggibile, quindi questa è l'unica differenza. Ha molto poco senso usare il secondo formato.

Un punto di sequenza viene introdotto dall'operatore di virgola.

Riferimento:

6.5.17 operatore virgola

Para 2:

L'operando sinistro dell'operatore virgola viene valutata come espressione vuoto; c'è un punto di sequenza tra la sua valutazione e quella dell'operando di destra. Quindi viene valutato l'operando destro ; il risultato ha il suo tipo e value.114)

+0

Quale sarebbe la ragione tecnica per dire che la seguente affermazione è assurda? Int a, b, * ptr, printf ("Hello"), printf ("Howdy"); '? Sarebbe valido se usi '(int a, b, * ptr), printf (" Hello "), printf (" Howdy ");'? –

1

La risposta è nel 6.8.5.3 della C di serie:

1774 La dichiarazione

for (clause-1 ; expression-2 ; expression-3) statement 

si comporta come segue:

1775 L'espressione> expression-2 è l'espressione di controllo che viene valutata prima di ogni esecuzione del corpo del ciclo.

1776 L'espressione expression-3 viene valutata come espressione di vuoto dopo ogni esecuzione del corpo del loop.

1777 Se la clausola 1 è una dichiarazione, l'ambito di tutti gli identificatori che dichiara è il resto della dichiarazione e l'intero ciclo , comprese le altre due espressioni;

1778 viene raggiunto nell'ordine di esecuzione prima della prima valutazione dell'espressione di controllo.

1779 Se clausola-1 è un'espressione, viene calcolata come vuoto espressione prima della prima valutazione del controllo expression.134)

1780 Sia clausola-1 e l'espressione-3 può essere omesso.

1781 Un'espressione omessa-2 viene sostituita da una costante diversa da zero.

C'è un punto di sequenza stabilito tra l'esecuzione dell'istruzione printf e quindi l'incremento di i. L'istruzione printf e i è expression-3 in questo caso, non un condizionale, quindi l'istruzione è valida anche se non la migliore pratica.

+0

Quale sarebbe la ragione tecnica per dire che la seguente affermazione è assurda? Int a, b, * ptr, printf ("Hello"), printf ("Howdy"); '? Sarebbe valido se usi '(int a, b, * ptr), printf (" Hello "), printf (" Howdy ");'? –

+0

@SheerFish: Non è diverso da quello che ho fatto io: 'int a, b, c = 0;' L'operatore virgola funziona allo stesso modo. La differenza nel mio esempio è il compito. Anche se i tuoi esempi non sono molto leggibili. –

+0

Devo metterlo in un'altra domanda? –

Problemi correlati