Was passier thier genau???



  • Also ich bin total am verzweifeln und zwar geht es wie meistens um diese dummen Zeiger:-)

    Einführungsfrage:
    Was passiert hier genau?

    int *pa = 5;
    

    Hier pa zeigt automatisch auf irgendetwas vom Typ int im Speicher und setzt dort den Wert 5 ein????
    Dies dürfte doch garnicht gehen oder??? Ich weise noch nicht mal ne Adresse zu!
    Dies müßte zu diesem analog sein: int *pa;
    *pa = 5;
    oder?

    OK was zum Teufel ist das hier dann?

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
       char string[10];
       char *str1 = "abcdefghi"; //diese Zeile bringt mich so krass durcheinander!!
    
       strcpy(string, str1);
       printf("%s\n", string);
       return 0;
    }
    

    Diese eine Zeile wie ist diese zu interpretieren im Zusammenhang mit dem Speicher und in Verbindung mit einem anderen Datentyp wie oben int???

    Hier kommt dann im Anschluß mein größtes Problem:
    Es geht hauptsächlich um verkettete Listen.

    ---------------------------------------------------------------------
    #include <iostream.h>
    #include <string.h>
    
    struct Person
    {
        char name[20];
        int zahl;
        Person *next;
    };
    struct Schlange
    {
        Person *first;
        Person *last;
    };
    

    anschließend kommt das main Programm und ich möchte einfach per Funktionsaufruf Parameter übergeben!

    Schlange Kasse; 
    add_back(110, "Peter", &Kasse);
    
    void add_back(int pzahl, string pname, Schlange *Kasse)
    {
        Person *tmp;
    
        if(Kasse->first == NULL && Kasse->last == NULL)
        {
            tmp = new Person;         
            strcpy(tmp->name, pname); //hier entsteht ein Problem
            tmp->zahl = pzahl;
            tmp->next = NULL;         
    
            Kasse->first = tmp;
            Kasse->last = tmp;
    
            counter++;
        }
    }
    ----------------------------------------------------------------
    

    Ich möchte kurz gesagt unabhängig ob das Sinn macht oder nicht den Namen übergeben und ihn dann in das charfeld reinpacken.

    Bitte Bitte um Hilfe!!!

    /edit von davie: Bitte Code Tags verwenden



  • Also...

    int *pi = 5;

    Weiß nicht, ob das geht

    char* text = "fjdkjafdks"

    Das geht, bei char is ne Ausnahme, da wird bei einern direkten Zuwesiung automatisch Speicher belegt. Ist ja gleichwertig zu

    char text[] =" jfdsk fjksdfj"

    ALso Array,wird auch automatisch belegt

    zum zweiten Problem:

    Du versuchst, ein String-Objekt in ein char* zeiger umzuwandeln...
    Das geht niatürlich nicht.
    Mach es so:

    strcpy(temp->name, pname->c_str());

    PS: Deine Funktin add_back macht irgendwie keinen sinn, sie reserviert zwar Speicher, legt aer das Element sowohl an den Anfang als auch ans Ende der Liste...

    Gruß, Maxi



  • tomekdomek schrieb:

    int *pa = 5;
    

    das geht nicht, da du einen int * keinen const int (5) zuweisen kannst, merke int* != int !

    #include <stdio.h>
    #include <string.h>
    
    int main(void)
    {
       char string[10];
       char *str1 = "abcdefghi"; //diese Zeile bringt mich so krass durcheinander!!
    
       strcpy(string, str1);
       printf("%s\n", string);
       return 0;
    }
    

    wie mein vorgänger schon sagte ist char* unteranderem eine ausnahme, hier wird direkt speicher für abcdefghi initialisiert!

    ---------------------------------------------------------------------
    #include <iostream.h>
    #include <string.h>
    
    struct Person
    {
        char name[20];
        int zahl;
        Person *next;
    };
    struct Schlange
    {
        Person *first;
        Person *last;
    };
    


  • int *pi = 5;
    geht nicht. Du kannst einem Zeiger keine konstante (außer 0) zuweisen ohne den Compiler zu zwingen (=casten).

    Maxi2 schrieb:

    char* text = "fjdkjafdks"

    Das geht, bei char is ne Ausnahme, da wird bei einern direkten Zuwesiung automatisch Speicher belegt. Ist ja gleichwertig zu
    char text[] =" jfdsk fjksdfj"

    Nein. char* text = "csacs"; geht eigentlich nicht. Richtig ist const char* text = "csacs" oder char text[] = "csacs".

    p.s.:
    Übergib den string an die Funktion add_back besser by reference, also mit "const string&" als Typ. Das ist schneller und einfach zu verstehen (du willst den String ja nicht ändern).
    Außerdem meinte Maxi2 wahrscheinlich pname.c_str() und nicht pname->c_str(). Das p irritiert (Stichwort Ungarische Notation).



  • Die addback sieht so aus und meiner Meinung nach in Ordnung:

    void add_back(int pzahl, char* pname, Schlange *Kasse)
    {
        Person *tmp;
    
        if(Kasse->first == NULL && Kasse->last == NULL)
        {
            tmp = new Person;         //Dynamisches Reservieren von Speicherplatz
                                      //für einen Datentyp Person (neue "Person")
            strcpy(tmp->name, pname);
            tmp->zahl = pzahl;
            tmp->next = NULL;         //Setzen der Nachfolgeradresse auf NULL
    
            Kasse->first = tmp;
            Kasse->last = tmp;
    
            counter++;
        }
        else
        {
          tmp = new Person;
          tmp->zahl = pzahl;
    
          Kasse->last->next = tmp;  //nachträgliches setzen der  Nachfolgeradresse
                                    //der ersten "Person" auf die neuerzeugte Person
          Kasse->last = tmp;        //die neue "Person" ist automatisch letzter
    
          counter++;
        }
    
    }
    

    Habe es mit Zahlen am Anfang nur gemacht und alles hat gefunzt. Jetzt soll es aber zusätzlich mit Namen gemacht werden!

    char* text <<ist doch nicht gleich>> char *text
    ???



  • Wir sind hier doch im C++ Forum, oder? 😉
    Nimm also bitte std::string anstelle char* (es müsste wenn überhaupt eh const char* heißen...).

    Doch char* Text ist das selbe wie char *Text. const char * Text ist auch das selbe wie char const * Text.



  • int* p = 5; //oder int *p = 5; - dasselbe
    

    geht nicht, da 5 vom typ int ist und p vom typ int*. Wenn, dann müsstest du casten:

    int* p = reinterpret_cast<int*>(5);
    

    und dann ist "5" nicht der Wert, der auf irgendeine Speicheradresse gelegt wird, sondern die Nummer der Speicheradresse selbst.
    Die einzige "Zahl" die du einem Zeiger zuweisen darfst ist 0 (aka NULL) da diese automatisch in einen Nullzeiger umgewandelt wird.

    char *x = "Ein String";
    

    Das ist zwar erlaubt, aber irreführend.
    "Ein String" ist nämlich konstant.
    Korrekterweise sollte es heißen:

    const char *x = "Ein String";
    

    Der String "Ein String" kann als const char * aufgefasst werden, und soll daher nur einem const char * zugewiesen werden. Durch Gründe, die die nicht interessieren dürften, ist es allerdigns auch möglich "Ein String" einem einfach char* zuzuweisen. Diesen allerdings dann zu dereferenzieren solltest du nicht versuchen.

    Allerdings ist cd9000s Tip, einen std::string zu verwenden hundertmal besser als dieses raw-char* herumgetue.

    Außerdem heißen die header nach "neuem" standard <iostream> (ohne h) und <cstring>. die standardklasse string findest du in <string>.

    /edit: uff... viel zu spät geantwortet..



  • hmm ja wollte ich aber der Ausbilder will das ich es erstmals nur mit char mache und net mit string aber Danke!!!

    EIn danke an Euch beide aber eine Sache qüält mich noch und zwar dieses Sternchen steht doch für Zeiger!!!

    Also was passiert hier genau:Hab es ein bissel umgeändert aber checken tue ich es net genau bei der Übergabe!

    #include <vcl.h>
    #include <stdio.h>
    #include <iostream.h>
    #include <string.h>
    
    struct Person
    {
        char name[20];
        int zahl;
        Person *next;
    };
    
    struct Schlange
    {
        Person *first;
        Person *last;
    };
    
    void add_back (int pzahl, char *pname, Schlange *Kasse);
    
    int counter;
    
    void main()
    {
        Schlange Kasse;          // Erstellen einer Variable des Datentyps Schlange
    
        Kasse.first = NULL;
        Kasse.last = NULL;
    
        add_back(110, "Peter", &Kasse);
    
        getchar();
    }
    
    void add_back(int pzahl, char *pname, Schlange *Kasse)
    {
        Person *tmp;
    
        if(Kasse->first == NULL && Kasse->last == NULL)
        {
            tmp = new Person;         //Dynamisches Reservieren von Speicherplatz
                                      //für einen Datentyp Person (neue "Person")
            strcpy(tmp->name, pname);
            tmp->zahl = pzahl;
            tmp->next = NULL;         //Setzen der Nachfolgeradresse auf NULL
    
            Kasse->first = tmp;
            Kasse->last = tmp;
    
            counter++;
        }
        else
        {
          tmp = new Person;
          tmp->zahl = pzahl;
    
          Kasse->last->next = tmp;  //nachträgliches setzen der  Nachfolgeradresse
                                    //der ersten "Person" auf die neuerzeugte Person
          Kasse->last = tmp;        //die neue "Person" ist automatisch letzter
    
          counter++;
        }
    
    }
    

    Wäre super wenn einer mir das in seinen eigenen Worten erklärt.
    Ich fang mal an und höre dann automatisch auf:-)
    Also ich übergebe einen Zeiger pname vom Typ char an die addback Funktion!
    Aber es sind doch mehrere char (Peter).....
    und wieso muß es so lauten strcpy(tmp->name, pname);
    und net ...strcpy(tmp->name, *pname);???



  • du übergibst pname als Zeiger auf char.
    Ein C-String (zb "foo") ist im Speicher so abgelegt:

    Speicherzelle  0  1  2  3 
    Inhalt         f  o  o \0
    

    wenn du jetzt folgenden code hast

    const char *x = "foo";
    

    dann zeigt x auf die 1. Speicherstelle (oben die Speicherstelle '0')
    wenn du jetzt x derefenzierst, und den inhalt ausgibst

    cout << *x << endl;
    

    erhältst du als ausgabe 'f'. Mehr nicht.
    wenn du x jetzt (als zeiger) inkrementierst

    ++x;
    

    zeigt x auf die nächste speicherstelle (mit dem inhalt 'o').

    strcpy macht jetzt nichts anderes, als

    void strcpy (char *ziel, const char *quelle) {
      while (*ziel++ = *quelle++);
    }
    

    solange quelle nicht '\0' (wert 0) ist, wird dem ziel ein char zugewiesen.
    char für char, bis eben zum ende vom string (die 0)
    deshalb belegen c-strings auch immer einen speicherplatz mehr, als wenn man nur die tatsächlich ausgegebenen buchstaben zählen würde.

    Kurz: den const char* den du an deine Funktion übergibst ist nur ein zeiger auf den ersten character deines (C-)Strings.

    ps
    verwende trotzdem die standardisierten header <iostream> und <cstring> und <cstdio>. darunter noch ein "using namespace std" um die namen sichtbar zu machen. wenn dir das jetzt alles noch nichts sagt, mach's trotzdem und informiere dich über namespaces



  • zu guter letzt
    und wieso muß es so lauten strcpy(tmp->name, pname);
    und net ...strcpy(tmp->name, *pname);???

    Da die Funktion strcpy es von alleine dereferenziert???

    Supi jetzt macht einiges Sinn.
    Danke vielmals!!!

    Ich werde bestimmt wie ich mich kenne bald mit nem neuen Zeigerproblem kommen aber erstmals is alles jut.


Log in to reply