Cercando di ottenere i fondamenti su da dove viene il termine " vuoto " e perché si chiama vuoto. L'intenzione della domanda è di aiutare qualcuno che non ha esperienza in C, e improvvisamente sta guardando una base di codice basata su C.
Cercando di ottenere i fondamenti su da dove viene il termine " vuoto " e perché si chiama vuoto. L'intenzione della domanda è di aiutare qualcuno che non ha esperienza in C, e improvvisamente sta guardando una base di codice basata su C.
Risposte:
Fondamentalmente significa "niente" o "nessun tipo"
Esistono 3 modi base per usare il vuoto:
Argomento int myFunc(void)
della funzione : - la funzione non accetta nulla.
Valore restituito void myFunc(int)
dalla funzione : - la funzione non restituisce nulla
Puntatore di dati generico: void* data
- 'dati' è un puntatore a dati di tipo sconosciuto e non può essere differito
Nota: l' void
in un argomento di funzione è opzionale in C ++, quindi int myFunc()
è esattamente la stessa int myFunc(void)
, e si lascia completamente in C #. È sempre richiesto per un valore di ritorno.
L'ho sempre considerato assente . Ecco quattro casi in linguaggio C che corrispondono a questo uso di assenti
R f(void)
- I parametri di funzione sono assentivoid f(P)
- Il valore di ritorno è assentevoid *p
- Il tipo di ciò che viene indicato è assente(void) p
- L'uso del valore è assenteAltri discendenti del C lo usano per altre cose. Il D
linguaggio di programmazione lo utilizza per i casi in cui un inizializzatore è assente
T t = void;
- il valore di inizializzazione è assente(void)p
? Non ho capito bene cosa intendevi per "utilizzo del valore assente".
(void) var;
, ho trovato risposte dettagliate su stackoverflow.com/q/21045615 .
Esistono due modi per utilizzare void:
void foo(void);
o
void *bar(void*);
Il primo indica che non viene passato alcun argomento o che non viene restituito alcun argomento.
Il secondo dice al compilatore che non esiste alcun tipo associato ai dati, il che significa che non è possibile utilizzare i dati a cui punta fino a quando non viene trasmesso a un tipo noto.
Ad esempio, vedrai molto void*
usato quando hai un'interfaccia che chiama una funzione i cui parametri non possono essere conosciuti in anticipo.
Ad esempio, nel kernel Linux durante il differimento del lavoro imposterai una funzione da eseguire in un secondo momento dandogli un puntatore alla funzione da eseguire e un puntatore ai dati da passare alla funzione:
struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data = somedata;
} deferred_work;
Quindi un thread del kernel passa sopra un elenco di lavori differiti e quando arriva a questo nodo esegue efficacemente:
bar(somedata);
Quindi nel bar hai:
void bar(void* mydata) {
int *data = mydata;
/* do something with data */;
}
Significa "nessun valore". Si utilizza void
per indicare che una funzione non restituisce un valore o che non ha parametri o entrambi. Abbastanza coerente con gli usi tipici della parola void in inglese.
Indica l'assenza di un valore di ritorno in una funzione.
Alcune lingue hanno due tipi di subroutine: procedure e funzioni. Le procedure sono solo una sequenza di operazioni, mentre una funzione è una sequenza di operazioni che restituisce un risultato.
In C e suoi derivati, la differenza tra i due non è esplicita. Tutto è sostanzialmente una funzione. la void
parola chiave indica che non è una funzione "effettiva", poiché non restituisce un valore.
Pensa al vuoto come alla "struttura vuota". Lasciatemi spiegare.
Ogni funzione accetta una sequenza di parametri, in cui ogni parametro ha un tipo. In effetti, potremmo impacchettare i parametri in una struttura, con gli slot della struttura corrispondenti ai parametri. Questo rende ogni funzione ha esattamente un argomento. Allo stesso modo, le funzioni producono un risultato, che ha un tipo. Potrebbe essere un valore booleano, oppure potrebbe essere float, oppure potrebbe essere una struttura, contenente un insieme arbitrario di altri valori tipizzati. Se vogliamo un linguaggio che abbia più valori di ritorno, è facile insistere sul fatto che siano impacchettati in una struttura. In effetti, potremmo sempre insistere sul fatto che una funzione ha restituito una struttura. Ora ogni funzione accetta esattamente un argomento e produce esattamente un valore.
Ora, cosa succede quando ho bisogno di una funzione che produce un valore "no"? Bene, considera cosa ottengo quando creo una struttura con 3 slot: contiene 3 valori. Quando ho 2 slot, contiene due valori. Quando ha uno slot, un valore. E quando ha zero slot, contiene ... uh, zero valori o "nessun" valore ". Quindi, posso pensare a una funzione che restituisce il vuoto come restituire una struttura che non contiene valori. Puoi persino decidere che" vuoto " è solo un sinonimo del tipo rappresentato dalla struttura vuota, piuttosto che una parola chiave nella lingua (forse è solo un tipo predefinito :)
Allo stesso modo, posso pensare a una funzione che non richiede valori come accettare una struttura vuota, ad esempio "vuoto".
Posso persino implementare il mio linguaggio di programmazione in questo modo. Passare un valore vuoto occupa zero byte, quindi passare valori vuoti è solo un caso speciale di passaggio di altri valori di dimensioni arbitrarie. Ciò semplifica al compilatore il trattamento del risultato o dell'argomento "vuoto". Probabilmente si desidera una funzione di lingua che può eliminare un risultato di funzione; in C, se chiamate la funzione risultato non nulla foo nella seguente istruzione: foo (...); il compilatore sa che foo produce un risultato e semplicemente lo ignora. Se void è un valore, questo funziona perfettamente e ora le "procedure" (che sono solo un aggettivo per una funzione con risultato vuoto) sono solo banali casi speciali di funzioni generali.
Void * è un po 'più divertente. Non penso che i designer C abbiano pensato al vuoto nel modo sopra; hanno appena creato una parola chiave. Quella parola chiave era disponibile quando qualcuno aveva bisogno di un punto a un tipo arbitrario, quindi annulla * come il linguaggio in C. Funziona piuttosto bene se interpreti il vuoto come una struttura vuota. Un puntatore void * è l'indirizzo di un luogo in cui è stata posizionata quella struttura vuota.
Lancia da void * a T * per altri tipi T, risolvendo anche questa prospettiva. I lanci di puntatori sono un trucco completo che funziona sulle architetture più comuni per trarre vantaggio dal fatto che se un composto di tipo T ha un elemento con sottotipo S posizionato fisicamente all'inizio di T nel suo layout di archiviazione, quindi getta S * in T * e viceversa l'utilizzo dello stesso indirizzo fisico della macchina tende a risolversi, poiché la maggior parte dei puntatori di macchine ha una singola rappresentazione. Sostituendo il tipo S con il tipo void si ottiene esattamente lo stesso effetto, e quindi si esegue il casting su / da void *.
Il linguaggio di programmazione PARLANSE implementa le idee sopra abbastanza da vicino. Abbiamo preso in giro il suo design e non abbiamo prestato molta attenzione al "vuoto" come tipo di ritorno e quindi abbiamo parole chiave linguistiche per la procedura. È principalmente solo una semplice modifica della sintassi, ma è una delle cose a cui non ti aggiri una volta ottenuto un codice di lavoro di grandi dimensioni in una lingua.
In c # useresti la parola chiave void per indicare che un metodo non restituisce un valore:
public void DoSomeWork()
{
//some work
}
Tre casi d'uso per nulla:
Firme delle funzioni. void foo(int bar)
non restituisce un valore. int bar(void)
non prende alcun parametro, ma questo è di solito espressa con lista di argomenti vuota: int bar()
. L'uso della parola chiave void qui corrisponde al suo significato in inglese.
Puntatore di tipo top generico void *
che punta a dati non specificati e non può essere rinviato. Qui il significato di vuoto è diverso dagli altri significati di vuoto: tipo universale contro nessun tipo.
In cast come (void) new Foo(this)
per indicare che il valore di ritorno viene deliberatamente gettato via. Qui l'utilizzo della parola chiave corrisponde anche al suo significato in inglese.
I casi 1 e 2 erano già coperti da @Gerald ma il caso 3 non è stato ancora affrontato.
Se stai spiegando il concetto a un principiante, potrebbe essere utile usare un'analogia. L'uso del vuoto in tutti questi casi ha un significato analogo a una pagina di un libro che ha le seguenti parole: "Questa pagina è stata lasciata intenzionalmente vuota". Serve a differenziare il compilatore tra qualcosa che dovrebbe essere contrassegnato come errore, rispetto a un tipo che deve essere lasciato intenzionalmente in bianco perché è il comportamento desiderato.
Appare sempre nel codice in cui normalmente ti aspetteresti di visualizzare un tipo, ad esempio un tipo restituito o un tipo di puntatore. Questo è il motivo per cui in C #, il vuoto viene mappato su un tipo CLR effettivo, System.Void perché è un tipo in sé.
Alcuni linguaggi di programmazione non hanno mai sviluppato il concetto di vuoto, proprio come alcune culture umane non hanno mai inventato il concetto del numero zero. Void rappresenta lo stesso progresso in un linguaggio di programmazione come il concetto di zero rappresenta per il linguaggio umano.
Significa "nessun valore". Usa void per indicare che una funzione non restituisce un valore o che non ha parametri o entrambi. È molto coerente con gli usi tipici della parola void in inglese.
Void non deve essere confuso con null. Null significa per la variabile il cui indirizzo è nello stack, il valore sull'heap per quell'indirizzo è vuoto.
Void viene utilizzato solo nelle firme del metodo. Per i tipi restituiti significa che il metodo non restituirà nulla al codice chiamante. Per i parametri significa che nessun parametro viene passato al metodo
per esempio
void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}
In C # possiamo omettere il vuoto per i parametri e possiamo scrivere il codice sopra come:
void MethodThatReturnsAndTakesVoid()
{
// Method body
}
Void non deve essere confuso con null. Null significa per la variabile il cui indirizzo è nello stack, il valore sull'heap per quell'indirizzo è vuoto.
void indica che non verrà restituito alcun valore dalla funzione o dal metodo
Vuoto significa che non è necessario alcun valore nel tipo restituito da una funzione in tutte e tre le lingue.