Perché i punti e virgola sono scambiati tra cicli?

49

In molte lingue (un ampio elenco, da C a JavaScript):

  • commas , argomenti separati (ad esempio func(a, b, c) ), mentre
  • punto e virgola ; istruzioni sequenziali separate (ad esempio instruction1; instruction2; instruction3 ).

Quindi, perché questa mappatura è stata invertita nelle stesse lingue per per cicli :

for ( init1, init2; condition; inc1, inc2 )
{
    instruction1;
    instruction2;
}

invece di (ciò che mi sembra più naturale)

for ( init1; init2, condition, inc1; inc2 )
{
    instruction1;
    instruction2;
}

Certo, for è (di solito) non una funzione, ma gli argomenti (cioè init , condition , increment ) si comportano più come argomenti di una funzione che come una sequenza di istruzioni.

È dovuto a ragioni storiche / una convenzione, oppure esiste una buona logica per lo scambio di , e ; nei cicli?

    
posta Piotr Migdal 21.04.2013 - 23:16
fonte

7 risposte

18

So why in the same languages such mapping is reversed for for loops.

Tecnicamente, la mappatura non è "invertita".

  • Le cose separate da virgole non sono parametri. In (almeno) C ++ e Java, possono essere dichiarazioni, quindi non sono nemmeno espressioni.
  • Le cose separate da punto e virgola non sono neanche dichiarazioni (singole).

In realtà ciò che abbiamo qui è un diverso contesto sintattico in cui gli stessi simboli vengono usati in modo diverso. Non stiamo confrontando come con simili, quindi non esiste alcuna mappatura e nessun argomento valido per una mappatura coerente basata sulla coerenza semantica.

Quindi, perché non farlo al contrario?

Penso che le ragioni derivino dal significato "naturale" di , e ; . Nella lingua scritta inglese, un punto e virgola è un'interruzione "più strong" di una virgola e il glifo per il punto e virgola è più visibile di una virgola. Queste due cose si combinano per rendere l'arrangiamento attuale (per me!) Più naturale.

Ma l'unico modo per sapere con certezza perché è stata fatta la scelta della sintassi sarebbe se i progettisti C potessero dirci cosa stavano pensando in ~ 1970. Dubito che abbiano un chiaro ricordo delle decisioni tecniche fatte molto indietro nel tempo.

Is it due to historical reasons / a convention

Non sono a conoscenza di alcun linguaggio prima di C che utilizzava una sintassi simile a C per i cicli "for":

  • Donal Fellows rileva che BCPL e B non avevano un costrutto equivalente.

  • Gli equivalenti FORTRAN, COBOL e Algol-60 (e Pascal) erano meno espressivi e presentavano sintassi che non assomigliavano alla sintassi C "per".

Ma linguaggi come C, C ++ e Java sono arrivati dopo che C ha chiaramente preso in prestito la sintassi "for" da C.

    
risposta data 22.04.2013 - 01:02
fonte
60

Scriviamo loop come:

 for(x = 0; x < 10; x++)

La lingua potrebbe essere stata definita in modo tale che i loop fossero simili a:

 for(x = 0, x < 10, x++)

Tuttavia, pensa allo stesso ciclo implementato usando un ciclo while:

 x = 0;
 while(x < 10)
 {
     x++;
 }

Si noti che x=0 e x++ sono istruzioni, terminate da punto e virgola. Non sono espressioni come quelle che avresti in una chiamata di funzione. I punti e virgola vengono utilizzati per separare le istruzioni e poiché due dei tre elementi di un ciclo for sono istruzioni, questo è ciò che viene utilizzato lì. Un ciclo for è solo una scorciatoia per un ciclo while.

Inoltre, gli argomenti non agiscono come argomenti per una funzione. Il secondo e il terzo vengono ripetutamente valutati. È vero che non sono una sequenza, ma non sono argomenti di funzione.

Inoltre, il fatto che puoi usare virgole per avere più istruzioni nel ciclo for è in realtà qualcosa che puoi fare al di fuori del ciclo for.

x = 0, y= 3;

è una dichiarazione perfettamente valida anche al di fuori di un ciclo for. Tuttavia, non conosco alcun uso pratico al di fuori del ciclo for. Ma il punto è che le virgole sempre suddividono le dichiarazioni; non è una caratteristica speciale del ciclo for.

    
risposta data 21.04.2013 - 23:38
fonte
15

In C e C ++ questo è l'operatore virgola, non solo una virgola.

La grammatica per un ciclo for è qualcosa come

for ([pre-expression]; [terminate-condition]; [increment-expression]) body-expression

Nel caso della tua domanda:

pre-expression -> init1, init2
terminate-condition -> condition
increment-expression -> inc1, inc2

