Hallo, warum kann ich bei Verwendung des gcc-avr die Parameter nicht als Referenz übergeben? void AddOne(int& y); void AddOne(int& y) { y++; } --> main.c:27: error: expected ';', ',' or ')' before '&' token
Falscher Operator ? Mit einem int* (es ist ja ein Zeiger) funktioniert es besser. Du kannst das Argument ja nicht dereferenzieren, nicht in der Definition.
Nein, es existieren in c sowohl & und * Typen. Pointer!=Referenz Referenz ist etwas sauberer & abgesicherter. Bsp aus: http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Du meinst 'in C++', das ist eine andere Sprache...
Oliver Rendgen schrieb: > es existieren in c sowohl & und * Typen. Nein. > Pointer!=Referenz Richtig, und C != C++. > http://www.learncpp.com/cpp-tutorial/73-passing-ar... Überschrift: "Tutorials to help you master C++ ...". Es gibt aber auch avr-g++. Da geht das. Aber "abgesicherter" ist da deshalb noch nix.
Oliver Rendgen schrieb: > Nein, > es existieren in c sowohl & und * Typen. nein, wie bereits gesagt - solange es um C geht. > Pointer!=Referenz Richtig. > Referenz ist etwas sauberer & abgesicherter. Wieso das? Zeiger deklarieren und die Adresse übergeben ist genauso sauber und nur eine andere Schreibweise wie eine Referenz. Irgendwie abgesichert sind beide nicht im Mindesten. Wenn du den Zeiger in der Funktion nicht versehentlich ändern möchtest, kannst du ihn eleganterweise als const deklarieren. Ab dann ist es nur noch eine Ausdrucksweise für eine Referenz.
Klaus Wachtler schrieb: > Oliver Rendgen schrieb: >> Referenz ist etwas sauberer & abgesicherter. > > Wieso das? > Zeiger deklarieren und die Adresse übergeben ist genauso > sauber und nur eine andere Schreibweise wie eine Referenz. > Irgendwie abgesichert sind beide nicht im Mindesten. Jain. Referenzen kann man AFAIK nur von existierenden Variablen bilden, insbesonders kann man keinen NULL-Pointer übergeben... ... was natürlich ein Problem ist, weil man dann keinen bequemen Mechanismus hat um z.B. die Abwesenheit eines Parameters zu signalisieren... Viele Grüße, Simon
Simon Budig schrieb: > Referenzen kann man AFAIK nur von existierenden Variablen bilden
1 | class A |
2 | {
|
3 | public:
|
4 | A() |
5 | : wert(*new int) |
6 | {
|
7 | }
|
8 | |
9 | ~A() |
10 | {
|
11 | delete &wert; |
12 | }
|
13 | |
14 | private:
|
15 | int &wert; |
16 | };
|
Und wehe du behauptest, das wäre kein richtiges C++!
Simon Budig schrieb: >> Irgendwie abgesichert sind beide nicht im Mindesten. > > Jain. Referenzen kann man AFAIK nur von existierenden Variablen bilden, Weder das, noch ist nach Anlegen der Referenz gesichert, daß die Variable auch noch existiert, wenn man die Refernz dann benutzen will. > insbesonders kann man keinen NULL-Pointer übergeben... Man darf nicht, weil es keine NULL-Referenzen gibt. Daß es nicht passiert, dafür muß man aber immer noch selbst sorgen:
1 | int* p = 0; |
2 | AddOne(*p); |
Zugegebenermaßen liegt hier nach C++-Norm das Problem schon bei der Dereferenzierung beim Aufruf, aber effektiv läuft es bei allen mir bekannten Compilern darauf hinaus, daß innerhalb der aufgerufenen Funktion dasselbe geschieht, wie bei einer Funktion, die einen Zeiger erwartet und NULL übergeben bekommt. > ... was natürlich ein Problem ist, weil man dann keinen bequemen > Mechanismus hat um z.B. die Abwesenheit eines Parameters zu > signalisieren... Naja, das kann man auch gerade als Mittel einsetzen, also die Referenz gerade dann verwenden, wenn man ganz klar will, daß der Parameter nicht weggelassen werden kann.
Simon Budig schrieb: > Jain. Referenzen kann man AFAIK nur von existierenden Variablen bilden, > insbesonders kann man keinen NULL-Pointer übergeben... doch kann man, es ist möglich einen Referenz auf NULL zu übergeben. Aber üblich ist es bestimmt nicht.
Peter schrieb: > es ist möglich einen Referenz auf NULL zu übergeben. Aber üblich ist es > bestimmt nicht. Nein, möglich ist das eigentlich nicht. Man kann Code so schreiben, daß es in der Praxis darauf hinausläuft, aber offiziell ist schon die Erzeugung einer Referenz auf NULL nicht möglich, bzw. der Versuch hat undefiniertes Verhalten.
Vorweg: Wir bewegen uns hier natürlich im Language-Lawyer-Land und ich bin kein C++-Experte, weil ich es meide, wo ich nur kann. Irgendwie steigern die von Euch gebrachten Beispiele auch nicht gerade meine Sympathie für C++ :-) Rolf Magnus schrieb: > Man darf nicht, weil es keine NULL-Referenzen gibt. Daß es nicht > passiert, dafür muß man aber immer noch selbst sorgen: > int* p = 0; > AddOne(*p); Hust. Das ist ja mal hässlich... :-) Ok, man kann kaputte Referenzen übergeben, aber auch nur, indem man eine Variable im Sourcecode hinschreibt. Einfach nur AddOne (NULL); geht nicht - was vom Sourcecode her natürlich die deutlich klarere Variante wäre... Peter schrieb: > doch kann man, es ist möglich einen Referrenz auf NULL zu übergeben. Aber > üblich ist es bestimmt nicht. Ja Moment, es ist aber ein Unterschied, ob Du eine Referenz auf einen Nullpointer (also eine Speicheradresse in der NULL drinsteht) übergibst, oder ob Du einen Nullpointer übergibst. Zumindest auf einer logischen Ebene - was ein Compiler draus macht ist nochmal eine andere Sache, s.o. Viele Grüße, Simon
Simon Budig schrieb: > bin kein C++-Experte, weil ich es meide, wo ich nur kann. Irgendwie > steigern die von Euch gebrachten Beispiele auch nicht gerade meine > Sympathie für C++ :-) Lass dich davon nicht verwirren. In der Praxis ist DIESER Punkt weit weniger ein Problem, als es jetzt scheint. >> int* p = 0; >> AddOne(*p); > > Hust. Das ist ja mal hässlich... :-) Es ist das Standardbeispiel in den Newsgroup, mit der jemand beweisen will, dass er eine NULL-Referenz erzeugen kann. Nur übersieht er dabei leider, dass sein Fehler streng genommen schon beim *p steckt und die Referenz nichts dafür kann. > Variable im Sourcecode hinschreibt. Einfach nur AddOne (NULL); geht > nicht - was vom Sourcecode her natürlich die deutlich klarere Variante > wäre... Niemand hindert dich AddOn( *NULL ); zu schreiben. :-) (Ist natürlich genauso falsch) > Ja Moment, es ist aber ein Unterschied, ob Du eine Referenz auf einen > Nullpointer (also eine Speicheradresse in der NULL drinsteht) übergibst, > oder ob Du einen Nullpointer übergibst. Zumindest auf einer logischen > Ebene - was ein Compiler draus macht ist nochmal eine andere Sache, s.o. Referenzen werden in C++ gerne misverstanden. Offiziell ist eine Referenz 'ein anderer Name für ein ansonsten existierendes Objekt'. Nicht mehr und nicht weniger. Ob der Compiler das mit einem Pointer realisiert oder nicht, ist dem Compiler überlassen. Er kann, aber er muss nicht (und in diesem speziellen Fall wird er das mit einem Pointer machen) Referenzen sind in C++ an dieser Stelle insofern praktisch, weil eine Funktion damit signalisieren kann: An dieser Stelle will ich vom Aufrufer ein Objekt haben. Ich lege es nichgt selbst an, sondern du musst es mir übergeben. Die Fehler von Neulingen sind legendär, in denen sie zb schreiben char * result; GetString( result ); Auf Nachfrage, warum sie da einen Pointer reinstopfen kommt dann meistens: " Ja aber die Funktion sieht doch so aus void GetString( char * result ); Da steh doch, dass ich der Funktion einen Pointer übergeben soll! " Dann muss man erst einmal lang und breit erklären, dass ein Pointer in einer Argumentliste 2 Dinge anzeigen kann. Unter anderem auch, dass die Funktion vom Aufrufer erwartet, dass er den Speicher bereitstellt und die Adresse bekannt gibt an der die Funktion schreiben kann. Referenzen sind da etwas eindeutiger. Das ist das eine. Zum anderen ermöglichen Referenzen dem Compiler ein paar Optimierungen und für Operator Overloading sind sie sowieso notwendig. Die übliche Empfehlung in C++ ist: Verwende lieber Referenzen anstelle von Pointern. Pointer in einer Argumentliste nur dann, wenn es die Möglichkeit geben soll, dass der Aufrufer signalisiern kann "Ich hab hier nichts was ich dir geben könnte" oder "Interessiert mich nicht" Aber wie gesagt: Lass dich davon nicht irre machen. Refernzen sind in C++ noch das harmloseste und in der Praxis auch kein größeres Problem als NULL-Pointer in C. Hat man das erst mal im Griff, wundert man sich was denn die ganze Zeit daran so schwer erschienen ist.
Danke Allen für die Erklärungen, jetzt weiss ich dass es Referenzen erst mit C++ gab;)
Zugegebenermaßen hätte die Diskussion etwas kompakter ausfallen können :-)
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.