Come funziona se / else funziona internamente in tutti i linguaggi di programmazione? [chiuso]

2
if(true/false){
     //if condition is true 
}else {
     // if condition is false
}

Tutti conoscono la struttura di if-else . Ma cos'è effettivamente if ? È un metodo di classe, un metodo statico o una parola chiave? Sono un po 'confuso su questo.

    
posta Dilip Kumar Chaudhary 15.02.2013 - 07:51
fonte

8 risposte

36

Mi sembra che tu stia facendo due diverse domande:

  1. In che modo if else funziona internamente?
  2. Quale if è in termini di programmazione ad alto livello ?

Questa risposta è per la domanda 1. Per la domanda 2 vedi altre risposte. La risposta di Gustav Bertram sembra molto chiara.

Prima che il codice venga eseguito, deve essere tradotto in codice macchina . La traduzione viene eseguita da un compilatore (come un compilatore C) o da un interpreter (come interprete Ruby) o una macchina virtuale (come con Java).

Le strutture di controllo come if-else sono tradotte in un modello di istruzioni di codice macchina. Il modello effettivo dipende dal computer di destinazione e dal compilatore / interprete / macchina virtuale. Una struttura if-else come

if (x >= y) {
    // main branch
} else {
    // else branch
}

potrebbe essere tradotto in codice (qui una sorta di pseudo- assemblaggio ) come

cmp (r1),(r2)    ;compare words at memory addresses pointed by registers r1 and r2
blt else         ;jump to else-part if (r1) is less than (r2)
   ...           ;insert the main branch code here
bra end_if       ;jump to end_if
else:
   ...           ;insert the else branch code here
end_if:

Il codice macchina attuale consiste solo di dati binari ma è strutturalmente simile al codice assembly.

    
risposta data 15.02.2013 - 08:54
fonte
17

Questa risposta riguarda linguaggi come C, C ++, Java, PHP e Javascript. Esistono altri linguaggi di programmazione che funzionano in modo diverso.

if è una parola chiave e else è una parola chiave . Quando vengono utilizzati nel codice, if e else formano insieme una istruzione del flusso di controllo .

I metodi di classe o i metodi statici sono sempre funzioni o procedure allegati a una classe . "Metodo" significa la stessa cosa di "funzione" o "procedura", ma di una classe.

if else non è una funzione, ma può apparire all'interno di una funzione.

# This part is a function, and *could* be a class method or static method
function hello($name)
{

  # This part is a control flow statement, and can be *inside* a function
  if($name=='Peter')
  {
    #The next line is one statement
    echo 'Hello Pete!";
  } else {
    echo 'Hello $name!";
  }

}

Questi sono esempi di parole chiave: if , else , while , for , case , continue , function , return , class , public , private , protected , static , new .

Ogni linguaggio di programmazione ha parole chiave diverse. Quali sono le tue parole chiave e come funzionano in modo diverso in ogni lingua.

Parole chiave ( if , else ), operatori ( == , < , != ), variabili ( $name ), stringhe letterali ( 'Peter' ), funzioni ( echo , hello ) lavorano tutti insieme per rendere dichiarazioni . Le istruzioni fanno all la maggior parte di del lavoro e sono raggruppate in funzioni o metodi (di solito).

Penso che dovresti provare Code Academy . Insegna programmazione di base e potrebbe aiutarti a comprendere le parti delle istruzioni di programmazione.

Dovresti anche cercare di trovare un libro che insegna il tuo linguaggio di programmazione. Tali libri dovrebbero spiegare anche le parti delle affermazioni. Se un libro non è chiaro, provane un altro.

    
risposta data 15.02.2013 - 08:55
fonte
7

In realtà può essere diverse cose. In linguaggi imperativi come C ++ o Java, è un tipo di istruzione. Nei linguaggi puramente orientati agli oggetti come Smalltalk è un metodo di istanza di booleano. Nei linguaggi funzionali puri è una funzione.

Ma in tutte le lingue è un primitivo . Alcune forme di condizionale devono essere incorporate nella lingua. Potrebbe essere un tipo leggermente diverso di condizionale (ad esempio cond in Lisp), ma è necessario crearne uno.

    
risposta data 15.02.2013 - 08:20
fonte
2

Come gli altri hanno già spiegato, il flusso di controllo viene solitamente implementato con istruzioni di ramificazione.

Ma i salti non sono sempre necessari. In alcuni ISA esiste una cosiddetta "esecuzione condizionale" : le istruzioni verranno aggirate se sono contrassegnate come condizionali e una bandiera dopo un'operazione di confronto precedente non è impostata. I salti possono essere imprevedibili e possono danneggiare il gasdotto, mentre una breve sequenza di istruzioni condizionali potrebbe essere molto più economica.

Un'altra forma interessante di flusso di controllo di basso livello è un cosiddetto "looping zero-overhead", comune in molti moderni processori DSP (ad esempio, in esagono ).

    
risposta data 15.02.2013 - 10:39
fonte
2

Internamente su architettura x86 / 64 se / else / then viene generato con CMP mnemonico interno

.

Confronta i risultati e imposta il registro EFLAGS con i flag appropriati (zero, overflow , eccetera.).

Internamente se gli argomenti sono uguali il loro prodotto meno è zero. Per esempio if (a == b) dove a = 10, b = 10 . Il processore ha 10-10 = 0 . Una volta che il risultato è zero, ZF (Zero Flag) è impostato.

cmp a, b
jz equal
jnz notEqual

JZ - Salta se Zero è uguale a JE e JNZ (Non zero) è uguale a JNE (Non uguale). Sono uguali e JE e JNE esistono solo per la leggibilità.

  • JL sta per - Jump if Less
  • JG sta per - Jump if Greater
