Zeiger definieren

Schnelle objektorientierte, kompilierende Programmiersprache.
Benutzeravatar
soufian88
Beiträge: 288
Registriert: So Jan 18, 2009 1:01 pm

Zeiger definieren

Beitrag von soufian88 » Sa Feb 21, 2009 8:02 pm

Ich habe Problem beim compilieren dieser Codezeilen:

Code: Alles auswählen

#include <stdio.h>
 
int main()
{
  int a = 100, *pa = &a;   /* a wird mit 100 initialisiert, pa zeigt gleich auf a */
 
  printf ("a = %d\n", a);
  printf ("*pa = %d\n", *pa);
 
  printf ("&a = %x (hexadezimal)\n", &a);
  printf ("pa = %x (hexadezimal)\n", pa);   /* "Wert" des Zeigers, also wohin zeigt pa? */
  printf ("&pa = %x (hexadezimal)\n",&pa);   /* Wo liegt der Zeiger selbst im Speicher? */
 
  printf ("Zeiger wird dereferenziert, Wert verändert ...\n");
  *pa = 200;   /* Ueber den Zeiger auf a zugreifen und dessen Wert veraendern */
  printf ("Neuer Wert von a: %d\n", a);
 
  return 0;
}
und bei Terminal zeigt er mir so ein Fehler an :
  • Zeiger.c: In Funktion »main«:
    Zeiger.c:10: Warnung: format »%x« erwartet Typ »unsigned int«, aber Argument 2 hat Typ »int *«
    Zeiger.c:11: Warnung: format »%x« erwartet Typ »unsigned int«, aber Argument 2 hat Typ »int *«
    Zeiger.c:12: Warnung: format »%x« erwartet Typ »unsigned int«, aber Argument 2 hat Typ »int **«
Ich vermute nur das es bei Datentyp liegt hab int in unsigned umgewandelt hat aber trotzdem nichts gebracht.
Könnt ihr mir vielleicht helfen ?

mfg soufian
C ( Durchschnittlich ) C++ (am Lernen)

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Zeiger definieren

Beitrag von nufan » Sa Feb 21, 2009 8:14 pm

soufian88 hat geschrieben: und bei Terminal zeigt er mir so ein Fehler an :
  • Zeiger.c: In Funktion »main«:
    Zeiger.c:10: Warnung: format »%x« erwartet Typ »unsigned int«, aber Argument 2 hat Typ »int *«
    Zeiger.c:11: Warnung: format »%x« erwartet Typ »unsigned int«, aber Argument 2 hat Typ »int *«
    Zeiger.c:12: Warnung: format »%x« erwartet Typ »unsigned int«, aber Argument 2 hat Typ »int **«
Warnungen halten dich nicht davon ab, dass Programm zu kompilieren.
Oder willst du wissen woher die Warnungen kommen?

Castest du die Adressen sind die Warnungen weg.

Code: Alles auswählen

      printf ("&a = %X (hexadezimal)\n", (unsigned int)&a);
      printf ("pa = %X (hexadezimal)\n", (unsigned int)pa);   /* "Wert" des Zeigers, also wohin zeigt pa? */
      printf ("&pa = %X (hexadezimal)\n",(unsigned int)&pa);   /* Wo liegt der Zeiger selbst im Speicher? */
Warum sich der Compiler beim anderen Code aufregt versteh ich auch nicht ganz.

BTW: Bei Hexadezimalzahlen ist %X schöner, da dann die Buchstaben als Großbuchstaben ausgegeben werden.

EDIT: Hinweis zu cast hinzugefügt.
Zuletzt geändert von nufan am Sa Feb 21, 2009 8:19 pm, insgesamt 1-mal geändert.

Benutzeravatar
soufian88
Beiträge: 288
Registriert: So Jan 18, 2009 1:01 pm

Re: Zeiger definieren

Beitrag von soufian88 » Sa Feb 21, 2009 8:24 pm