Si noti che l'operatore virgola consente di eseguire più azioni in un'unica istruzione (come la vede il compilatore). Se il tuo suggerimento fosse implementato, ci sarebbe un'ambiguità nella grammatica su quando il programmatore intendeva scrivere un'istruzione virgola-operatore o un separatore.

In breve, ; indica la fine di una dichiarazione. Un ciclo for è una parola chiave seguita da un elenco di istruzioni facoltative circondate da () . L'istruzione virgola-operatore consente l'utilizzo di , in una singola istruzione.

    
risposta data 22.04.2013 - 01:44
fonte
8

Non c'è inversione concettuale.

I punti e virgola in C rappresentano più divisioni maggiori rispetto alle virgole. Separano dichiarazioni e dichiarazioni.

Le principali divisioni nel ciclo for sono che ci sono tre espressioni (o una dichiarazione e due espressioni) e un corpo.

Le virgole che vedi in C for loops non fanno parte della sintassi del ciclo for in particolare. Sono solo manifestazioni dell'operatore virgola.

Le virgole sono i principali separatori tra gli argomenti nelle chiamate di funzione e tra i parametri nelle dichiarazioni di funzione, ma i punti e virgola non vengono utilizzati. Il ciclo for è una sintassi speciale; non ha nulla a che fare con le funzioni o le chiamate di funzione.

    
risposta data 22.04.2013 - 03:45
fonte
2

Forse è qualcosa di specifico per C / C ++, ma pubblico questa risposta, perché la sintassi dei lagnuages che hai descritto è per lo più influenzata dalla sintassi C.

Oltre alle domande a risposta precedente sono vere, da un punto di vista tecnico, questo è anche perché in C (e C ++) la virgola è in realtà un operatore , che puoi anche overload . L'uso di un operatore punto e virgola ( operator;() ) potrebbe rendere più difficile scrivere i compilatori, poiché il punto e virgola è il terminatore di espressioni assiomatiche.

Ciò che rende questo interessante è il fatto che la virgola è ampiamente usata come separatore in tutta la lingua. Sembra che l'operatore virgola sia un'eccezione, utilizzata principalmente per ottenere for -loops con più condizioni di lavoro, quindi qual è l'offerta?

In effetti operator, è costruito per fare la stessa cosa come nelle definizioni, negli elenchi di argomenti e così via: è stato creato per espressioni separate - qualcosa che il costrutto sintattico , non può fare. Può solo separare ciò che è stato definito nello standard.

Tuttavia il punto e virgola non è separato: termina . E questo è anche ciò che ci riporta alla domanda iniziale:

for (int a = 0, float b = 0.0f; a < 100 && b < 100.0f; a++, b += 1.0f)
    printf("%d: %f", a, b);

La virgola separa le espressioni nelle tre parti del ciclo, mentre il punto e virgola termina una parte (inizializzazione, condizione o ripensamento) della definizione del ciclo.

I linguaggi di programmazione più recenti (come C #) potrebbero non consentire di sovraccaricare l'operatore virgola, ma probabilmente mantengono la sintassi, perché modificarla sembra in qualche modo innaturale.

    
risposta data 22.04.2013 - 12:38
fonte
0

Per me sono usati un significato meno simile al loro senso linguistico. Le virgole vengono utilizzate con elenchi e punti e virgola con più parti separate.

In func(a, b, c) abbiamo una lista di argomenti.

instruction1; instruction2; instruction3 è forse una lista ma un elenco di istruzioni separate e indipendenti.

Mentre in for ( init1, init2; condition; inc1, inc2 ) abbiamo tre parti separate: un elenco di inizializzazioni, una condizione e un elenco di espressioni di incremento.

    
risposta data 22.04.2013 - 01:26
fonte
0

Il modo più semplice per vederlo è il seguente:

for(x = 0; x < 10; x++)

è:

for(
x = 0;
x < 10;
x++
)

In altre parole, quelli x = 0 thingy sono in realtà un'istruzione / istruzioni piuttosto che un parametro. Inserisci una dichiarazione lì. Quindi sono separati da punto e virgola.

In effetti non esiste un modo in cui sono separati da una virgola. Quando fai l'ultima volta inserisci cose come x < 10 come parametro? Lo fai se vuoi un computer x < 10 una volta e inserisci il risultato di quell'operazione come parametro. Quindi nel mondo delle virgole si inserisce x < 10 se si desidera passare il valore di x < 0 a una funzione.

Qui si specifica che il programma deve controllare x < 10 ogni volta che viene passato il ciclo. Quindi questa è un'istruzione.

x ++ è sicuramente un'altra istruzione.

Queste sono tutte istruzioni. Quindi sono separati da un punto e virgola.

    
risposta data 22.04.2013 - 06:46
fonte

Leggi altre domande sui tag