door middel van referentie in C

Als C niet ondersteunt die door verwijzing een variabele passeert, waarom werkt dit?

#include <stdio.h>
void f(int *j) {
  (*j)++;
}
int main() {
  int i = 20;
  int *p = &i;
  f(p);
  printf("i = %d\n", i);
  return 0;
}

OUTPUT:

$ gcc -std=c99 test.c
$ a.exe
i = 21 

1, Autoriteit 100%

Omdat u de waarde van de aanwijzer naar de methode passeert en vervolgens afneemt om het integer waarnaar te krijgen.


2, Autoriteit 47%

Dat is niet pass-by-reference, dat is pass-by-waarde zoals anderen vermeld.

De C-taal wordt zonder uitzondering pass-by-waarde. Een aanwijzer passeren
Aangezien een parameter niet betekent Pass-by-reference.

De regel is het volgende:

Een functie is niet in staat om de daadwerkelijke parameterswaarde te wijzigen.


Laten we proberen de verschillen tussen scalaire en pointerparameters van een functie te zien.

Scalar-variabelen

Dit korte programma toont pass-by-waarde met behulp van een scalaire variabele. paramwordt de formele parameter en variablebij functie-aanwijzing genoemd, wordt de werkelijke parameter genoemd. OPMERKING Incrementing paramin de functie verandert niet variable.

#include <stdio.h>
void function(int param) {
    printf("I've received value %d\n", param);
    param++;
}
int main(void) {
    int variable = 111;
    function(variable);
    printf("variable %d\m", variable);
    return 0;
}

Het resultaat is

I've received value 111
variable=111

Illusie van pass-by-referentie

We veranderen het stukje code iets. paramis nu een aanwijzer.

#include <stdio.h>
void function2(int *param) {
    printf("I've received value %d\n", *param);
    (*param)++;
}
int main(void) {
    int variable = 111;
    function2(&variable);
    printf("variable %d\n", variable);
    return 0;
}

Het resultaat is

I've received value 111
variable=112

Daardoor denk je dat de parameter als referentie is doorgegeven. Het was niet. Het werd doorgegeven door waarde, waarbij de parameterwaarde een adres was. De waarde van het type int is verhoogd, en dat is het neveneffect waardoor we denken dat het een pass-by-reference-functieaanroep was.

Aanwijzers – doorgegeven-by-waarde

Hoe kunnen we dat feit aantonen/bewijzen? Nou, misschien kunnen we het eerste voorbeeld van scalaire variabelen proberen, maar in plaats van scalair gebruiken we adressen (pointers). Eens kijken of dat kan helpen.

#include <stdio.h>
void function2(int *param) {
    printf("param's address %d\n", param);
    param = NULL;
}
int main(void) {
    int variable = 111;
    int *ptr = &variable;
    function2(ptr);
    printf("ptr's address %d\n", ptr);
    return 0;
}

Het resultaat zal zijn dat de twee adressen gelijk zijn (maak je geen zorgen over de exacte waarde).

Voorbeeld resultaat:

param's address -1846583468
ptr's address -1846583468

Naar mijn mening bewijst dit duidelijk dat pointers per waarde worden doorgegeven. Anders zou ptrNULLzijn na het aanroepen van een functie.


Antwoord 3, autoriteit 22%

In C wordt Pass-by-reference gesimuleerd
door het adres van een variabele door te geven
(een aanwijzer) en de verwijzing naar dat
adres binnen de functie om te lezen of
schrijf de werkelijke variabele. Dit zal
worden aangeduid als “C-stijl”
pass-by-referentie.”

Bron: www-cs-students.stanford .edu


Antwoord 4, autoriteit 15%

Omdat er geen pass-by-referentie is in de bovenstaande code. Het gebruik van pointers (zoals void func(int* p)) is een pass-by-adres.
Dit is pass-by-referentie in C++ (werkt niet in C):

void func(int& ref) {ref = 4;}
...
int a;
func(a);
// a is 4 now

Antwoord 5, autoriteit 9%

Uw voorbeeld werkt omdat u het adres van uw variabele doorgeeft aan een functie die de waarde manipuleert met de dereference exploitant.

