mikrocontroller.net

Forum: PC-Programmierung c++: verstehe Zeiger-Konzept nicht


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
Autor: ccccc++ (Gast)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
Folgender Code macht mein Verständnisproblem deutlich:
#include <iostream>
#include <conio.h>

using namespace std;

int main(void)
{
    int a;
    
    /*
     _Speicherzellen_______________ _____________
     |  [1]  |  [2] |  [3] |  [4] |  [5]  |  [6] |
     |  127  |  42  |   7  | 1024 | 31415 | 1337 |
     |_______|______|______|______|_______|______|
    */
    
    //Adresse ausgeben
    cout << "Adresse von a: " << &a << endl;
    
    //Datentyp, der Adressen speichert: Zeiger (Pointer)
    int *zeigerAufA = &a;
    
    cout << "Fuer die erste Methode 1 eingeben\n"
         << "Fuer die zweite Methode 2 eingeben\n";
         
    char eingabe;
    do {
        eingabe = getch();//Buchstabe von Tastatur abfangen (ohne ENTER)
        
        if(eingabe == '1') {
            a = 7;
            cout << "a = " << a << endl;
        } else if (eingabe == '2') {
            *zeigerAufA = 42;
            //*zeigerAufA = &a;
            cout << "a = " << a << endl << endl;
            cout << "zeigerAufA = " << zeigerAufA << endl;//zeigerAufA (ADRESSE)
            cout << "*zeigerAufA = " << *zeigerAufA << endl;//*zeigerAufA (WERT)
        } else {
            return 0;
        }
        
    } while((eingabe == '1') || (eingabe == '2'));
    
    return 0;

}
Oben im Programm wird "*zeigerAufA" eine Adresse nämlich "&a" 
zugewiesen. Weiter unten wird demselben Objekt eine Zahl und zwar "42" 
zugewiesen.
1) *zeigerAufA = &a;
2) *zeigerAufA = 42;
Wenn ich im Programmtext unter "*zeigerAufA = 42;" nochmals das 
auskommentierte "*zeigerAufA = &a;" einfüge, läuft dieses beim ersten 
Auftreten (oben) unter Dev C++ problemlos durch den Compiler, während es 
beim zweiten Auftreten (unten) angemeckert wird.
"[Error] invalid conversion from 'int*' to 'int' [-fpermissive]"

Das Programm stammt aus einem Youtube Video.[1] Da erwähnt der Verfasser 
zwar bei Minute 9:05, dass das Sternchen unten nicht das gleiche ist, 
wie das oben. Aber er erklärt den Unterschied nicht so richtig.

Wieso funktioniert der gleiche Befehl oben im Programm und unten nicht?

Funktioniert das Ganze auch unter C (ohne ++)?

[1] Youtube-Video "C++ Crashkurs für Anfänger in 2 Std [12/14] | ZEIGER/POINTER"

Autor: NichtWichtig (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
*zeigerAufA = &a; // ist ja auch falsch
Da wird versucht die Adresse von A an die int-Speicherstelle zu 
schreiben wo zeigerAufA hinzeigt.

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
1 lesenswert
nicht lesenswert
ccccc++ schrieb:
> 1) *zeigerAufA = &a;
> 2) *zeigerAufA = 42;

Nein. Die erste Zuweisung ist keine, sondern eine Deklaration mit 
nachfolgender Initialisierung.

Dabei wird der Pointer nicht derefernziert; der "*"-Operator wirkt sich 
nur auf die Deklaration, nicht aber die Initialisierung aus.

Effektiv bedeutet
    int *zeigerAufA = &a;

das gleiche wie
    int *zeigerAufA;
    
    zeigerAufA = &a;

Genau: Bei der zweiten Zeile entfällt der "*"-Operator!

Autor: Oliver S. (oliverso)
Datum:

Bewertung
1 lesenswert
nicht lesenswert
YouTube - Videos sind klasse, leider nicht alle.

Auch wenn das jetzt völlig old-School rüberkommt, ist in diesem Fall 
eine sequentielle Buchstabensammlung besser zur Wissensvermittlung 
geeignet. Früher nannte ma das Buch, heute gibt es sowas auch online.

Da könntest du dann nachlesen, wie man auf einen Zeiger, und wie man auf 
den Wert, auf den der Zeiger zeigt, zugreift. Der *-Operator ist, wie du 
schon erkannt hast, das Stichwort.

Ach ja, das Verhalten ist in diesem Fall unter C und C++ gleich.

Oliver

Autor: Wilma Streit (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Bin auch kein Profi und der Fehler ist mir so erstmal nicht aufgefallen. 
Aber dafür gibt es ja die Fehlermeldungen und die ist doch eindeutig. :)

Autor: rµ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Etwas übersichtlicher ist es wenn man solche Deklarationen so
int* zeiger = &a;
int& ref = a;

schreibt, also *, & zum Typ dazu, und sich auf eine Deklartion pro 
Statement beschränkt.

Autor: Dussel (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wurde eigentlich schon gesagt, aber noch nicht von jedem. ;-)

'*' hat (mindestens) zwei unterschiedliche Bedeutungen/Funktionen.
Bei der Definition, also
int *Zeiger
bzw.
int* Zeiger
zeigt * an, dass 'Zeiger' kein Integer ist, sondern ein Zeiger auf einen 
Integer.

Bei der Zuweisung
*Zeiger=...
zeigt * an, dass du nicht auf 'Zeiger' selber schreiben, also die 
Adresse ändern, willst, sondern dass du die Speicherzelle, auf die der 
Zeiger zeigt ändern willst.

Also merk dir, dass * in dem Beispiel in zwei unterschiedlichen 
Bedeutungen verwendet wird.

Autor: ccccc++ (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:
> Effektiv bedeutet
> int *zeigerAufA = &a;
>
> das gleiche wie
> int *zeigerAufA;
> 
> zeigerAufA = &a;

Diese Erklärung durchschlägt den Knoten, der mir als OP trotz x Anläufen 
immer wieder den vollständigen Durchblich beim Zeigerkonzept verhagelte. 
Vielen Dank!

Das zitierte Programm aus Youtube hat beim Herausfinden geholfen, wie 
überhaupt die Frage lauten musste.

Autor: Dirk B. (dirkb2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal logisch gedacht:

int *zeigerAufA = &a;

ist ja eine Definition mit Initialisierung.
Der Zeiger wird angelegt und bekommt zum ersten mal einen Wert 
zugewiesen.
Das einzig sinnvolle ist eine Adresse.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.