Natührlich der Cast Operator wieso bin ich nicht früher raufgekommen.
Dank dir. :P
C ( Durchschnittlich ) C++ (am Lernen)

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Zeiger definieren

Beitrag von nufan » Sa Feb 21, 2009 8:29 pm

soufian88 hat geschrieben:Natührlich der Cast Operator wieso bin ich nicht früher raufgekommen.
Dank dir. :P
Das Problem ist zwar gelöst, trotzdem wäre es schön wenn jemand noch eine Erklärung abgeben könnte, warum der Compiler (gcc oder?) dabei Warnungen ausgibt.

Benutzeravatar
soufian88
Beiträge: 288
Registriert: So Jan 18, 2009 1:01 pm

Re: Zeiger definieren

Beitrag von soufian88 » Sa Feb 21, 2009 8:32 pm

Ja Gcc ich hab aber keine Ahnung warum der Compiler die Überflüssigen Fehler ausgibt.
C ( Durchschnittlich ) C++ (am Lernen)

Benutzeravatar
fat-lobyte
Beiträge: 1398
Registriert: Sa Jul 05, 2008 12:23 pm
Wohnort: ::1
Kontaktdaten:

Re: Zeiger definieren

Beitrag von fat-lobyte » Sa Feb 21, 2009 8:47 pm

nufan hat geschrieben:Warnungen halten dich nicht davon ab, dass Programm zu kompilieren.
Warnungen sind dazu da dir den Code anzuschauen und nochmal zu überlegen was falsch ist.
nufan hat geschrieben:Castest du die Adressen sind die Warnungen weg.
Ich glaube klassisch wäre jetzt ein Kommentar von Xin angesagt, aber bis dahin erklär ich mal:
Casts sind in den meisten fällen ein Anzeichen eines Fehlers im Programmdesign. Das hier ist so ein Fall.
nufan hat geschrieben:Warum sich der Compiler beim anderen Code aufregt versteh ich auch nicht ganz.
Umso wichtiger dass du nicht leichtfertig Ratschläge zum Casten und ignorieren der Warnungen gibst, sondern dich zuerst mal schlau machst.