Hoewel C referentiegegevenstypenniet ondersteunt, kunt u toch doorverwijzing door expliciet pointerwaarden door te geven, zoals in uw voorbeeld.

Het C++-referentiegegevenstype is minder krachtig, maar wordt als veiliger beschouwd dan het aanwijzertype dat is geërfd van C. Dit zou uw voorbeeld zijn, aangepast voor gebruik van C++ referenties:

void f(int &j) {
  j++;
}
int main() {
  int i = 20;
  f(i);
  printf("i = %d\n", i);
  return 0;
}

Antwoord 6, autoriteit 4%

U passeert een pointer(adreslocatie) op waarde.

Het is alsof je zegt “hier is de plek met de gegevens die ik wil dat je updatet.”


Antwoord 7, autoriteit 2%

In C is alles pass-by-waarde. Het gebruik van pointers geeft ons de illusie dat we voorbijgaan aan referentie omdat de waardevan de variabele verandert. Als u echter het adres van de pointervariabele zou afdrukken, zult u zien dat deze niet wordt beïnvloed. Een kopievan de waardevan het adres wordt doorgegeven aan de functie. Hieronder een fragment dat dat illustreert.

void add_number(int *a) {
    *a = *a + 2;
}
int main(int argc, char *argv[]) {
   int a = 2;
   printf("before pass by reference, a == %i\n", a);
   add_number(&a);
   printf("after  pass by reference, a == %i\n", a);
   printf("before pass by reference, a == %p\n", &a);
   add_number(&a);
   printf("after  pass by reference, a == %p\n", &a);
}
before pass by reference, a == 2
after  pass by reference, a == 4
before pass by reference, a == 0x7fff5cf417ec
after  pass by reference, a == 0x7fff5cf417ec

Antwoord 8, autoriteit 2%

p is een pointervariabele. De waarde is het adres van i. Als je f aanroept, geef je de waarde doorvan p, wat het adres is van i.


Antwoord 9, autoriteit 2%

Geen pass-by-referentie in C, maar p “verwijst” naar i, en je geeft p door met waarde.


Antwoord 10

Omdat je een pointer (geheugenadres) doorgeeft aan de variabele p in de functie f. Met andere woorden, u geeft een aanwijzer door, geen verwijzing.


11

Kort antwoord: Ja, C implementeert de parameter die door verwijzing door verwijzing wordt gebruikt.

Terwijl het implementeren van parameter passeren, gebruiken ontwerpers van programmeertalen drie verschillende strategieën (of semantische modellen): gegevens overbrengen naar het subprogramma, ontvang gegevens van het subprogramma, of doen beide. Deze modellen worden algemeen bekend als in modus, out-modus en de modus, dienovereenkomstig.

Verschillende modellen zijn ontworpen door taalontwerpers om deze drie elementaire parameter passerende strategieën uit te voeren:

Pass-by-waarde (in modus Semantiek)
Pass-by-resultaat (out-modus semantiek)
Pass-by-value-Resultaat (Semantiek in de modus)
Pass-by-reference (out-mode semantiek)
Pass-by-no (out-modus semantiek)

Pass-by-reference is de tweede techniek voor inout-mode parameter passeren.
In plaats van dat gegevens heen en weer tussen de hoofdroutine en het subprogramma kopiëren, verzendt het runtime-systeem een ​​direct toegangspad naar de gegevens voor het subprogramma. In deze strategie heeft het subprogramma directe toegang tot de gegevens die effectief de gegevens met de hoofdroutine delen. Het grote voordeel met deze techniek is dat het absoluut efficiënt in de tijd en de ruimte is, omdat het niet nodig is om de ruimte te dupliceren en er geen gegevenskopieeringen zijn.

Parameter passerende implementatie in C:
C implementeert pass-by-waarde en pass-by-reference (inout-modus) semantiek met behulp van pointers als parameters. De aanwijzer wordt naar het subprogramma gestuurd en er worden helemaal geen feitelijke gegevens gekopieerd. Omdat een pointer echter een toegangspad is naar de gegevens van de hoofdroutine, kan het subprogramma de gegevens in de hoofdroutine wijzigen. C heeft deze methode overgenomen van ALGOL68.