risposta data 15.02.2013 - 12:37
fonte
1

Una volta che arrivi al metal, è una frase di salto / salto - fondamentalmente un goto di fantasia. I linguaggi di livello superiore dispongono di strutture di controllo che consentono di implementare attività di basso livello comuni in modo chiaro e comprensibile. Ma quando ci si abbassa, è un mucchio di registri, salti e spunti dentro e fuori dalla memoria.

    
risposta data 15.02.2013 - 08:07
fonte
1

Dipende davvero dalla lingua, ovviamente. Dato che stai dando un esempio di pseudo-C, mi limiterò a come funziona nella maggior parte dei linguaggi di tipo C.

Alla fine, un programma deve essere tradotto in codice macchina, quindi dobbiamo prima parlare del codice macchina.

Iniziamo con un computer molto vecchio (immaginario, ma è l'idea) che è in grado di eseguire solo queste operazioni:

  • 1: inserisci il valore inserito dall'operatore nel registro A
  • 2: inserisce il valore inserito dall'operatore nel registro B
  • 3: inserisci il seguente valore nel registro C
  • 4: inserisci il contenuto di C in A
  • 5: inserisci il contenuto di A in C
  • 6: aggiungi A e B e metti il risultato nel registro A
  • 7: sottrai A e B e ...
  • 8: moltiplica A e B ...
  • 9: divide A e B e metti il quoziente nel registro A
  • 10: stampa il valore che si trova nel registro A su un pezzetto di carta

Quindi, il seguente "programma" salvato su, diciamo, una scheda perforata:

  • istruzione 1: 1
  • istruzione 2: 2
  • istruzione 3: 6
  • istruzione 4: 10

Mettere un numero in A, poi un altro in B, aggiungerli e inserire il risultato in A, quindi stamparlo su un foglio di carta. Il punto è che i computer molto vecchi non avevano alcuna possibilità di esecuzione condizionale o loop. Un programma non era altro che eseguire questo calcolo, quindi questo, poi questo e così uno. Erano poco più di una calcolatrice a cui hai dato un elenco di calcoli da eseguire.

Questo divenne presto un problema: molto spesso, vogliamo che un calcolo non venga eseguito in alcune situazioni; per esempio, se il valore corrente è 0, non voglio dividerlo con un altro numero! I computer dovevano essere migliorati, e quello era un grande e (un po ') miglioramento complicato: ora il tuo computer deve essere consapevole di dove si trova nel flusso del programma corrente e agire su di esso; solo leggere l'istruzione corrente e andare al prossimo non è sufficiente.

Ciò significa che devi aggiungere le seguenti istruzioni per andare avanti:

  • 11: vai all'istruzione #n, n è il valore nella prossima "istruzione"

Molto bene, ora puoi saltare le istruzioni se necessario; per esempio, puoi saltare l'istruzione della divisione se non vuoi eseguirla. Beh, in realtà, salteremo sempre, quindi questa è una dichiarazione piuttosto inutile. Riscriviamolo in questo modo:

  • 11: vai all'istruzione #n, solo se il valore in A è 0

Sì, una "istruzione if", ecco dove viene effettivamente implementata: in un'istruzione macchina. È molto basso e limitato, ma in realtà non è un problema perché puoi fare tutto ciò che vuoi con esso. È difficile da usare, ma i linguaggi di alto livello lo gestiranno per te. Nota che è davvero molto potente: puoi anche implementare dei loop (i loop sono un salto indietro piuttosto che in avanti).

Scriviamo il seguente programma: leggi due numeri, sottraili. Se il risultato non è 0, leggere un terzo numero, dividerlo per il risultato e stampare il risultato complessivo.

  • istruzione 1: 1
  • istruzione 2: 2
  • istruzione 3: 7
  • istruzione 4: 11
  • istruzione 5: 7
  • istruzione 6: 2
  • istruzione 7: 10

Beh, è piuttosto noioso scrivere programmi in questo modo, così sono stati inventati i linguaggi di assemblaggio:

  • READ-A
  • READ-B
  • SUB
  • JMP-IF-ZERO .endif
  • DIVIDE .endif:
  • Stampa

Inoltre, poiché l'assembly è noioso e soggetto a errori, abbiamo inventato linguaggi di alto livello come C. Il seguente pseudo-C programma è equivalente come sopra:

a = read();
b = read();
a = a - b;

if (a != 0) {
   b = read();
   a = a / b;
}

print(a);

Il modo in cui if viene tradotto dal tuo compilatore nelle istruzioni della macchina: la condizione dopo che la parola chiave if viene trasformata come un test il cui risultato è memorizzato in A, e il numero dell'istruzione dove saltare è determinato sulla base dove si chiude la parentesi.

    
risposta data 17.02.2013 - 19:55
fonte
0

Questo di fatto dipende dalla lingua di cui stai parlando.

Qui ci sono risposte eccellenti su come if e else sono parole chiave e forma istruzioni flusso di controllo perché quando vengono compilate in una sequenza di istruzioni, queste istruzioni controllano il flusso di esecuzione della sequenza di istruzioni, che naturalmente è sequenziale per impostazione predefinita, ma può avere salti per consentire che l'esecuzione dipenda dallo stato corrente . E questo è certamente vero per un intero insieme di lingue.

Ma ci sono un paio di linguaggi, come Smalltalk e Lisp (probabilmente gli esempi più importanti), che implementano effettivamente il loro equivalente di istruzioni di controllo di flusso come metodi o macro rispettivamente, su un meccanismo molto semplice per esecuzione condizionale / salti.

    
risposta data 16.02.2013 - 14:31
fonte

Leggi altre domande sui tag