Wenn du dir die Referenz von printf() ansiehst, dann steht da
x Unsigned hexadecimal integer
Das bedeutet die Funktion printf() liest das %X ein, und denkt sich auf dem Stack liegt ein unsigned und druckt es entsprechend aus. Es ist aber keines, sondern ein signed. Die probleme tauchen auf, wenn du versuchst eine negative Zahl mit %X anzuzeigen. (siehe http://tutorial.proggen.org/doku.php?id ... m_computer).

Übrigens, genau dieses unvorsichtige Vorgehen mit printf() ermöglicht eine Reihe von sogenannten "Formatting String Attacks".

Hier bist du eigentlich schon auf die Problematik von printf() gestoßen, und wieso man es in C++ vermeiden sollte und stattdessen std::cout verwenden sollte: cout ist typsicher, und solche Fehler können nicht passieren. Wenn man ehrlich ist, dann ist es "eigentlich" eine ziemlich blöde Idee den Programmablauf (also eigentlich was alles angezeigt werden soll) anhand eines Strings zu bestimmen. Das zusammen mit der Variablen Argumentzahl macht (vielleicht nicht gerade printf, aber andere) solche Funktionen gefährlich.


Du kannst dich übrigens glücklich schätzen, dass dein Compiler in den Formatstring von printf() reinschaut und nicht einfach stupide sagt "ist eh nur ein string, kann ja nix passieren" wie andere Compiler es tun.

nufan hat geschrieben:EDIT: Hinweis zu cast hinzugefügt.
Wo denn? Bitte nochmal revidieren, mit der info der ich oben gegeben habe.
soufian88 hat geschrieben:Ja Gcc ich hab aber keine Ahnung warum der Compiler die Überflüssigen Fehler ausgibt.
Wie gesagt, gar nicht überflüssig sondern völlig zurecht.
Haters gonna hate, potatoes gonna potate.

nufan
Wiki-Moderator
Beiträge: 2558
Registriert: Sa Jul 05, 2008 3:21 pm

Re: Zeiger definieren

Beitrag von nufan » Sa Feb 21, 2009 9:12 pm

fat-lobyte hat geschrieben:Das bedeutet die Funktion printf() liest das %X ein, und denkt sich auf dem Stack liegt ein unsigned und druckt es entsprechend aus. Es ist aber keines, sondern ein signed. Die probleme tauchen auf, wenn du versuchst eine negative Zahl mit %X anzuzeigen. (siehe http://tutorial.proggen.org/doku.php?id ... tems:bin&s[]=zahlensysteme#binaere_zahlen_im_computer).
Ich denke ich verstehe das allgemeine Problem. Aber bei Adressen? Das es negative Adressen gibt wäre mir neu, lasse mich aber gerne belehren.
fat-lobyte hat geschrieben:
nufan hat geschrieben:EDIT: Hinweis zu cast hinzugefügt.
Wo denn? Bitte nochmal revidieren, mit der info der ich oben gegeben habe.
Nunja... laut Referenz kann man mittels %p Adressen ausgeben. Habs getestet und ergibt die gleiche Ausgabe wie der Cast, nur mit vorangestelltem 0x und kleinen Buchstaben. Sollte also die Lösung sein. Wenn nicht, bin ich endgültig ratlos.

Benutzeravatar
soufian88
Beiträge: 288
Registriert: So Jan 18, 2009 1:01 pm

Re: Zeiger definieren

Beitrag von soufian88 » Sa Feb 21, 2009 9:14 pm

Danke für die Ausführliche Erklärung. ;)
aber eine Frage hab ich noch was ein Stack ?
C ( Durchschnittlich ) C++ (am Lernen)

Benutzeravatar
Kerli
Beiträge: 1456
Registriert: So Jul 06, 2008 10:17 am
Wohnort: Österreich
Kontaktdaten:

Re: Zeiger definieren

Beitrag von Kerli » Sa Feb 21, 2009 9:44 pm

soufian88 hat geschrieben:aber eine Frage hab ich noch was ein Stack ?
Das ist das Grundlegende Prinzip das hinter Funktionsaufrufen bzw. eigentlich überhaupt der Ausführung von Programmen liegt. Alle Variablen die nicht dynamisch angefordert werden liegen zum Beispiel auf dem Stack.

Wenn nun ein Funktionaufruf durchgeführt wird, werden unter anderem die Parameter auf den Stack gelegt. Dann springt die Ausführung des Programms in die Funktion und führt damit die Berechnungen durch. Dannach legt die Funktion das Ergebnis auf den Stack. Und die Ausführung wird wieder dort fortgesetzt wo sie vorher unterbrochen worden ist.

Eine kurze Erklärung zum Stack findet sich auch hier: http://proggen.org/doku.php?id=c:die_sp ... _prozesses

Der Artikel mit einer genaueren Beschreibung fehlt leider noch...
"Make it idiot-proof and someone will invent an even better idiot." (programmers wisdom)

OpenGL Tutorials und vieles mehr rund ums Programmieren: http://www.tomprogs.at

Benutzeravatar
Xin
nur zu Besuch hier
Beiträge: 8862
Registriert: Fr Jul 04, 2008 11:10 pm
Wohnort: /home/xin
Kontaktdaten:

Re: Zeiger definieren

Beitrag von Xin » Sa Feb 21, 2009 10:17 pm

Kerli hat geschrieben:Eine kurze Erklärung zum Stack findet sich auch hier: http://proggen.org/doku.php?id=c:die_sp ... _prozesses

Der Artikel mit einer genaueren Beschreibung fehlt leider noch...
Auf die Schnelle:
http://tutorial.proggen.org/doku.php?id=c:stack

Antworten