Diskussion:C-Programmierung: Zeiger
Wie kommt man in Visual Basic ohne Zeiger aus?
BearbeitenHat jemand eine Ahnung, wie man in Visual Basic ohne Datenstrukturen wie verkette Listen auskommt? -- Daniel B 17:12, 8. Sep 2004 (UTC)
Funktionen sollten nicht im Kapitel für Zeiger erklärt werden!
BearbeitenAb der Überschrift "Unterschied zwischen Call by Value & Call by Reference" bis hin zu "swap()" kann alles gelöscht oder zu den Beispielen im Kapitel "Funktionen" verschoben werden, da dies nichts mit dem Kapitel über Zeiger zu tun hat. Könnte sein das der vorherige Autor einfach nur den Unterschied aufzeigen wollte oder einen einfacheren Übergang zu seinem/ihren Beispiel mit dem swap() haben wollte (auch wenn seine/ihre alte Überschrift überhaupt nicht gepasst hat). Also am besten weg damit und ab der Überschift einfach neu schreiben oder den bereits vorhandenen Text abändern und/oder ergänzen. Jeder Anfänger der dieses Buch liest/(lesen wird) wäre dem/der/denen-jenigen für die Arbeit an der überarbeitung sicherlich überaus dankbar. :)
Beispiel für Zeigerarithmetik falsch?
BearbeitenOb es nun komplett falsch ist, kann ich anhand meines bisherigen Kenntnissstandes über C nicht beurteilen. Es ist jedoch nicht allgemein gültig.
Ich habe das Beispiel einmal genauso, wie es im Artikel steht, versucht zu kompilieren und bekomme folgende Fehlermeldungen:
zeiger-arithmetik.c: In function ‘main’: zeiger-arithmetik.c:5: error: ‘new’ undeclared (first use in this function) zeiger-arithmetik.c:5: error: (Each undeclared identifier is reported only once zeiger-arithmetik.c:5: error: for each function it appears in.) zeiger-arithmetik.c:5: error: expected ‘,’ or ‘;’ before ‘int’
Diese Ausgaben kommen von gcc im ANSI-C89-Modus (gcc -std=c89), auch C99 (gcc -std=c99). Soweit erscheint mir das auch vollkommen verständlich. Wenn es sich nur um ein fiktives Beispiel handeln sollte, wäre eine Kennzeichnung als solches wünschenswert. Aber ein wirklich funktionierendes Beispiel wäre deutlich besser.
Da ich noch nicht alles begriffen habe, werde ich erst einmal den Artikel nicht selber bearbeiten, aber meinen Vorschlag für ein funktionierendes Beispiel hier unterbreiten:
#include <stdio.h>
int main(void)
{
unsigned int *i;
*i=5;
printf("Speicheradresse %u enthält %u\n",i,*i);
i++; // nächste Adresse lesen
printf("Speicheradresse %u enthält %u\n",i,*i);
return 0;
}
Die Ausgabe ist allerdings etwas anders:
Speicheradresse 3086544884 enthält 5 Speicheradresse 3086544888 enthält 3086672512
Im originalen Beispiel habe ich ohnehin nicht verstanden, warum plötzlich *i == 0
sein soll, es wird doch der Inhalt der nächsten Speicherzelle ausgelesen, der ja davon abhängt, was da gerade drin steht. Eine sonsitge Wertzuweisung oder Initialisierung für diese Zelle ist ja nicht erfolgt.
-- Marcus 85.183.158.220 15:03, 11. Sep. 2007 (CEST)
Fehlerteufel
BearbeitenTach!
Unter "3 Zeiger auf Funktionen" steht unter dem ersten Beispiel geschrieben: "Anstelle des Namens der Funktion tritt der Zeiger." Klingt irgendwie verwirrend. Mag das mal jemand berichtigen? :)
Gruss, Levent
Beispiel der Zeiger in Funktionen
BearbeitenHallo. Ich finde das Beispiel mit den Zeigern in Funktionen unpassend. Darin kommt eine Rekursion vor, obwohl das Thema erst einige Kapitel später behandelt wird. Um Zeiger zu verstehen bedarf es einer gewissen Zeit. Ich finde, dass die Rekursion das Thema erst kompliziert macht.
Da ich dir nicht ins Handwerk pfuschen will, überlasse ich es dir, das Beispiel zu ändern.
Bezeichnung "Call By Reference" ist nicht unproblematisch
BearbeitenIm Text steht "In vielen Büchern wird ein solcher Aufruf auch als Call By Reference bezeichnet. Diese Bezeichnung ist aber nicht unproblematisch" Wie lautet denn dann die richtiige Bezeichnung dafür?
Zeiger auf Funktionen
BearbeitenHallo! Ich versteh nicht ganz, was mir ein Zeiger auf eine Funktion bringen soll... MoB der 1. 16:55, 5. Jan. 2009 (CET) Darum geht es hier ja auch nicht. (Trotzdem, bsp: callback Funktionen)
Ich hab auch noch ne Frage:
"Die Schreibweise (f = func) ist gleich mit (f = &func), da die Adresse der Funktion im Funktionsnamen steht. Der Lesbarkeit halber sollte man nicht auf den Adressoperator(&) verzichten." Trotzdem wird(!) im Beispiel darauf verzichtet. Warum ? Man könnte zumindest noch ein weiteres Beispiel machen, in der die Schreibweise mit dem Adressoperator verwendet wird.
Abschnitt: Werte an Funktionen übergeben
BearbeitenDer Abschnitt Werte an Funktionen übergeben mag ja inhaltlich sehr gut sein. Aber was hat das mit Zeigern zu tun? Irgendwie nicht sehr viel ... --WissensDürster 12:06, 21. Feb. 2009 (CET)
Bezeichnung ist falsch
BearbeitenOriginal:
printf("Inhalt der Variablen b: %i\n", b); printf("Inhalt der Variablen a: %i\n", *a); printf("Adresse der Variablen b: %p\n", &b); printf("Adresse der Variablen a: %p\n", (void *)a);
IMHO besser:
printf("Inhalt der Variablen b: %i\n", b); printf("Inhalt des Speichers, auf den a zeigt: %i\n", *a); printf("Adresse der Variablen b: %p\n", &b); printf("Gespeicherte Adresse in der Variable a: %p\n", (void *)a);
--195.72.96.249 11:03, 20. Nov. 2009 (CET)
- Das ist mir auch aufgefallen und ich stimme dir zu. Die Variable eines Zeigers enthält nämlich selbst eine Adresse und die erreicht man mit &a. Will man aber den Inhalt des Zeigers haben und der Inhalt ist hier ganz klar eine Adresse und kein Wert, weil ein Zeiger nunmal Adressen speichert, dann ist (void *)a richtig. Will man aber den Inhalt der Adresse haben, auf die der Zeiger verweist, dann ist *a richtig. Ich habe es daher mal folgendermaßen korrigiert:
printf("Inhalt der Variablen b: %i\n", b); printf("Inhalt des Speichers, auf den a zeigt: %i\n", *a); printf("Adresse der Variablen b: %p\n", &b); printf("Adresse auf die die Zeigervariable a verweist: %p\n", (void *)a); /* Aber */ printf("Adresse des Zeigersvariable a: %p\n", &a);
Grösse von Zeigern
BearbeitenZitat: Bei einer 16 Bit CPU ist die Adresse 2 Byte, bei einer 32 Bit CPU 4 Byte und bei einer 64 Bit CPU 8 Byte breit - unabhängig davon, ob die Zeigervariable als char, int, float oder double deklariert wurde.
Problem: Das ist meines Erachtens nicht allgemein gültig, wenn auch oft richtig. Besser wäre: Ein Pointer (Zeiger) belegt natürlich immer dieselbe Menge Speicherplatz, unabhängig davon, worauf er zeigt. Wenn die Grösse eines Pointers interessiert, sollte diese mit sizeof() ermittelt werden.
Zeigerarithmetik : Beispiel
BearbeitenSorry, too shy to write German (would make too many mistakes).
In the discussion of the example under "Zeigerarithmetik", it is hinted that the architecture is to blame for the 4-byte advance resulting from i++ .
Should that not rather be blamed on the fact that the int data type happens to be 4 bytes wide (on that system) ?
Test 1 : run the same example on x86_64 : again 4-byte advance
Test 2 : modify x and its pointer from int to double : 8-byte advance
Cheers
Piet
--90.41.112.247 22:21, 3. Dez. 2015 (CET)
- Ich habe etwas zum Kommentar hinzugefügt. Hybrid Dog 20:50, 3. Jun. 2017 (CEST)
- Das Programm stellt kein korrektes C dar. Zunächst ist auf einen Zeiger vom Typ
void*
in ISO C keine Arithmetik anwendbar. Siehe Stack Overflow. Stattdessen musschar*
benutzt werden. Außerdem ist das Lesen der nächsten Speicherzelle undefined behavior. Da kann ein zufälliges Datum gelesen werden, es kann aber auch zum Programmabbruch mit Speicherzugriffsfehler führen. Valgrind findet solche Fehler. Man verwende am besten: $ gcc main.c -o main -Wall -pedantic $ valgrind ./main
- -- Rumil 22:04, 3. Jun. 2017 (CEST)
- Das Programm stellt kein korrektes C dar. Zunächst ist auf einen Zeiger vom Typ
Zeigeraddressen in die andere Richtung
BearbeitenWenn man: int a; int *b; b = &a; macht - ginge auch &a = b; (oder &a = *b;) um die Speicheraddresse die b hat um auf einen Wert zu zeigen in a so zu schreiben, dass a den Wert zurückgibt? --79.206.204.48 10:25, 3. Feb. 2023 (CET)