Erstes Programm: "Laufzeit"fehler und Projektidee


  • Mod

    Das sind zwar alles beantwortbare Fragen, aber eine zufriedenstellende Antwort wäre wohl jeweils ein kleines Lehrbuchkapitel. Weil es genau die Art Fragen sind, die in Lehrbüchern beantwortet wird. Ein paar Stichworte:

    Es compiliert mit Warnungen und notes (Hinweisen?).

    Dann beheb die! Das sind Fehler.

    Meine Vermutung: printf(c) findet kein Ende der Zeichenkette?

    Auch. Eigentlicher Fehler ist, das du printf an sich falsch benutzt -> Lehrbuch. Außerdem hast du noch nicht verstanden, wie Zeichenketten in C funktionieren -> Lehrbuch.

    Was bedeutet * in Funktionssignaturen sprich bei Funktionsparametertypen,

    Zeiger.

    und was bei Variablen(-Zuweisungen und -Aufrufen) innerhalb einer Funktion?

    Kommt drauf an, wo. Auf eine Variablendeklaration angewandt: Wieder Zeiger. Auf eine Variable angewandt, die Dereferenzierung eines Zeigers. Aus zwei Variablen angewandt, Multiplikation.

    Anweisungen/Direktive des Prä-Prozessors, so viel ist klar.

    Richtig erkannt. Ebenfalls Lehrbuchfrage.

    Ist Datenkapselung in Klassen und Objekte schon in C möglich?

    Nicht direkt. Muss man sich selber mit den geringen Mitteln der Sprache nachbasteln. Ist aber bei komplexeren Programmen trotzdem zu empfehlen.

    Was gibt es neben "typedef" noch, was keine Variable oder Funktion ist?

    Vieles. structs, Makros, enums, Schlüsselwörter, Operatoren, Literale, Kommentare, Codeblöcke. Die Frage ist viel zu allgemein. Da kann man alles drauf antworten.

    Gibt es access modifier?

    Nein, nicht so, wie du sie kennst.



  • regInfo000? schrieb:

    Meine Vermutung: printf(c) findet kein Ende der Zeichenkette?

    Du übergibst keine Zeichenkette sondern nur ein Zeichen.
    Beachte die Warnungen für Zeile 10.
    Zur Ausgabe eines einzelnen Zeichens gibt es andere Funktionen.

    regInfo000? schrieb:

    Ich versuche jetzt mal, eine Funktion zu schreiben, die ein Übergabe-Zeichen an eine Zeichenkette hängt und diese nicht zurückgeben muss, denn der Aufrufer hat ja den Pointer/Referenz.

    Schau dir mal die Referenz zu strcat an. Es hat schon seinen Grund für den Rückgabeparamter.

    regInfo000? schrieb:

    Was bedeutet * in Funktionssignaturen sprich bei Funktionsparametertypen, und was bei Variablen(-Zuweisungen und -Aufrufen) innerhalb einer Funktion?

    Zeiger. Diese Frage widerspricht sich etwas mit deienm Vorhaben.

    regInfo000? schrieb:

    Noch viele Fragen
    ....
    Ein Buch darüber habe ich whrs. erst morgen. Viele Grüße!

    Dann warte bis morgen.
    Da das alles Grundlagen sind, werden die (hoffentlich) auch im Buch behandelt.



  • Also, einmal geschlafen und Gedanken darüber gemacht. Ich möchte jetzt:
    1. ein Hangman (zwecks Ein-/Ausgabe),
    2. eine halb-transparente, immer sichtbare, ohne Fonts mit Linien und Kreisen selbst-gezeichnete 'digitale' Uhr mit Millisekunden,
    3. Temperatur der CPU und Umgebung entweder jede Sekunde oder durch Hooks(?) und
    4. ein multithread Bruteforce auf Daten im RAM
    programmieren. Da Windows ja auch in C geschrieben wurde, sollte das doch kein Problem sein. Benötigt man dafür immer, unter allen Umständen die Win.-API? Danke noch mal für ein paar Antworten.



  • regInfo000? schrieb:

    Also, einmal geschlafen und Gedanken darüber gemacht. Ich möchte jetzt:
    1. ein Hangman (zwecks Ein-/Ausgabe),

    Auf der Konsole kein Problem. wenn du auf Gimmicks verzichtest.

    regInfo000? schrieb:

    2. eine halb-transparente, immer sichtbare, ohne Fonts mit Linien und Kreisen selbst-gezeichnete 'digitale' Uhr mit Millisekunden,
    3. Temperatur der CPU und Umgebung entweder jede Sekunde oder durch Hooks(?) und
    4. ein multithread Bruteforce auf Daten im RAM
    programmieren.

    Von alledem (Fonts, Linien, Millisekunden, CPU) ist im C-Standard keine Rede.

    regInfo000? schrieb:

    Da Windows ja auch in C geschrieben wurde, sollte das doch kein Problem sein. Benötigt man dafür immer, unter allen Umständen die Win.-API?

    Letztendlich schon. Ob du noch ein anderes Framework dazwischen schaltest, das dir arbeit abnimmt, liegt an dir.



  • Jetzt habe ich was nNeues:

    Operatoren:
    [] () {}
    . -> ? : ,
    ++ -- & * + - / % ~ ! sizeof
    << >> < > <= >= == != ^ | && ||
    *= /= %= += -= <<= >>= &= ^= |=
    , = ; ...
    # ##
    (Fehler? Redundanzen?) Einige kenne ich, aber wofür steht z. B. ~ und was sind die Bit-Operatoren (unär, binär), was sind ternäre Operatoren (ternary operators)? Gibt's quaternäre Operatoren?

    Schlüsselwörter:
    auto double int struct
    break else long switch
    case enum register typedef
    char extern return union
    const float short unsigned
    continue for signed void
    default goto sizeof volatile
    do if static while
    Was bedeutet hier register, volatile und besonders extern?

    Integer Anhängsel: l, u und ul; Präfixe: kein, 0 und 0x usw.

    Jede Variable/Konstante belegt mindestens ein Byte und immer eine ganze Anzahl Bytes. Es gibt verhsciedene Zusicherungen.

    So, jetzt zu der eig. Frage, was sind "generische Zeiger" void *ptr; ? Wie geht man damit um?? Was sind Zeiger, Felder, Strukturen und Funktionen oder Prozeduren (Funktionen keiner Rückgabe==void)??

    Was ich schreiben möchte:

    void append(char c, &*?char str, int size) { /* hängt an den Zeiger der Zeichenkette str ein weiteres Zeichen c, insofern hinter '\0' noch Platz ist!! */
    

    Eig. kann auch ein Zeiger auf c und size möglich?

    Kann ich einzelne oder mehrere Zeichen immer nur mit printf("%s\n", str); ausgeben? C89 (k&r) verwendet derzeit wohl keiner mehr- oder?



  • Der K&R ist immer noch das Buch über C.
    Wenn du das hast, bist du gut bedient. Arbeite es durch (nicht nur lesen)
    Deine Fragen werden in dem Buch beantwortet.

    Und Visual Studio kennt bei C nichts neueres als C89.

    Deine Funktion sollte

    char *append(char *str, char c, int size) 
    { ....
    
      return str;
    }
    

    sein.



  • Ein Schritt nach dem anderen: Mache erst Hangman mit scanf und printf! Versuche nicht, an Cursorpositionen zu springen! Lerne einfache Ein-/Ausgabe! Komme wieder bei konkreten Fragen, die du nicht selbst beantworten kannst (entsprechende Muehe vorausgesetzt)!



  • Sonst schau mal in die Linkliste für Neulinge
    Ist der erste wichtige Thread hier im Unterforum.



  • So, ich bin jetzt hier angelangt:

    /*
     * Kommentar
     */
    
     #include <stdio.h>
    
     typedef unsigned char char255; /* 0..255 */
    
     char255* toChar255String(char* str);
    
     void printChar255String(char255*);
    
     int main(void) {
    	char255 ca[16] = toChar255String("!!Hello World!!\n");
    	printChar255String(&ca);
    	printf("!!Hello World!!\n");
    	return 0;
    }
    
    char255* toChar255String(char* ca) {
    	int i, size=sizeof(ca)/sizeof(ca[0]);
    	char255 res[size];
    	for(i=0; i<size; i++) {
    		res[i] = ca[i];
    	}
    	return &ca;
    }
    
    void printChar255String(char255* ca) {
    	/* for.... */
    }
    

    Compiler gibt genau so viele Warnungen aus, wie die Länge des Programms....

    error: invalid initializer (14)

    incompatible pointer

    variable length array

    function returns address of local variable

    res set but not used

    FRAOLV kenne ich: Die Adresse einer Variablen, die nach der Methode nicht mehr gültig/sichtbar ist, wird zurückgegeben, was viell. mal zu Problemen kommen könnte, in dem Programm jedoch keine Rolle spielt und einfach schneller ist.

    Wie behebe ich nun alle Fehler? Danke noch.mal für Antworten.



  • regInfo000? schrieb:

    FRAOLV kenne ich: Die Adresse einer Variablen, die nach der Methode nicht mehr gültig/sichtbar ist, wird zurückgegeben, was viell. mal zu Problemen kommen könnte, in dem Programm jedoch keine Rolle spielt und einfach schneller ist.

    Mit der Einstellung: Vergiss es. Lass das Programmieren in C sein.

    Zudem geben die Compiler zu den Fehlermeldungen auch die Zilenn und Spalten an.
    Mit diesen Angaben ist die Fehlerbehebung sehr viel leichter.

    Hast du jetzt dein Buch?
    Welches ist es denn?



  • @regInfo000

    Kauf dir ein ordentliches Buch und deine Fragen beantworten sich von selbst.
    Ich glaube mehr gibt es da nicht zu sagen... Wenn es mit solchen Grundlagen dann immer noch hookt...suche dir ein anderes "Hobby".



  • Wirklich sehr freundlich alle und das hat auch nur bis zur 2 Seite gedauert 👎 entschuldigt, das ich Götter nicht denenentsprechend gehuldigt habe. Danke für nicht mal ein klein wenig Hilfe.



  • Was du wissen willst steht in den Büchern über C. Besonders im K&R.
    Das sind die Grundlagen, die musst du dir erarbeiten.

    Wenn du dann Verständnisprobleme hast, kannst du gerne fragen.

    regInfo000? schrieb:

    Danke für nicht mal ein klein wenig Hilfe.

    Die kleine Hilfe hast du bekommen, nur du wolltest einen privaten C-Kurs haben.
    Dafür ist hier aber keiner bereit.



  • Aus Fehlern lernt man aber mehr als aus von vornherein richtig geschriebenen C-Programmcode. Ich habe ein Buch über C++, in dem C-Zeiger und vor allem -Arrays nur ganz am Rande abgehandelt werden. Ich erachte es für sinnvoll, zuerst die C-Syntax zu erlernen (und typedef struct enum (union) * & [] etc. pp.), bevor man Klassen und Objekte in C++ kennenlernt (und auch eine teilweise andere Syntax). Also C -> C++ und nicht C++ AND C. Wenn ich die 31-32 Zeilen aus den vorherigen Beiträgen zum Laufen bringen würde, wäre mir sehr geholfen. Ich habe in der Vergangenheit auch Fragen über Java beantwortet und dachte, eine ähnliche Community-struktur gäbe es auch hier. Ich will mir gar nicht Lösungen erbetteln, aber für jmd., der schon 1-2 Jahre in C programmiert hätte, wäre das doch ein Kleinigkeit....


  • Mod

    regInfo000? schrieb:

    aber für jmd., der schon 1-2 Jahre in C programmiert hätte, wäre das doch ein Kleinigkeit....

    Nein. Dein Fragenkatalog stellt vom Umfang her, wollte man alles beantworten, so manches schlechte Lehrbuch in den Schatten.

    Bezüglich C und C++: Die allgemeine Empfehlung ist, dringend C++ zu lernen, wenn man C++ machen willst. Die Syntax wird schließlich mit der Sprache gelernt. Selbst wenn sie hier ausnahmsweise gleich ist zur Syntax einer anderen Sprache, so ist das doch kein Argument, die andere Sprache zu lernen. Wenn du Java kennst, dann kennst du die Syntax von C und C++ ohnehin schon.

    Was du aber erreichst, wenn du stattdessen eine andere Sprache lernst, ist, dass du dann die Spezialitäten und Herangehensweisen dieser anderen Sprachen lernst. In C++ programmiert man jedoch ganz anders als in C oder Java, auch wenn von der Syntax her alles gleich aussieht. Du musst lernen, wie man in C++ vorgeht und das lernst du nur, wenn du C++ lernst. Es funktioniert als Anfänger sogar eine Weile, C/Java in C++ zu machen, aber weder nutzt man die Stärken und Möglichkeiten der Sprache, noch ist das Ergebnis wirklich im Sinne des Erfinders. Das sind später die schlimmsten Programmierer, die hier Fragen zu den schlimmsten Hackcodes stellen.

    C ist keine vereinfachte Version von C++! C++ ist keine einfache Erweiterung von C*! Es sind komplett unterschiedliche Sprachen mit gleicher Grammatik.

    *: Das mag historisch so sein, aber trifft nicht den Kern der Sache.



  • Dein Programm ist so voller Fehler, das es eher eine Klausuraufgabe ist "Finden sie alle Fehler und verbessern Sie diese"

    Wenn du im K&R mal nach strcat oder strcpy schaust (da ist ein Beispiel drin), weißt du auch schon wie es richtig geht. Bzw. sollten dann nur ca. zwei Fehler übrig bleiben.

    Da helfen wir auch gerne.



  • DirkB schrieb:

    , das es eher eine Klausuraufgabe ist "Finden sie alle Fehler und verbessern Sie diese"

    Dann aber auch fies sein und // einfügen und */ am eNde des Kommentars nicht weglassen. 😉

    Also de jure/de facto sind es zu viele Möglichkeiten, um das Programm nur durch Ausprobieren ausführbar zu machen.

    Ich werde in den von Euch genannten Quellen nach Online-Literatur suchen



  • regInfo000? schrieb:

    Also de jure/de facto sind es zu viele Möglichkeiten, um das Programm nur durch Ausprobieren ausführbar zu machen.

    Gerade in C heißt "ausführbar" noch lange nicht "läuft richtig".
    Und man muss wissen was man programmiert. Mit Ausprobieren kommst du da nicht weiter.



  • DirkB schrieb:

    Gerade in C heißt "ausführbar" noch lange nicht "läuft richtig".
    Und man muss wissen was man programmiert. Mit Ausprobieren kommst du da nicht weiter.

    Am Anfang ist "ausführbar" schon ein Erfolg.

    So, ich habe das jetzt erst mal so:

    /*
     * Kommentar
     */
    
    #include <limits.h>
    #include <stdio.h>
    #include <stdlib.h>
    
    typedef unsigned char char255; /* 0..255 */
    
    int main(void) {
    	int a, b;
    	char c;
    
    	printf("!!Hello World!!\n");
    
    	printf("Bitte a und b (Ganzzahl) eingeben: ");
    	scanf("%i %i", &a, &b);
    	printf("a=%i, b=%i\n", a, b);
    
    	printf("a + b = %i\n",       a + b);
    	printf("a - b = %i\n",       a - b);
    	printf("a * b = %i\n",       a * b);
    	printf("a / (b | 1) = %i\n", a / (b | 1));
    	printf("a % (b | 1) = %i\n", a % (b | 1));
    	printf("b << 1 = %i\n",      b << 1);
    	printf("b >> 1 = %i\n",      b >> 1);
    
    	scanf("%c%c", &c, &c);
    	return EXIT_SUCCESS;
    }
    

    Facts: <limits.h> habe ich gar nicht benötigt. | hat keinen größeren Operatorrang (Präzedenz) als / und %. / 0 ist undefiniert (weder implementierungsabhängig noch unspezifiziert) und sollte immer vermieden werden.

    Dazu ein paar konkrete (<-- kein Hyperlink 😉 ) Fragen:

    scanf mit neuer Zeile scanf("%i %i\n" funktioniert bei mir nicht, generell verhält sich scanf komisch... - wieso, was kann man dagegen machen?

    getchar() (ohne actual parameters) führt bei mir nicht dazu, dass die Konsole nicht geschlossen wird, deshalb musste ich scanf("%c%c", &c, &c); (was ja unsinnig ist) schreiben... - wieso?

    Ist es besser EXIT_SUCCESS zu schreiben - oder einfach 0 (für "keine Fehler während der Programmlaufzeit")? Bei/Für EXIT_SUCCESS muss ich <stdlib.h> 'inkludieren', was die .exe hinterher etwas aufbläht.

    Wie funktioniert die Bedingte Anweisung ("? :" ??), kann ich damit erreichen, dass nicht durch 0 geteilt wird?

    Danke noch mal, ich bin geraden in dem C-Programmierung - Wikibooks bei 2.6 Fließkommazahlen (also noch nicht sehr weit). Wirklich super geschrieben, Sprachlich, Beispiele etc



  • regInfo000? schrieb:

    scanf mit neuer Zeile scanf("%i %i\n" funktioniert bei mir nicht, generell verhält sich scanf komisch... - wieso, was kann man dagegen machen?

    scanf ist ja auch zum Lesen gedacht, nicht zum Ausgeben.

    getchar() (ohne actual parameters) führt bei mir nicht dazu, dass die Konsole nicht geschlossen wird, deshalb musste ich scanf("%c%c", &c, &c); (was ja unsinnig ist) schreiben... - wieso?

    Egal, was ich hier jetzt schreiben werde: Gleich gibts die obligatorische SeppJ vs Unreg Diskussion über den C Konsolenpuffer. 🕶
    Jedenfalls ist das Enter von der letzten Eingabe noch im Puffer, was dazu führt, dass getchar() das liest. Um das zu vermeiden, muss man es aus dem Puffer löschen oder deine Variante verwenden.
    (alternativ auch zweimal getchar()).

    Ist es besser EXIT_SUCCESS zu schreiben - oder einfach 0 (für "keine Fehler während der Programmlaufzeit")? Bei/Für EXIT_SUCCESS muss ich <stdlib.h> 'inkludieren', was die .exe hinterher etwas aufbläht.

    EXIT_SUCCESS ist auf den meisten Plattformen 0, also kannst du das auch direkt schreiben.
    Aber das Inkludieren eines Headers erzeugt in der Regel keine Auswirkungen der exe size.

    Wie funktioniert die Bedingte Anweisung ("? :" ??), kann ich damit erreichen, dass nicht durch 0 geteilt wird?

    Die bedingte Bedingung ist wie if, nur in eine Zeile:

    if (b)
       result = a / b;
    else
       result = some_error_val;
    

    ->

    result = b ? a / b : some_error_val;
    

    Sinn des Beispiels mal außen vor gestellt.


Anmelden zum Antworten