Frage zu Typedef



  • Hallo,
    ich lerne gerade C++ neu und bin gerade bei typedef und structen angekommen. Hier mein Code:

    #include <iostream>
    
    typedef struct emp_struct
    {
    	char name[10];
    	int employee_no;
    	float salary, tax_to_date;
    } Employee;
    
    typedef Employee Database[10];
    
    void swap(char* string1, char* string2, int str_size)
    {
    	char* temp = (char*)malloc(str_size);
    	*temp = *string2;
    	*string2 = *string1;
    	*string1 = *temp;
    	cout << "true\n";
    }
    
    void sort(Database people[], int n, int str_size)
    {
    	int i, j;
    
    	for (i = 0; i < n - 1; i++)
    		for (j = i + 1; j > 0; j--)
    			if (strcmp(people[j]->name, people[j - 1]->name) < 0)
    				swap(people[j]->name, people[j - 1]->name, str_size);
    			else if (strcmp(people[j]->name, people[j - 1]->name) == 0)
    				if  (people[j]->employee_no < people[j - 1]->employee_no)
    					swap(people[j]->name, people[j - 1]->name, str_size);
    }
    
    int main()
    {
    	Database people = /*initializer: real DB would read from disk*/
    	{ {"Fred", 10, 10000, 3000},
    	{"Jim", 9, 12000, 3100.5},
    	{"Fred", 13, 1000000, 30},
    	{"Mary", 11, 170000, 40000},
    	{"Judith", 45, 130000, 50000},
    	{"Nigel", 10, 5000, 1200},
    	{"Trevor", 10, 20000, 6000},
    	{"Karen", 10, 120000, 34000},
    	{"Marianne", 10, 50000, 12000},
    	{"Mildred", 10, 100000, 30000}
    	};
    
    	sort(people, 10, 10); /*Hier ist der Fehler*/
    }
    

    Mein Compiler gibt die Fehlermeldung: Das Argument vom Typ ""Employee *"" ist mit dem Parameter vom Typ ""Database *"" inkompatibel.
    Meine Frage ist: Warum ist "people" vom Typ "employee" und nicht "Database", wenn ich es doch vorher als Database initialisiert habe?
    LG H.P.Wurst



  • @H-P-Wurst Du hast bei den typedefs die Übersicht verloren.

    Warum ist people in Zeile 21 ein Array of Database (was ein Array of Employee ist)?



  • @H-P-Wurst sagte in Frage zu Typedef:

    Hallo,
    ich lerne gerade C++ neu und bin gerade bei typedef und structen angekommen.

    Mit welchem Material, wenn man fragen darf? Das sieht ja alles ziemlich merkwürdig aus, so schreibt man kein C++. typedef benutzt man in C vielleicht so, aber nicht in C++.

    typedef Employee Database[10];
    Mein Compiler gibt die Fehlermeldung: Das Argument vom Typ ""Employee *"" ist mit dem Parameter vom Typ ""Database *"" inkompatibel.
    Meine Frage ist: Warum ist "people" vom Typ "employee" und nicht "Database", wenn ich es doch vorher als Database initialisiert habe?

    people ist vom Typ Database, aber Database ist ja gar kein eigenständiger Typ, sondern ein Typalias auf Employee[30]. Erwartet wird von der sort-Funktion jedoch ein Zeiger auf Database, also ausgeschrieben ein (*Employee)[30].

    Warum dein Compiler die Fehlermeldung so ausgibt, weiß ich auch nicht, aber es ist klar, dass die Typen nicht zusammenpassen.

    Über die swap-Funktion muss man auch nochmal reden, das geht so einfach mal überhaupt gar nicht. Nicht nur allozierst du darin Speicher mit malloc, den du nie wieder freigibst, du tauschst auch jeweils nur das erste Zeichen aus, und ... vergiss es einfach. Wegschmeißen, mehr C++ lernen, nochmal versuchen.



  • Ich verstehe den Unterschied zwischen C und C++ noch nicht ganz.
    Das Problem mit people ist jetzt gelöst. Wie kann man die swap-Funktion:

    void swap(char* string1, char* string2, int str_size)
    {
    	char* temp = (char*) malloc(str_size);
    	*temp      = *string2;
    	*string2   = *string1;
    	*string1   = *temp;
    }
    

    denn besser machen?



  • @DirkB Danke!



  • Das hier? https://www.slideshare.net/princebhau/programming-c-and-c-in-five-days

    Copyright 1994. Vergiss es. Such dir was besseres. Im Ernst.

    @H-P-Wurst sagte in Frage zu Typedef:

    Ich verstehe den Unterschied zwischen C und C++ noch nicht ganz.

    Musst du doch auch nicht. Willst du C oder C++ lernen?

    Wie kann man die swap-Funktion:

    void swap(char* string1, char* string2, int str_size)
    {
    	char* temp = (char*) malloc(str_size);
    	*temp      = *string2;
    	*string2   = *string1;
    	*string1   = *temp;
    }
    

    denn besser machen?

    Das Interface lässt keine richtige Lösung zu, da für die beiden Strings nur eine gemeinsame Länge angegeben werden kann. Es wäre ohnehin besser, std::string statt char-Arrays zu verwenden, dann löst sich das Problem auch ganz von selbst.



  • @H-P-Wurst Habs jetzt so:

    void swap(char* string1, char* string2, int str_size)
    {
    	char* temp = (char*) malloc(str_size);
    	temp       = string2;
    	strcpy_s(string2, str_size, string1);
    	strcpy_s(string1, str_size, temp);
    }
    


  • @H-P-Wurst sagte in Frage zu Typedef:

    char* temp = (char*) malloc(str_size);
    temp = string2;

    wozu das malloc, wenn du das Ergebnis gleich wieder mit string2 überschreibst?
    Da wird kein Inhalt kopiert.
    zudem gehört zu jedem malloc auch ein free!



  • @Bashar sagte in Frage zu Typedef:

    ich lerne gerade C++ neu und bin gerade bei typedef und structen angekommen.

    Du lernst C.
    Du lernst kein C++ (zumindest deinen Codebeispielen zufolge).

    @H-P-Wurst sagte in Frage zu Typedef:

    #include <iostream>

    Das lässt vermuten, dass du einen C++ Compiler zum Lernen von C benutzt; das ist komplett sinnfrei und gerade für einen Lernenden schlecht.



  • @Wutz Also ich benutze Visual Studio 2020. Wie kann ich denn bei VS einen C-Compiler benutzen?



  • @Bashar sagte in Frage zu Typedef:

    Willst du C oder C++ lernen?



  • @H-P-Wurst sagte in Frage zu Typedef:

    @Wutz Also ich benutze Visual Studio 2020. Wie kann ich denn bei VS einen C-Compiler benutzen?

    Indem du die Source-Datei mit der Endung .c abspeicherst oder in den Compiler Optionen das entsprechend einstellst.



  • @Swordfish Das Skript mit dem ich arbeite ist aufgeteilt in einen C- und einen C++ Teil. Momentan bin ich noch im C-Teil



  • Also so funktioniert es jetzt:

    #include <stdio.h>
    
    typedef struct emp_struct
    {
    	char name[10];
    	int employee_no;
    	float salary, tax_to_date;
    } Employee;
    
    typedef Employee Database[10];
    
    void swap(Employee* emp1, Employee* emp2)
    {
    	Employee temp;
    	temp = *emp1;
    	*emp1 = *emp2;
    	*emp2 = temp;
    }
    
    void sort(Database people, int n, int str_size)
    {
    	int i, j;
    
    	for (i = 0; i < n - 1; i++)
    		for (j = i + 1; j > 0; j--)
    
    			if (strcmp(people[j].name, people[j - 1].name) < 0)
    				swap(&people[j], &people[j - 1]);
    
    			else if (strcmp(people[j].name, people[j - 1].name) == 0)
    				if (people[j].employee_no < people[j - 1].employee_no)
    					swap(&people[j], &people[j - 1]);
    }
    
    int main()
    {
    	int i, n, str_size;
    	n = 10;
    	str_size = 10;
    
    	Database people = /*initializer: real DB would read from disk*/
    	{ {"Fred", 10, 10000, 3000},
    	{"Jim", 9, 12000, 3100.5},
    	{"Fred", 13, 1000000, 30},
    	{"Mary", 11, 170000, 40000},
    	{"Judith", 45, 130000, 50000},
    	{"Nigel", 10, 5000, 1200},
    	{"Trevor", 10, 20000, 6000},
    	{"Karen", 10, 120000, 34000},
    	{"Marianne", 10, 50000, 12000},
    	{"Mildred", 10, 100000, 30000}
    	};
    
    	sort(people, n, str_size);
    
    	for (i = 0; i < n; i++)
    		printf("Name%d: %s, Mitarbeiternummer: %d \n", i, people[i].name, people[i].employee_no);
    }
    

  • Mod

    @H-P-Wurst sagte in Frage zu Typedef:

    @Swordfish Das Skript mit dem ich arbeite ist aufgeteilt in einen C- und einen C++ Teil. Momentan bin ich noch im C-Teil

    Dein Script ist falsch. Such dir bitte was anderes. Wurde dir schon gesagt, hast du aber nicht ernst genommen. Musst du aber. Falsches Lehrmaterial ist das schlimmst, was du dir antun kannst. Und ganz wichtig: Entscheide dich für eine Sprache. Wenn ein Buch dir C und C++ beibringen möchte, dann bringt es dir keines davon bei.



  • @H-P-Wurst sagte in Frage zu Typedef:

    Also so funktioniert es jetzt:

    void sort(Database people, int n, int str_size)
    

    Ohje, wieder ein Skript was nicht die korrekten Typen für die Größe von Strings verwendet. int ist dafür nicht ausreichend. Früher (in der guten alten Zeit mit 16Bit Computern oder den ersten 32Bit Systemen) mag das noch funktioniert haben. Mittlerweile kann man in Intels bzw. AMD aktuelle Desktop Plattform 128GB RAM verbauen, da ist es sehr einfach mehr als 2GB für einen String zu verwenden. Der korrekte Typ ist size_t bzw. wenn man es Vorzeichen behaftet haben will ssize_t.



  • @john-0 sagte in Frage zu Typedef:

    Ohje, wieder ein Skript was nicht die korrekten Typen für die Größe von Strings verwendet.

    Nicht alles, was str im Namen hat, wird für Strings verwendet. Und hier wird die Variable gar nicht benutzt.



  • @manni66 sagte in Frage zu Typedef:

    Nicht alles, was str im Namen hat, wird für Strings verwendet. Und hier wird die Variable gar nicht benutzt.

    Es ändert nichts daran, dass im gesamten Code Variablen des Typs int verwendet werden, um über dynamische allozierte Felder zu iterieren. Das ist ein Programmfehler.



  • @john-0 sagte in Frage zu Typedef:

    Der korrekte Typ ist size_t bzw. wenn man es Vorzeichen behaftet haben will ssize_t.

    Rede nur von Sachen, von denen du Ahnung hast. ssize_t ist nur POSIX und kein Bestandteil von ISO C.



  • @Wutz sagte in Frage zu Typedef:

    Rede nur von Sachen, von denen du Ahnung hast. ssize_t ist nur POSIX und kein Bestandteil von ISO C.

    Das von jemanden, der das int Problem unkommentiert durchgehen lässt. Das ergibt UB. Ja, ssize_t ist aus POSIX, aber der Compiler würde das Problem anmerken. Deshalb hatte ich das nicht korrigiert.



  • @john-0 sagte in Frage zu Typedef:

    aber der Compiler würde das Problem anmerken

    LOL
    Leute die nach dem Motto programmieren "der Compiler wirds schon merken" - wann hast du das letzte Mal produktionsrelevanten Code geschrieben, der das mehrstufige Codereview überstanden hat?
    Trolle dich.