Diskussion:C-Programmierung: Zeiger

Aus Wikibooks
Zur Navigation springen Zur Suche springen

Wie kommt man in Visual Basic ohne Zeiger aus?[Bearbeiten]

Hat 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![Bearbeiten]

Ab 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?[Bearbeiten]

Ob 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[Bearbeiten]

Tach!

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[Bearbeiten]

Hallo. 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[Bearbeiten]

Im 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[Bearbeiten]

Hallo! 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[Bearbeiten]

Der 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[Bearbeiten]

Original:

 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);

--84.58.205.228 16:50, 16. Mai 2011 (CEST)

Grösse von Zeigern[Bearbeiten]

Zitat: 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[Bearbeiten]

Sorry, 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 muss char* 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)