auf strukturelemente zugreifen



  • ja deshalb ist das +1 da.
    steht auch in der API, dass die monate von 0 bis 11 gehen, genau wie die minuten und sekunden (oder so)

    ist halt das typische programmierer zählen: von 0 bis n-1



  • Cool, jetzt weiß ichs ! 🙂

    noch eine sache ( will dafür nicht extra noch ein thema machen)

    static char *MonatsName[13] = {" ", "Jan", "Feb", "Mar", "Apr",
    						  "Mai", "Jun", "Jul", "Aug",
    						  "Sep", "Okt", "Nov", "Dez"};
    
    	// Gib Jan Feb Mar Apr etc. zurück
    char *Datum::HoleMonatsName(void)
    {
       return MonatsName[Monat];
    }
    
    	// Gib eine ASCII-Z Zeichenfolge mit dem gespeicherten Fromat zurück
    	//   Format = 1	Aug 29, 1991
    	//   Format = 2	29.8.91
    	//   Format = 3	29.8.1991
    	//   Format = 4	29 Aug 1991       Militärsiche Zeit
    	//   Format = ?	Alles andere wird als Format 1 interpretiert
    char *Datum::HoleFormatiertesDatum(void)
    {
       switch (Format)
       {				// Diese Ausgabe nimmt an, dass das Jahr
    				// zwischen 1970 und 2069 liegt
    	case 2  : sprintf(AusStrom, "%02d.%02d.%02d",
    							  Tag, Monat, Jahr - 1970);
    		    break;
    
    	case 3  : sprintf(AusStrom, "%02d.%02d.%04d",
    								   Tag, Monat, Jahr);
    		    break;
    
    	case 4  : sprintf(AusStrom, "%d %s %04d",
    						   Tag, MonatsName[Monat], Jahr);
    		    break;
    
    	case 1  : // Weiter zu default
    	default : sprintf(AusStrom, "%s %d, %04d",
    						   MonatsName[Monat], Tag, Jahr);
    		    break;
       }
       return AusStrom;
    }
    

    Kann mir einer hier die verwendung der zeiger erklären und dazu noch, wieso überhaupt zeiger und nicht normale variablen?



  • Meinst Du die **char ***?
    Ein char kann nur ein Zeichen halten.
    Du willst aber eine Kette von Zeichen verarbeiten. Also nimmt man einen Zeiger auf das erste Zeichen. Das Kettenende wird durch ein Nullbyte gekennzeichnet (bei verwendung von "" implizit).



  • die zeiger sind doch aber in erster linie auf funktionen gerichtet, heißt das, dass hier nur der ausgabetyp der funktion der grund für die verwendung von zeigern ist?



  • Die Frage verstehe ich nicht.
    Und welche Funktion meinst Du?



  • Er mein z. Bsp. HoleMonatsName welche ein char* zurückgibt. Wenn diese Funktionen statt dessen std:.string zurückgeben würden bräuchte man keine Zeiger.



  • @Braunstein: Danke.
    @Flub:
    Es gibt verschiedene Gründe für die Verwendung von Zeigern.
    In dem von Dir gebrachten Beispiel verwendest Du C-Strings (alias char-Arrays), die kannst Du nur via Zeigern referenzieren.
    Wenn Du, wie Braunstein erwähnte, stattdessen std::String verwendetest könntest Du ohne Zeiger auskommen. Aber nur, weil std::string das intern für dich übernimmt.



  • genau, ich meinte z.B. in zeile 6.
    Ich habe irrtümlicherweise Funktion statt Methode geschrieben, also dort wird die methode HoleMonatsName implementiert, das Sternchen ist allerdings vor dem Namen der Methode, weshalb ich an Funktionszeiger gedacht habe.

    Kann man also immer wenn eine Methode eine Zeichenkette als Rückgabewert liefert

    char *methode(...
    

    im prototyp und in der implementation schreiben?

    EDIT:wir waren gleichzeitig am schreiben...

    Woher weiß der compiler, dass es überhaupt eine Zeichenkette (char-array ist) wenn es laut char *methode, genauso ein zeiger auf einen char sein könnte?



  • Flub schrieb:

    Kann man also immer wenn eine Methode eine Zeichenkette als Rückgabewert liefert

    char *methode(...
    

    im prototyp und in der implementation schreiben?

    Wenn's ein C-String sein soll, kannst Du nicht, Du mußt.

    Flub schrieb:

    Woher weiß der compiler, das es überhaupt eine Zeichenkette (char-array ist) wenn es laut char *methode, genauso ein zeiger auf einen char sein könnte?

    Die Frage ist falsch.
    Es ist ein Zeiger auf einen char - Punkt. Du entscheidest, wie Du ihn verwendest.



  • Eine Funktion, die einen char* ausgeben soll etc. handelt damit eben ganz besonders:

    Sie geht auf das Element, auf welches char* zeigt (also den char), und gibt diesen aus. Jetzt geht die Funktion davon aus, dass an der Speicheradresse direkt nach dem Zeiger wieder ein auszugebendes Zeichen ist und gibt das auch aus. Solange bis \0 kommt.
    Man könnte das auch so schreiben:

    void output(const char* str)
    {    
        if(*str != '\0')
        { 
            do
            {
                std::cout << *str;
            }while(*(++str) != '\0')
        }
    }
    


  • Man muß hier lediglich beachten, dass char* kein normaler Zeiger ist, sondern dass es hier diverse Sonderbehandlungen (siehe Streams) gibt. Hierbei wird char* im Allgemeinen als Zeichenkette interpretiert und auch so verwendet. Deswegen setzt man char* häufig mit einer Zeichenkette gleich. Siehe auch alle Funktionen aus cstring. Dies ist natürlich eine Altlast aus C.



  • Eisflamme schrieb:

    Man könnte das auch so schreiben:

    void output(const char* str)
    {    
        if(*str != '\0')
        { 
            do
            {
                std::cout << *str;
            }while(*(++str) != '\0')
        }
    }
    

    Auch bekannt als das komplizierte if/do-Konstrukt.

    void output(const char* str)
    {    
        while(*str != '\0')
        { 
            std::cout << *str;
            ++str;
        }
    }
    


  • Man sehe es mir nach, ich war noch halb am schlafen. ^^



  • Spricht eigentlich irgendetwas gegen

    std::cout << *str++;
    

    ?



  • hm...



  • Caligulaminus schrieb:

    Spricht eigentlich irgendetwas gegen

    std::cout << *str++;
    

    ?

    Ich verwende eigentlich nie sowas, wenn ich das Auslesen und das Inkrementieren auch auf zwei Zeilen packen kann.
    Früher schrieb ich auch mit Spaß Sachen wie

    while(!++*d++);//Vaxerzragvreg rvar Ynatmnuy zvg avrqrejregvtfgrz HVag mhrefg.
    

    , viel schlimmer noch, ich konnte nicht anders.



  • volkard schrieb:

    while(!++*d++);//Vaxerzragvreg rvar Ynatmnuy zvg avrqrejregvtfgrz HVag mhrefg.
    

    , viel schlimmer noch, ich konnte nicht anders.

    LOL - und da weisst du nach nem halben Jahr noch was es tut? Übrigens hast du vergessen das rot13 zu salzen *eg*



  • Argh!

    Dann ist hier d ein int(32)* das auf die untere Hälfte eines int(64) zeigt um hinterher nach inkrementierung dieser auf die obere zu zeigen?

    Habe ich das richtig verstanden?

    ~P.S.: Wird man für sowas eigentlich gefeuert, oder ist das eine effektive Jobsicherung?~



  • Caligulaminus schrieb:

    Dann ist hier d ein int(32)* das auf die untere Hälfte eines int(64) zeigt um hinterher nach inkrementierung dieser auf die obere zu zeigen?

    Ja, den Ausdruck haste gelöst, aber das while vergessen. Es seollte nicht auf int64 beschrängt sein, sondern für int32[1000] gehen, das Inkrementieren stoppt, sobald einmal kein Übertrag geschieht, was auch vorher sichergestellt wird. Also das while hast Du nicht beantwortet.



  • Da hakt's noch...

    Dann bezöge sich das vordere ++ auf d, das ! aber auf *d.

    Bisher war meine Reihenfolge:
    - postfix ++ auf *d
    - präfix ++ auf d
    - und dann !d

    Wo liege ich falsch?


Anmelden zum Antworten