Parameter doorgeven implementatie in C++:
C++ implementeert ook pass-by-reference (inout-modus) semantiek met behulp van aanwijzers en ook met behulp van een speciaal soort aanwijzer, het referentietype. Referentietype-pointers worden impliciet gederefereerd binnen het subprogramma, maar hun semantiek is ook pass-by-referentie.

Dus het belangrijkste concept hier is dat pass-by-reference een toegangspad naar de gegevens implementeert in plaats van de gegevens naar het subprogramma te kopiëren. Paden voor gegevenstoegang kunnen expliciet gederefereerde pointers of automatisch gederefereerde pointers (referentietype) zijn.

Raadpleeg voor meer informatie het boek Concepts of Programming Languages door Robert Sebesta, 10e editie, hoofdstuk 9.


Antwoord 12

Je geeft geen int door als referentie, je geeft een pointer-naar-een-int door als waarde. Andere syntaxis, zelfde betekenis.


Antwoord 13

pointers en referenties zijn twee verschillende dingen.

Een paar dingen die ik nog niet genoemd heb gezien.

Een aanwijzer is het adres van iets. Een aanwijzer kan worden opgeslagen en gekopieerd zoals elke andere variabele. Het heeft dus een maat.

Een verwijzing moet worden gezien als een ALIAS van iets. Het heeft geen maat en kan niet worden bewaard. Het MOET ergens naar verwijzen, bijv. het kan niet nul of gewijzigd zijn. Welnu, soms moet de compiler de referentie opslaan als een pointer, maar dat is een implementatiedetail.

Met referenties heb je geen problemen met verwijzingen, zoals eigendomsafhandeling, null-controle, de-referentie bij gebruik.


Antwoord 14

‘Pass by reference’ (door gebruik te maken van pointers) staat vanaf het begin in C. Waarom denk je dat dat niet zo is?


Antwoord 15

Ik denk dat C in feite pass by reference ondersteunt.

De meeste talen hebben syntactische suiker nodig om door te verwijzen naar referentie in plaats van naar waarde. (C++ vereist bijvoorbeeld & in de parameterdeclaratie).

C heeft hiervoor ook syntactische suiker nodig. Het is * in de declaratie van het parametertype en & op het betoog. Dus * en & isde C-syntaxis voor pass by reference.

Je zou nu kunnen stellen dat echte pass-by-referentie alleen syntaxis vereist voor de parameterdeclaratie, niet voor de argumentkant.

Maar nu komt C# die ondersteuntdoor verwijzing door te geven ensyntactische suiker vereist op zowelparameter- als argumentkanten.

Het argument dat C geen by-ref-passing heeft waardoor de syntactische elementen om het uit te drukken de onderliggende technische implementatie vertonen, is helemaal geen argument, aangezien dit min of meer op alle implementaties van toepassing is.

Het enige overgebleven argument is dat het passeren van ref in C geen monolithisch kenmerk is, maar twee bestaande kenmerken combineert. (Neem ref van argument met &, verwacht dat ref typt met *.) C# vereist bijvoorbeeld twee syntactische elementen, maar ze kunnen niet zonder elkaar worden gebruikt.

Dit is duidelijk een gevaarlijk argument, omdat veel andere functies in talen zijn samengesteld uit andere functies. (zoals string-ondersteuning in C++)


Antwoord 16

Wat u doet, is een waarde doorgeven, niet een verwijzing.
Omdat je de waarde van een variabele ‘p’ naar de functie ‘f’ stuurt (hoofdzakelijk als f(p);)

Hetzelfde programma in C met pass-by-referentie zal er als volgt uitzien,(!!!dit programma geeft 2 fouten omdat pass-by-referentie niet wordt ondersteund in C)

#include <stdio.h>
void f(int &j) {    //j is reference variable to i same as int &j = i
  j++;
}
int main() {
  int i = 20;
  f(i);
  printf("i = %d\n", i);
  return 0;
}

Uitvoer:-

3:12: fout: verwacht ';', ',' of ')' voor '&' token
       ongeldig f(int & j);
            ^
9:3: waarschuwing: impliciete verklaring van functie 'f'
        fa);
        ^

Other episodes