Wat betekent void in C, C++ en C#?

Op zoek naar de grondbeginselen van waar de term “void” vandaan komt en waarom deze leeg wordt genoemd. De bedoeling van de vraag is om iemand te helpen die geen C-ervaring heeft en plotseling naar een op C gebaseerde codebase kijkt.


Antwoord 1, autoriteit 100%

In principe betekent het “niets” of “geen type”

Er zijn 3 basismanieren waarop void wordt gebruikt:

  1. Functieargument: int myFunc(void)
    — de functie neemt niets.

  2. Functieretourwaarde: void myFunc(int)
    — de functie geeft niets terug

  3. Algemene datapointer: void* data
    — ‘data’ is een verwijzing naar gegevens van een onbekend type, en kan niet worden verwijderd

Opmerking: de voidin een functieargument is optioneel in C++, dus int myFunc()is precies hetzelfde als int myFunc(void), en het is volledig weggelaten in C#. Het is altijd vereist voor een retourwaarde.


Antwoord 2, autoriteit 15%

Ik heb het altijd opgevat als afwezig. Hier zijn vier gevallen in de C-taal die overeenkomen met dit gebruik van afwezig

  • R f(void)– Functieparameters zijn afwezig
  • void f(P)– Retourwaarde is afwezig
  • void *p– Het type waarnaar wordt verwezen is afwezig
  • (void) p– Gebruik van waarde is afwezig

Andere C-afstammelingen gebruiken het voor andere dingen. De programmeertaal Dgebruikt het voor gevallen waarin een initializer afwezig

is

  • T t = void;– initialisatiewaarde is afwezig

Antwoord 3, autoriteit 6%

Er zijn twee manieren om void te gebruiken:

void foo(void);

of

void *bar(void*);

De eerste geeft aan dat er geen argument wordt doorgegeven of dat er geen argument wordt geretourneerd.

De tweede vertelt de compiler dat er geen type is gekoppeld aan de gegevens, wat in feite betekent dat u geen gebruik kunt maken van de gegevens waarnaar wordt verwezen totdat deze naar een bekend type zijn gegoten.

Je zult bijvoorbeeld zien dat void*veel wordt gebruikt als je een interface hebt die een functie aanroept waarvan de parameters niet van tevoren bekend kunnen zijn.

Bij het uitstellen van werk in de Linux-kernel bijvoorbeeld, stelt u een functie in die op een later tijdstip moet worden uitgevoerd door deze een verwijzing te geven naar de uit te voeren functie en een verwijzing naar de gegevens die aan de functie moeten worden doorgegeven:

struct _deferred_work {
sruct list_head mylist;
.worker_func = bar;
.data        = somedata;
} deferred_work;

Vervolgens gaat een kernelthread over een lijst met uitgesteld werk en wanneer het bij dit knooppunt komt, voert het effectief het volgende uit:

bar(somedata);

Dan heb je in de bar:

void bar(void* mydata) {
    int *data = mydata;
    /* do something with data */;
}

Antwoord 4, autoriteit 6%

Het betekent ‘geen waarde’. U gebruikt voidom aan te geven dat een functie geen waarde retourneert of dat deze geen parameters heeft of beide. Vrijwel consistent met typisch gebruik van het woord voidin het Engels.


Antwoord 5, autoriteit 2%

Het geeft de afwezigheid van een retourwaarde in een functie aan.

Sommige talen hebben twee soorten subroutines: procedures en functies. Procedures zijn slechts een reeks bewerkingen, terwijl een functie een reeks bewerkingen is die een resultaat opleveren.

In C en zijn afgeleiden is het verschil tussen de twee niet expliciet. Alles is eigenlijk een functie. het sleutelwoord voidgeeft aan dat het geen “werkelijke” functie is, omdat het geen waarde retourneert.


Antwoord 6

Zie leegte als de ‘lege structuur’. Laat het me uitleggen.

