2010-10-03 17 views
5

Nonostante il cattivo stile, è legale C avere un ciclo for con bretelle all'interno dei parents? Come questo:È per ({istruzioni;}; condizione; {istruzioni;}) legale C?

char *a = "a "; 
char *b = "b "; 

for ({ int aComesFirst = 1; 
     char *first = a; 
     char *second = b; 
     }; 
     aComesFirst >= 0; 
     { aComesFirst--; 
     swap(first, second); 
     }) 
{ 
    printf("%s%s\n", first, second); 
} 

Se qualcosa del genere fosse possibile, dovrei mettere un punto e virgola dopo i primi vicini bretelle, o vorrei che aggiungere una dichiarazione vuota?

Mi rendo conto che è stilisticamente preferibile spostare le dichiarazioni char* all'esterno del ciclo for e swap alla fine dell'interno del ciclo. Ma lo stile non è il punto di questa domanda, voglio solo sapere se mettere le parentesi all'interno del paren è possibile.

+0

Immagino che quell'orrenda cosa in realtà compili? – naiad

+0

No, non è così. Questo è solo un esempio della forma di risposta che sto cercando. – AlcubierreDrive

+0

Correlati: http://stackoverflow.com/questions/3348766/how-to-initialize-several-variables-in-a-for-loop-in-c –

risposta

9

Ho risposto prima ... questo può facilmente essere legale in C o C++ con l'aggiunta di un struct tipo locale. Di solito è in stile povero, però.

char *a = "a "; 
char *b = "b "; 

for (struct loopy { 
     int aComesFirst; 
     char *first; 
     char *second; 
     } l = { 1, a, b }; /* define, initialize structure object */ 

     l.aComesFirst >= 0; /* loop condition */ 

     l.aComesFirst--, /* loop advance */ 
     swap(l.first, l.second) 
    ) 
{ 
    printf("%s%s\n", l.first, l.second); 
} 
+1

'struct loopy' Ah! +1 ama il tag; -1 Arrrggghhhh; risultato +0 – pmg

+0

++ per l'hacking del loop in realtà funzionante; l'unica risposta diretta alla mia domanda. E sì, è elegante come il fondo della campana. – AlcubierreDrive

+0

Ci sono probabilmente dei compilatori che permetteranno di omettere 'loopy' e' l' per dichiarare un oggetto anonimo di tipo anonimo, così puoi far finta che non esista. – Potatoswatter

6

No, non è legale, ma è possibile utilizzare le virgole per arrivare a metà strada:

for (int a = 1, b = 2; a < 10; ++a, ++b) 

Non è possibile dichiarare più variabili di tipi diversi, e non è possibile utilizzare le strutture di controllo nel corso dell'ultimo un po ', ma è abbastanza buono il più delle volte.

Se non lo sapeva, la virgola utilizzato non v'è una certa sintassi speciale che può essere utilizzato solo in for loop, è un generale operator che può essere utilizzato ovunque per valutare l'operando sinistro, seguito dal operando di destra, e restituire il risultato dell'espressione corretta, ovvero a, b == b e a, b, c == c e così via.

+0

Grazie! Accetterò la tua risposta tra qualche minuto se è ancora il migliore. – AlcubierreDrive

+0

... e, francamente, l'equivalente struttura 'while' sarà più chiara comunque.Se sei determinato a ottenere un ambito limitato, usa semplicemente un blocco '{}' in posizione libera attorno al codice di inizializzazione-n-while-loop. – dmckee

3

No, non è legale. Se fosse legale, il codice non funzionerebbe comunque perché c ha un ambito a livello di blocco, quindi non avresti accesso ad una delle variabili definite nelle parentesi.

+2

Buon punto sull'ambito del livello del blocco. – AlcubierreDrive

2

Questo non è legale, ma questo è:

for(i = 0, j = 10; i < 10; i++, j--) 
{ 
    // .. 
} 

See: the comma operator

+0

++ per il collegamento a "operatore virgola". Non sapevo che la virgola fosse un operatore di prima classe e così utile. – AlcubierreDrive

0

The Standard dice (6.8.5.3/1)

per (clausola-1; espr-2; espr-3) dichiarazione

sono abbastanza sicuro né expr-2 o expr-3 può essere sostituito da qualcosa che non è un'espressione (un blocco non è un'espressione), e sono abbastanza sicuro che anche clause-1 non può essere sostituito da una dichiarazione.

+0

+1 per la citazione pertinente e per contrastare chiunque fosse l'idiota downvoting. –

1

Si sta utilizzando lo gcc con le espressioni di istruzione? http://tigcc.ticalc.org/doc/gnuexts.html#SEC63 Forse questo renderà funzionante quel tipo di codice. eccetto che è (int i = { stmts; }; { stmts; bool}; { ... })

+0

++ Grazie per avermi mostrato l'estensione di Express di istruzioni. – AlcubierreDrive