Fragen zu Arrays



  • Hallo an alle!

    Ich hab da als Übung für die Schule ein Lotto Programm programmiert. Der User muss die 6 Ziffern eingeben Danach die Zusatzzahl. Diese werden mit den, die der Computer erstellt hat verglichen. Wenn er etwas richtig hat wird es ihm mitgeteilt….

    Zu meinen Fragen:
    In zerlege() und übgebe ich ein 2 dimensionales char Array als Referenzparameter. Jedoch bin ich mir nicht sicher ob die Deklaration es Übergabeparameter stimmt: void zerlege(char user_tipp[], char tipp_array[7][3]); So wie es jetzt geschrieben ist, sieht man nicht so schnell das dies ein Referenzparameter ist. Kann man das auch anders schreiben??

    Noch eine Frage: Bei Übergabe eines eindimensionalen Arrays: void erzeuge_tipp(int *tipp) ist äquivalent zu void erzeuge_tipp(int tipp[]), oder???

    Wenn ihr den Code anschaut, welche Tipps könnt ihr mir noch geben??
    Den Code hab ich zum Schluss..

    Danke im Voraus

    Gruß Robert

    void convert(char user_tipp_array[][3], int *user_tipp_int);
    void zerlege(char user_tipp[], char tipp_array[7][3]);
    
    void lotto(void)
    {
    	char user_tipp[50], user_tipp_array[7][3] = {{0}}, zusatz[2];
    	int erst_tipp[7], user_tipp_int[7];
    
    	do
    	{
    		eingabe("\n\nBitte geben Sie Ihren Tipp\nein (6 Zahlen + "
    				"eine Zusatzzahl (Zahlenbereich 1 - 45))\n\nIhr Tipp: ", user_tipp);
    		printf("\nZusatzzahl: ");
    		gets(zusatz);
    
    		strcat(user_tipp, " ");
    		strcat(user_tipp, zusatz);
    
    		zerlege(user_tipp, user_tipp_array);
    		convert(user_tipp_array, user_tipp_int);
    	}
    	while(check_zahlen(user_tipp_int) == ERROR);
    
    	erzeuge_tipp(erst_tipp);
    
    	ueberpruefe_zahlen(user_tipp_int, erst_tipp);
    
    	printf("\n\nDie gezogenen Tipps lauten: ");
    	print_tipp(erst_tipp);
    
    	printf("\n\nIhr Tipp hat gelautet: ");
    	print_tipp(user_tipp_int);
    }
    
    void convert(char user_tipp_array[][3], int *user_tipp_int)
    {
    	char i;
    
    	for(i = 0; i < 7; i++)
    	{
    		user_tipp_int[i] = atoi(user_tipp_array[i]);
    	}
    }
    
    void zerlege(char user_tipp[], char tipp_array[7][3])
    {
    	char *ptr = user_tipp;
    	char zaehler_x = 0, zaehler_y = 0;
    
    	while(*ptr != 0)
    	{
    		if((*ptr >= 48) && (*ptr <= 57))
    		{
    			tipp_array[zaehler_x][zaehler_y] = *ptr;
    			zaehler_y++;
    		}
    		else
    		{
    			if(*ptr == 32)
    			{
    				zaehler_x++;
    				zaehler_y = 0;
    				}
    		}
    		ptr++;
    	}
    }
    


  • reduziere bitte deinen code auf einen beispielcode, der NUR dein problem darstellt.



  • Ich hoffe so ist es einfacher 🙂



  • Hab mal was geändert:

    typedef char (*Ptr)][3];
    
    void convert(Ptr user_tipp_array, int* user_tipp_int); 
    void zerlege(char* user_tipp, Ptr tipp_array); 
    
     memset()
    void lotto(void) 
    { 
        char user_tipp[50], user_tipp_array[7][3]/* = {{0}}* Fehler - nimm memset()*/, zusatz[2]; 
        int erst_tipp[7], user_tipp_int[7]; 
    
        do 
        { 
            eingabe("\n\nBitte geben Sie Ihren Tipp\nein (6 Zahlen + " 
                    "eine Zusatzzahl (Zahlenbereich 1 - 45))\n\nIhr Tipp: ", user_tipp); 
            printf("\nZusatzzahl: "); 
            gets(zusatz); 
    
            strcat(user_tipp, " "); 
            strcat(user_tipp, zusatz); 
    
            zerlege(user_tipp, user_tipp_array); 
            convert(user_tipp_array, user_tipp_int); 
        } 
        while(check_zahlen(user_tipp_int) == ERROR); 
    
        erzeuge_tipp(erst_tipp); 
    
        ueberpruefe_zahlen(user_tipp_int, erst_tipp); 
    
        printf("\n\nDie gezogenen Tipps lauten: "); 
        print_tipp(erst_tipp); 
    
        printf("\n\nIhr Tipp hat gelautet: "); 
        print_tipp(user_tipp_int); 
    } 
    
    void convert(Ptr user_tipp_array, int* user_tipp_int) 
    { 
        char i; 
    
        for(i = 0; i < 7; i++) 
        { 
            user_tipp_int[i] = atoi(user_tipp_array[i]); 
        } 
    } 
    
    void zerlege(char* user_tipp, Ptr tipp_array) 
    { 
        char *ptr = user_tipp; 
        char zaehler_x = 0, zaehler_y = 0; 
    
        while(*ptr != 0) 
        { 
            if((*ptr >= 48) && (*ptr <= 57)) 
            { 
                tipp_array[zaehler_x][zaehler_y] = *ptr; 
                zaehler_y++; 
            } 
            else 
            { 
                if(*ptr == 32) 
                { 
                    zaehler_x++; 
                    zaehler_y = 0; 
                    } 
            } 
            ptr++; 
        } 
    }
    

    ungetestet



  • in c heisst es zeiger oder pointer, nicht referenz. in C++ gibts referenzen, die aehnlich aber anders sind.

    zerlege() und convert() haette ich keinesfalls in extra funktionen gepackt. die funktionen sind zu winzig und unbedeutend.
    nimm scanf(), wenn du mehrere zahlen formatiert einlesen willst. ist sehr viel einfacher.

    kein gets! nimm fgets.

    was hat das rumfliegende "memset()" dort zu suchen? machs weg.

    was macht ueberpruefe_zahlen()? es gibt nichts zurueck und die argumente werden auch nicht veraendert. wenn die funktion UEBERHAUPT etwas als result hat, dann gib es mit return zurueck anstatt globale variablen zu missbrauchen.



  • Noch eine Frage: Bei Übergabe eines eindimensionalen Arrays: void erzeuge_tipp(int *tipp) ist äquivalent zu void erzeuge_tipp(int tipp[]), oder???
    

    Nein, das ist ein Unterschied. Bei der ersten Variante übergibst Du einen Zeiger int *tipp, bei der zweiten int tipp als Wert.
    Der Unterschied ist, daß tipp in einer Unterfunktion nur als lokale Variable existiert und nach der Rückkehr der Funktion ungültig wird. In der Ursprungsvariable steht immer noch der alte Wert.
    Bei der Zeigervariante greifst Du über den Zeiger direkt auf die Ursprungsvariable zu.
    Übrigens sollte Zeiger nicht den selben Namen haben wie die Referenz-Variable: Fehlergefahr. ich empfehle int *ptipp (p für Pointer = ungarische Notation).



  • Elektronix schrieb:

    Noch eine Frage: Bei Übergabe eines eindimensionalen Arrays: void erzeuge_tipp(int *tipp) ist äquivalent zu void erzeuge_tipp(int tipp[]), oder???
    

    Nein, das ist ein Unterschied. Bei der ersten Variante übergibst Du einen Zeiger int *tipp, bei der zweiten int tipp als Wert.

    Es ist ja nicht so, als ob der Zeiger selber nicht auch nur kopiert wird... C kennt kein "echtes" Call by Reference wie man es z.B. in C++ hat.

    Der Unterschied ist, daß tipp in einer Unterfunktion nur als lokale Variable existiert und nach der Rückkehr der Funktion ungültig wird. In der Ursprungsvariable steht immer noch der alte Wert.
    Bei der Zeigervariante greifst Du über den Zeiger direkt auf die Ursprungsvariable zu.

    Wenn du in der Funktion tipp[0] = 7; schreibst, funzt das bei beiden Varianten. Änderungen am Zeiger selber werden allerdings verworfen.

    Übrigens sollte Zeiger nicht den selben Namen haben wie die Referenz-Variable: Fehlergefahr. ich empfehle int *ptipp (p für Pointer = ungarische Notation).

    Ich nicht. Über Ungarische Notation lässt sich sicher streiten, aber ich bin der Meinung, dass man ohne sie auskommt. Was soll schon für eine Namensverwechslung vorkommen, wenn man sauber (Kapselung usw., oop ansatz halt) programmiert?

    MfG

    GPC



  • GPC schrieb:

    Es ist ja nicht so, als ob der Zeiger selber nicht auch nur kopiert wird... C kennt kein "echtes" Call by Reference wie man es z.B. in C++ hat.

    Stimmt schon, aber der Zeiger bzw. dessen Kopie enthält nur die Adresse der Referenzvariable. Die Adresse wird nicht geändert, als wird über den Zeiger auf die Originale Variable im Hauptprogramm zugegriffen. Bei Übergabe als Wert wird nur die lokale Variable geändert, die Variable im Hauptprogramm aber nicht. Das kann zu Verwirrung führen.

    Was soll schon für eine Namensverwechslung vorkommen, wenn man sauber (Kapselung usw., oop ansatz halt) programmiert?

    Generell ist das natürlich Geschmacksache. Aber abgesehen davon, daß Kapselung und OOP Sachen für C++ und nicht für Ansi-C sind, hat Razer_6 vermutlich nicht genügend Erfahrung, um zu beurteilen, was "saubere Programmierung" ist. Sonst würde er nicht nach den Zeigern und Arrays fragen.



  • Elektronix schrieb:

    GPC schrieb:

    Es ist ja nicht so, als ob der Zeiger selber nicht auch nur kopiert wird... C kennt kein "echtes" Call by Reference wie man es z.B. in C++ hat.

    Stimmt schon, aber der Zeiger bzw. dessen Kopie enthält nur die Adresse der Referenzvariable. Die Adresse wird nicht geändert, als wird über den Zeiger auf die Originale Variable im Hauptprogramm zugegriffen. Bei Übergabe als Wert wird nur die lokale Variable geändert, die Variable im Hauptprogramm aber nicht. Das kann zu Verwirrung führen.

    Äh, nö:

    #include <stdio.h>
    
    void foo(int *i) {
      i[0] = 7;
    }
    
    void bar(int i[]) {
      i[0] = 8;
    }
    
    int main(int argc, char **argv) {
      int array[2];
      foo(array);
      printf("%i\n", array[0]);
    
      bar(array);
      printf("%i\n", array[0]);
      return 0;
    }
    

    Ausgabe:
    7
    8

    Auch bei der int i[] Variante ändert man durchaus das "Original"

    Was soll schon für eine Namensverwechslung vorkommen, wenn man sauber (Kapselung usw., oop ansatz halt) programmiert?

    Generell ist das natürlich Geschmacksache. Aber abgesehen davon, daß Kapselung und OOP Sachen für C++ und nicht für Ansi-C sind,

    Geht auch in C wunderbar (inkl. Polymorphie usw.), dass GTK+ Toolkit beweist das 😉



  • Auch bei der int i[] Variante ändert man durchaus das "Original"

    Äächnartisch 😕 . Da hab ich was anderes gelernt. Werd ich nochmal überprüfen.

    Geht auch in C wunderbar (inkl. Polymorphie usw.), das GTK+ Toolkit beweist das

    Hmm, interessant. Das will ich mir mal ansehen. Wo gibts das bzw. entsprechenden Beispielcode?



  • Dieses Buch könnte dich interessieren.


Anmelden zum Antworten