Elke functie heeft een reeks parameters nodig, waarbij elke parameter een type heeft. In feite zouden we de parameters in een structuur kunnen verpakken, waarbij de structuurslots overeenkomen met de parameters. Hierdoor heeft elke functie precies één argument. Evenzo produceren functies een resultaat, dat een type heeft. Het kan een boolean zijn, of het kan float zijn, of het kan een structuur zijn die een willekeurige reeks andere getypte waarden bevat. Als we een taal willen die meerdere retourwaarden heeft, is het gemakkelijk om erop te staan dat ze in een structuur worden verpakt. In feite zouden we er altijd op kunnen staan dat een functie een structuur teruggeeft. Nu heeft elke functie precies één argument nodig en produceert precies één waarde.

Wat gebeurt er als ik een functie nodig heb die een ‘nee’-waarde produceert?
Nou, bedenk eens wat ik krijg als ik een structuur vorm met 3 slots: it
heeft 3 waarden. Als ik 2 slots heb, bevat het twee waarden. Wanneer het
heeft één slot, één waarde. En als het nul slots heeft, houdt het… uh,
nulwaarden, of “geen” waarde”. Dus ik kan een functie bedenken die void retourneert
als het retourneren van een structuur die geen waarden bevat. Je kunt zelfs beslissen dat “leegte”
is slechts een synoniem voor het type vertegenwoordigd door de lege structuur,
in plaats van een trefwoord in de taal (misschien is het gewoon een vooraf gedefinieerd type 🙂

Evenzo kan ik een functie die geen waarden vereist, beschouwen als het accepteren van een lege structuur, bijvoorbeeld “void”.

Ik kan zelfs mijn programmeertaal op deze manier implementeren. Een ongeldige waarde doorgeven
neemt nul bytes in beslag, dus het doorgeven van ongeldige waarden is slechts een speciaal geval van doorgeven
andere waarden van willekeurige grootte. Dit maakt het gemakkelijk voor de compiler om te behandelen
het “ongeldige” resultaat of argument. U wilt waarschijnlijk een taalfunctie
die een functieresultaat kan weggooien; in C, als je het niet-ongeldige resultaat noemt
function foo in de volgende instructie:
foo(…);
de compiler weet dat foo een resultaat produceert en negeert het gewoon.
Als void een waarde is, werkt dit perfect en nu “procedures” (die zijn
gewoon een bijvoeglijk naamwoord voor een functie met ongeldig resultaat) zijn gewoon triviaal speciaal
gevallen van algemene functies.

Void* is een beetje grappiger. Ik denk niet dat de C-ontwerpers dachten aan leegte in de
boven weg; ze hebben zojuist een trefwoord gemaakt. Dat trefwoord was beschikbaar toen iemand
had een punt nodig naar een willekeurig type, dus ongeldig* als het idioom in C.
Het werkt eigenlijk best goed als je leegte interpreteert als een lege structuur.
Een void* pointer is het adres van een plaats waar die lege structuur heeft
gezet.

Afgietsels van void* naar T* voor andere typen T werken ook vanuit dit perspectief.
Pointercasts zijn een complete cheat die werkt op de meest voorkomende architecturen om te profiteren van het feit dat als een samengesteld type T een element heeft met subtype S fysiek aan het begin van T in zijn opslaglay-out, dan S* naar T* en vice versa werkt het gebruik van hetzelfde fysieke machineadres meestal goed, aangezien de meeste machinewijzers een enkele representatie hebben. Het vervangen van het type S door het type void geeft precies hetzelfde effect, en dus werkt casten naar/van void*.

De programmeertaal PARLANSE implementeert de bovenstaande ideeën vrij nauwkeurig.
We hebben het ontwerp verprutst en hebben niet goed gelet op “leegte” als een terugkeer
type en hebben dus taalsleutelwoorden voor procedure. Het is meestal gewoon een simpele
syntaxisverandering, maar het is een van de dingen waar je niet aan toe komt als je het eenmaal hebt
een grote lichaamswerkcode in een taal.


Antwoord 7

In c# zou je het void trefwoord gebruiken om aan te geven dat een methode geen waarde retourneert:

public void DoSomeWork()
{
//some work
}

Antwoord 8

Drie gebruiksgevallen voor ongeldig:

  1. Functiehandtekeningen. void foo(int bar)retourneert geen waarde. int bar(void)heeft geen parameters, maar dit wordt meestal uitgedrukt met een lege argumentenlijst: int bar(). Het gebruik van het ongeldige trefwoord komt overeen met de betekenis in het Engels.

  2. Algemene top-type pointer void *die verwijst naar niet-gespecificeerde gegevens en niet kan worden verwijderd. Hier is de betekenis van leegte anders dan andere betekenissen van leegte: universeel type versus geen type.

  3. In casts zoals (void) new Foo(this)om aan te geven dat de retourwaarde opzettelijk is weggegooid. Hier komt het zoekwoordgebruik ook overeen met de betekenis in het Engels.

Zaken 1 en 2 werden al behandeld door @Gerald, maar zaak 3 is nog niet behandeld.


Antwoord 9

Als je het concept aan een beginner uitlegt, kan het handig zijn om een analogie te gebruiken. Het gebruik van leegte in al deze gevallen is analoog in betekenis aan een pagina in een boek die de volgende woorden heeft: “Deze pagina is opzettelijk blanco gelaten.” Het is bedoeld om voor de compiler onderscheid te maken tussen iets dat als een fout moet worden gemarkeerd, en een type dat opzettelijk leeg wordt gelaten omdat dat het gewenste gedrag is.

Het verschijnt altijd in code waar je normaal gesproken een type zou verwachten, zoals een retourtype of een aanwijzertype. Dit is de reden waarom void in C# verwijst naar een echt CLR-type, System.Void, omdat het een type op zich is.

Sommige programmeertalen hebben nooit het concept van leegte ontwikkeld, net zoals sommige menselijke culturen nooit het concept van het getal nul hebben uitgevonden. Void vertegenwoordigt dezelfde vooruitgang in een programmeertaal als het concept nul vertegenwoordigt voor menselijke taal.


Antwoord 10

Het betekent ‘geen waarde’. Je gebruikt void om aan te geven dat een functie geen waarde retourneert of dat deze geen parameters heeft of beide. Het komt veel overeen met het typische gebruik van het woord void in het Engels.

Void moet niet worden verward met null.Null betekent dat voor de variabele waarvan het adres op de stapel staat, de waarde op de heap voor dat adres leeg is.


Antwoord 11

Void wordt alleen gebruikt in methodehandtekeningen. Voor retourtypen betekent dit dat de methode niets teruggeeft aan de aanroepende code. Voor parameters betekent dit dat er geen parameters worden doorgegeven aan de methode

bijv.

void MethodThatReturnsAndTakesVoid(void)
{
// Method body
}

In C# kunnen we de leegte voor parameters weglaten en kunnen we de bovenstaande code schrijven als:

void MethodThatReturnsAndTakesVoid()
{
// Method body
}

Void moet niet worden verward met null.Null betekent dat voor de variabele waarvan het adres op de stapel staat, de waarde op de heap voor dat adres leeg is.


Antwoord 12

Void is een onvolledig type dat per definitie geen l-waarde kan zijn. Dat betekent dat er geen waarde aan kan worden toegewezen.

Dus het kan ook geen waarde hebben.


Antwoord 13

void betekent dat u geen enkele waarde uit de functie of methode retourneert


Antwoord 14

Void betekent dat er geen waarde vereist is in het retourtype van een functie in alle drie de talen.


Antwoord 15

Void is het equivalent van Visual Basic’s Sub.

Other episodes