From 066e454654135e9fd375d522745fa4978920391a Mon Sep 17 00:00:00 2001 From: caminsha Date: Thu, 30 Jan 2020 19:12:07 +0100 Subject: Started german translation in C --- de-de/c-de.html.markdown | 83 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 de-de/c-de.html.markdown (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown new file mode 100644 index 00000000..242e51e1 --- /dev/null +++ b/de-de/c-de.html.markdown @@ -0,0 +1,83 @@ +--- +language: c +filename: learnc.c +contributors: + - ["caminsha", "https://github.com/caminsha"] +lang: de-de +--- + +Ach, C. Immer noch **die** Sprache für modernes High-Performance Computing. + +C ist wahrscheinlich die niedrigste Programmiersprache, welche die meisten +Programmierer je brauchen werden. Die Geschwindigkeit von C ist enorm, allerdings +muss man sich stets der maneullen Speicherverwaltung bewusst sein. + + +> **Über Compiler Flags** +> +> Standardmässig sind `gcc` und `clang` ziemlich ruhig bezüglich Warnungen und +> Fehlern, obwohl dies sehr nützliche Informationen sein können. Es wird +> empfohlen, strengere Compiler Flags zu verwenden. Hier sind einige empfohlene +> Standards: +> `-Wall -Wextra -Werror -O2 -std=c99 -pedantic` +> +> Für weitere Informationen, was diese und weitere Optionen genau machen, +> sollte die Man-Page des C-Compilers aufgerufen werden (z.B. `man 1 gcc`). +> Alternativ kann auch online nach den unterschiedlichen Optionen gesucht werden. + +```c +// einzeilige Kommentare starten mit // - nur in C99 und später vorhanden. + +/* +mehrzeilige Kommentare sehen so aus. Diese funktionieren auch in C89 +*/ + +/* +mehrzeilige Kommentare können nicht verschaltelt werden /* Sei Vorsichtig! */ // Kommentar endet auf dieser Linie ... +*/ // ... nicht bei dieser! + +// Konstanten: #define +// Konstanten werden laut der Konvention immer in GROSSBUCHSTABEN geschrieben +#define TAGE_IM_JAHR 365 + +// Konstanten können auch als Aufzählungskonstanten (Enums) definiert werden. +// Alle Anweisungen müssen mit einem Semikolon beendet werden. +enum tage {SO=1, MO, DI, MI, DO, FR, SA}; +// MO wird automatisch zu 2, DI zu 3 etc. + +// Importiere Header-Dateien mit #include +#include +#include +#include + +// Dateien, welche zwischen stehen, sind Header-Dateien aus +// der C-Standard-Bibliothek. +// Für deine eigenen Header müssen Anführungszeichen verwendet werden, z.B.: +// #include "mein_header.h" + +// Funktionssignaturen werden entweder vorher in einer .h-Datei deklariert oder +// am Anfang der .c-Datei. +void funktion_1(); +int funktion_2(void); + +// Es muss ein Funktionsprototyp deklariert werden vor der `main()` Funktion, +// wenn die Funktion nach der `main()` Funktion gebraucht wird. +int addiere_zwei_integer(int x1, int x2); // Funktionsprototyp +// Auch wenn der Ausdrck `int addiere_zwei_integer(int, int)` auch valid wäre, +// ist es empfohlen, dass man die Namen der Argumente hinschreibt für eine +// einfachere Analyse. + +// Der Einstiegspunkt deines Programms ist eine Funktion mit dem Namen main und +// einem Integer als Rückgabewert. +int main(void){ + // dein Programm +} + +// Die Kommandozeilenargumente, welche gebraucht werden, damit dein Programm läuft, +// werden als Argumente der `main`-Funktion mitgegeben. +// argc steht für die Anzahl von Argumenten. - Der Programmname ist das erste Argument. +// argv ist ein Array von Zeichenarrays, welche die Argumente beinhaltet. +// argv[0] = Name des Programms +// argv[1] = erstes Argument usw. +int main (int argc, char** argv){ +} -- cgit v1.2.3 From b4e6dc73c1dcb5dfd4aa53a31fa666a537492a73 Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 00:00:39 +0100 Subject: Continued with german translation of C --- de-de/c-de.html.markdown | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 242e51e1..777bba11 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -80,4 +80,76 @@ int main(void){ // argv[0] = Name des Programms // argv[1] = erstes Argument usw. int main (int argc, char** argv){ + // Ausgabe mit Hilfe von printf (print formatted) + // %d ist ein Integer. + // \n steht für eine neue Zeile + printf("%d\n",0); // => Gibt 0 aus. + + //////////////////////////////////////////////// + // Typen + //////////////////////////////////////////////// + + // Alle Variable müssen am Anfang des jetzigen Blocks deklariert werden. + // Wir deklarieren die Variablen dynamisch im Code um die Lesbarkeit im + // Tutorial zu verbessern. + // C99-Konforme Compiler erlauben die Variablendeklaration an dem Punkt, an + // welchem die Variable verwendet wird. + + // integer sind normalerweise 4 Bytes gross + int x_int = 0; + + // shorts sind normalerweise 2 Bytes gross + short x_short = 0; + + // chars sind garantiert 1 Byte gross + char x_char = 0; + char y_char = 'y'; // Charakterliterale werden mit '' gekennzeichnet. + + // longs sind oft 4 bis 8 Bytes gross. long long sind garantiert mindestens + // 8 Bytes gross. + long x_long = 0; + long long x_long_long = 0; + + // floats sind normalerweise 32-Bit Gleitkommazahlen + float x_float = 0.0f; // 'f'-Suffix beschreibt eine Gleitkommazahl. + + // doubles sind normalerweise 64-Bit Gleitkommazahlen + double x_double = 0.0; // echte Zahlen ohne Suffix sind vom Typ double + + // integer-Typen können vorzeichenlos (unsigned) sein (grösser oder kleiner als 0) + unsigned short ux_short; + unsigned int ux_int; + unsigned long long ux_long_long; + + // chars innerhalb von einfachen Anführungszeichen sind Integers im + // Maschinenzeichensatz + '0'; // => 48 im ASCII-Zeichensatz + 'A'; // => 65 im ASCII-Zeichensatz + + // sizeof(T) gibt die Grösse einer Variablen des Typen T in Bytes zurück. + // sizeof(obj) ergibt die Grösse des Ausdrucks (Variable, Literal usw.) + + printf("%zu\n", sizeof(int)); // => 4 (auf den meisten Rechnern mit einem 4-Byte-Wort) + + // Wenn das Argument des `sizeof`-Operator ein Ausdruck ist, dann wird das + // Argument nicht ausgewertet (ausser Arrays mit variabler Länge) + // Der Wert, der in diesem Fall zurückgegeben wird, ist eine Konstante zur + // Kompillierzeit. + + int a = 1; + //size_t ist ein vorzeichenloser Integer Typ mit mindestens 2 Byte um die + // Grösse eines Objekts zu repräsentieren. + size_t size = sizeof(a++); // a++ wird nicht ausgewertet + printf("sizeof(a++) = %zu, wobei a=%d ist\n", size, a); + // Gibt "sizeof(a++) = 4, wobei a=1 ist" aus (mit einer 32-Bit-Architektur) + + // Arrays müssen mit einer Grösse initialisiert werden. + char my_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes + int my_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes. + // unter der Voraussetzung eines 4-Byte-Worts. + + // Ein Array kann auf diese Weise mit 0 initialisiert werden. + char my_array[20] = {0}; + // Hierbei ist der Teil "{0}" der "Array Initialisierer". + } -- cgit v1.2.3 From ea00cc1fdac7acded85b8aad0eb2ac5e09b8e5d7 Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 01:11:48 +0100 Subject: translated operators to german --- de-de/c-de.html.markdown | 141 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 138 insertions(+), 3 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 777bba11..69576da0 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -144,12 +144,147 @@ int main (int argc, char** argv){ // Gibt "sizeof(a++) = 4, wobei a=1 ist" aus (mit einer 32-Bit-Architektur) // Arrays müssen mit einer Grösse initialisiert werden. - char my_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes - int my_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes. + char mein_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes + int mein_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes. // unter der Voraussetzung eines 4-Byte-Worts. // Ein Array kann auf diese Weise mit 0 initialisiert werden. - char my_array[20] = {0}; + char mein_array[20] = {0}; // Hierbei ist der Teil "{0}" der "Array Initialisierer". + // Beachte, dass die Länge des Arrays nicht explizit definiert werden muss, + // wenn er auf derselben Linie initialisiert wird. + // Folgende Deklaration ist gleichwertig: + char mein_array[] = {0}; + // Allerdings muss die Länge des Arrays dann zur Laufzeit ausgewertet werden: + size_t mein_array_size = sizeof(mein_array) / sizeof(mein_array[0]); + // WARNUNG: Wenn dieser Ansatz gewählt wird, muss man sicherstellen, dass die + // Grösse des Arrays ermittelt werden *bevor* dieser einer Funktion als + // Argument weitergegeben wird (siehe Diskussion weiter unten), weil Arrays + // einer Funktion nur als Zeiger übergeben werden. => Das obere Statement + // würde innerhalb einer Funktion ein falsches Resultat liefern. + + // Das Indexieren eines Arrays funktioniert wie in anderen Sprache - resp. + // in anderen Sprachen funktioniert es gleich wie in C. + mein_array[0]; // => 0 + + // Arrays sind veränderbar; es ist nur Arbeitsspeicher! + mein_array[1] = 2; + printf("%d\n", mein_array[1]); // => 2 + + // In C99 (und als optionales Feature in C11) können Arrays mit variabler + // Länge deklariert werden. Die Grösse eines solchen Array muss eine Konstante + // zur Kompilierzeit sein. + printf("Geben Sie die Arraygrösse an: "); //Frag den Benutzer nach der Arraygrösse + int array_size; + fcsanf(stdin, "%d", &array_size); + int var_length_array[array_size]; // deklariere Array mit variabler Länge + printf("sizeof array =%zu\n", sizeof var_length_array); + + // Zum Beispiel: + // > Geben Sie die Arraygrösse an: 10 + // > sizeof array = 40 + + // Strings sind lediglich Arrays von `chars`, welche mit einem Null-Byte + // (0x00) beendet werden. In Strings wird das Nullbyte durch das Zeichen \0 + // repräsentiert. Wir müssen das Null-Byte nicht angeben in String-Literalen; + // Der Compiler fügt es am Ende des Array automatisch hinzu. + char ein_string[20] = "Das ist ein String"; + printf("%s\n", ein_string); // %s formattiert einen String + + printf("%d\n", ein_string[18]); // => 0 + // Hier ist das Byte #19 0 (wie auch Byte #20) + + // Wenn wir Zeichen zwischen einfachen Anführungszeichen haben, ist es ein + // Zeichenliteral vom Typ int und *nicht* char. (aus historischen Gründen) + int cha = 'a'; // Ok + char chb = 'a'; // auch ok (implizite Umwandlung von int zu char) + + // Mehrdimensionale Arrays: + int multi_array[2][5] = { + {1,2,3,4,5}, + {6,7,8,9,0} + }; + // Auf Elemente zugreifen: + int array_int = multi_array[0][2]; // => 3 + //////////////////////////////////////////////// + // Operatoren + //////////////////////////////////////////////// + + // Kurzschreibweise für mehrere Deklarationen + int i1 = 1, i2 = 2; + flaot f1 = 1.0, f2 = 2.0; + + int b,c; + b = c = 0; + + // Arithmetik ist unkompliziert + i1 + i2; // => 3 + i2 - i1; // => 1 + i2 * i1; // => 2 + i1 / i2; // 0 (0.5, aber abgeschnitten, da es int sind. + + // Man muss mindestens ein Integer to einen float konvertieren, damit man als + // Resultat eine Gleitkommazahl erhält. + (float)i1 / i2; // => 0.5f + i1 / (double)i2; // => 0.5 // das gleiche mit dem Typ `double` + f1 / f2; // => 0.5, plus oder minus Epsilon + // Gleitkommazahlen und deren Berechnungen sind nicht exakt. + + // Es gibt auch die Möglichkeit, Modulo zu rechnen + 11 % 3; // => 2 + + // Vergleichsoperatoren sind vielleicht schon bekannt, aber in C gibt es keinen + // Boolean-Typ. In C verwenden wir `int`. (Oder _Bool oder bool in C99.) + // 0 ist falsch, alles andere ist wahr (Die Vergleichsoperatoren ergeben + // immer 1 oder 0. + 3 == 2; // => 0 (falsch) + 3 != 2; // => 1 (wahr) + 3 > 2; // => 1 + 3 < 2; // => 0 + 2 <= 2; // => 1 + 2 >= 2; // => 1 + + // C ist nicht Python - Vergleiche können nicht verkettet werden. + // Warnung: die folgende Zeile wird kompilieren, aber es bedeutet `(0 < a) < 2`. + // Dieser Ausdruck ist immer wahr, weil (0 < a) kann entweder 1 oder 0 sein. + // In diesem Falle ist es 1, weil (0 < 1). + int zwischen_0_und_2 = 0 < a < 2; + // Benutze stattdessen folgende Schreibweise: + int zwischen_0_und_2 = 0 < a && a < 2; + + // Logik funktioniert auch mit ints + !3; // => 0 (logisches Nicht) + !0; // => 1 + 1 && 1; // => 1 (logisches Und) + 0 && 1; // => 0 + 0 || 1; // => 1 (logisches Oder) + 0 || 0; // => 0 + + // Bedingter ternärer Ausdruck ( ? : ) + int e = 5; + int f = 10; + int z; + z = ( e > f) ? e : f; // => // => 10 "wenn e > f ist, gib e zurück, sonst f." + + // Inkrementierungs- und Dekrementierungsoperatoren + int j = 0; + int s = j++; // gib j zurück und erhöhe danach j. (s = 0, j = 1) + s = ++j; // erhöhe zuerst j und gib dann j zurück (s = 2, j = 2) + // das gleiche gilt für j-- und --j + + // Bitweise Operatoren + ~0x0F; // => 0xFFFFFFF0 (Bitweise Negation, "Einer-Komplement", Beispielresultat für 32-Bit int) + 0x0F & 0xF0; // => 0x00 (Bitweises UND) + 0x0F | 0xF0; // => 0xFF (Bitweises ODER) + 0x04 ^ 0x0F; // => 0x0B (Bitweises XOR) + 0x01 << 1; // => 0x02 (Bitweises Linksshift (left shift) (um 1)) + 0x02 >> 1; // => 0x01 (Bitweises Rechtsshift (right shift) (um 1)) + + // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern - folgende Ausdrücke sind nicht definiert: + // - Verschiebung in das Vorzeichenbit (int a = 1 << 31) + // - Linksshift einer negativen Zahl (int a = -1 << 2) + // - Shift um einen Offset, welcher >= die Breite des linken Ausdrucks ist. + // int a = 1 << 32; // undefiniertes Verhalten, wenn int 32-Bit ist. + } -- cgit v1.2.3 From dcf628e2866634bee9e9e04ecbb336885adaf7e4 Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 01:42:28 +0100 Subject: translated control structures to German --- de-de/c-de.html.markdown | 85 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 69576da0..b027cdbe 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -287,4 +287,89 @@ int main (int argc, char** argv){ // - Shift um einen Offset, welcher >= die Breite des linken Ausdrucks ist. // int a = 1 << 32; // undefiniertes Verhalten, wenn int 32-Bit ist. + //////////////////////////////////////////////// + // Kontrollstrukturen + //////////////////////////////////////////////// + if (0) { + printf("Ich werde nie ausgeführt."); + } + else if (0){ + printf("Ich werde auch nie ausgeführt."); + } + else { + printf("Ich gebe etwas aus."); + } + + // While-Schleifen existieren auch + int ii = 0; + while (ii < 10){ // JEDER Wert unter zehn ist wahr + printf("%d, " ii++); //i++ inkrementiert ii NACHDEM der Wert gebraucht wurde. + } // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + + printf("\n"); + + int kk = 0; + do { + printf("%d, ", kk); + } while(++kk < 10); //++kk inkrementiert kk BEVOR der Wert gebraucht wurde. + // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + + printf("\n"); + + // In C gibt es auch for-Schleifen + int jj; + for (jj = 0; jj < 10; jj++){ + printf("%d, ", jj); + } // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " + + printf("\n"); + + // **Merke** + // Schleifen und Funktionen müssen einen Body haben. Wenn kein Body gebraucht + // wird, kann folgendes gemacht werden: + int i; + for (i = 0; i <= 5; i++){ + ; // Semikolon wird als Body behandelt (Null-Anweisung) + } + // Alternativ kann auch folgendes geschrieben werden: + for (i = 0; i <= 5; i++); + + // Verzweigungen mit mehreren Möglichkeiten: `switch()` + switch (a){ + case 0: //labels müssen integrale *konstante* Ausdrücke sein (z.B. Enums) + printf("Hey, 'a' ist gleich 0!\n"); + break; //Wenn du kein break einsetzt, so geht der Kontrollfluss durch die Labels + case 1: + printf("Huh, 'a' ist gleich 1!\n"); + break; + // Sei vorsichtig - wenn man das `break` vergisst, werden alle Anweisungen + // ausgeführt bis das nächste `break` erscheint. + case 3: + case 4: + printf("Schau mal ... 'a' ist entweder 3 oder 4.\n"); + break; + default: + // wenn der Ausdruck `a` auf kein Label zutrifft. + fputs("Fehler!\n", stderr); + exit(-1); + break; + } + + // Verwendung von "goto" in C + typedef enum { false, true } bool; + bool desaster = false; + int i, j; + for(i=0; i < 100; ++i){ + for (j=0; j < 100; ++j){ + if ((i + j ) >= 150){ + desaster = true; + } + if (desaster){ + goto error; + } + } + } +error: + printf("Ein Fehler ist aufgetreten bei i = %d & j ? %d\n", i, j); + } -- cgit v1.2.3 From a53f355f9ffa02e4b87f1769bb48b2cb2b40ea2f Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 01:47:49 +0100 Subject: added translation for type casting --- de-de/c-de.html.markdown | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index b027cdbe..1b97faaf 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -372,4 +372,31 @@ int main (int argc, char** argv){ error: printf("Ein Fehler ist aufgetreten bei i = %d & j ? %d\n", i, j); + //////////////////////////////////////////////// + // Typenumwandlung + //////////////////////////////////////////////// + + // Jeder Wert in C hat einen bestimmten Typen, aber es ist möglich, ein + // Wert in einen anderen Typ umzuwandeln (mit einigen Einschränkungen). + + int x_hex = 0x01; // Es ist möglich, Variablen Hexadezimalwerten zuzuweisen. + + // Bei der Umwandlung zwischen Typen wird versucht, den numerischen Wert + // beizubehalten. + printf("%d\n", x_hex); // => 1 + printf("%d\n", (short) x_hex); // => 1 + printf("%d\n", (char) x_hex); // => 1 + + // Typen werden überlaufen (overflow) ohne jegliche Warnung + printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 wenn char 8 Bit lang ist) + + // Um den maximalen Wert eines `char`, `signed char` oder `unsigned char` + // herauszufinden, können die Makros `CHAR_MAX`, `SCHAR_MAX` und `UCHAR_MAX` + // aus der Header-Datei `` verwendet werden. + + // Integer-Typen können zu Gleitkommazahlen und umgekehrt umgewandelt werden. + printf("%f\n", (double) 100); // %f formattiert immer zu einem `double`... + printf("%f\n", (flaot) 100); // ... auch mit einem `float` + printf("%d\n", (char)100.0); + } -- cgit v1.2.3 From 09a4d598ae157d2d007db1740c6b811a11c84367 Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 03:16:16 +0100 Subject: translated section pointers to german --- de-de/c-de.html.markdown | 132 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 131 insertions(+), 1 deletion(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 1b97faaf..c9e01181 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -399,4 +399,134 @@ error: printf("%f\n", (flaot) 100); // ... auch mit einem `float` printf("%d\n", (char)100.0); -} + //////////////////////////////////////////////// + // Zeiger (aka Pointer) + //////////////////////////////////////////////// + + // In diesem Tutorial wird das deutsche Wort Zeiger nicht verwendet, da es + // bei einer weiteren Recherche einfacher ist, wenn man von Pointern ausgeht. + // Ausserdem ist der Begriff Pointer auf im deutschen Sprachgebrauch zu finden. + + // Ein Pointer ist eine Variable, welche deklariert wurde, um eine Speicher- + // Adresse zu speichern. Die Deklaration eines Pointers wird auch zeigen, + // auf welche Art von Daten der Pointer zeigt. Man kann die Speicheradresse + // von Variablen abrufen und dann mit diesen herumspielen. + + int x = 0; + printf("%p\n", (void *)&x); // verwende & um die Adresse der Variable zu erhalten + // %p formattiert einen Objektpointer des Typen void*) + // => Gibt eine Adresse im Speicher aus + + // Pointer starten mit einem * zu Beginn der Deklaration. + int *px, kein_pointer; // px ist ein Pointer zu einem int. + px = &x; // Speichert die Adresse von x in px + printf("%p\n", (void *)px); // => Gibt eine Adresse im Speicher aus + printf("%zu, %zu\n", sizeof(px), sizeof(kein_pointer)); + // Gibt auf einem typischen 64-Bit-System folgendes aus: "8, 4" + + // Um den Wert einer Adresse, auf welche ein Pointer zeigt, herauszufinden, + // muss man vor die Variable ein * setzen, um sie zu dereferenzieren. + // Notiz: Ja, es kann verwirrend sein, dass '*' sowohl für das Deklarieren + // als auch das Derefenzieren verwendet werden kann. + printf("%d\n", *px); // => 0, der Wert von x + + // Man kann den Wert, auf welchen ein Pointer zeigt, auch verändern. + // Man muss die Dereferenzierung in Klammern setzen, weil ++ eine höhere + // Priorität als * hat. + (*px)++; // Inkrementiere den Wert, auf welchen px zeigt, um 1 + printf("%d\n", *px); // => 1 + printf("%d\n", x); // => 1 + + // Arrays sind eine gute Möglichekit, einen zusammenhängenden Block von + // Speicher zu allozieren. + int x_array[20]; // deklariert einen Array der Grösse 20 (Grösse kann + // nicht geändert werden.) + int xx; + for (xx =0; xx < 20; xx++){ + x_array[xx] 20 -xx; + } // Initialisiere x_array zu 20, 19, 18, ... 2, 1 + + // Deklariere ein Pointer des Typs int und initalisiere ihn, um auf `x_array` + // zu zeigen. + int *x_ptr = x_array; + // x_ptr zeigt jetzt auf den ersten Wert innerhalb des Arrays (int 20) + // Das funktioniert, weil Arrays oft zu Pointern reduziert werden, welche + // auf das erste Element zeigen. + // Zum Beispiel: Wenn ein Array einer Funktion mitgegeben wird oder einem + // Pointer zugewiesen wird, wird es zu einem Pointer reduziert (implizites Casting) + // Ausnahme: Wenn das Array das Argument des Operators `&` ist. + int arr[10]; + int (*ptr_zu_arr)[10] = &arr; //`&arr` ist nicht vom Typ `int *`! + // Es ist vom Typem "Pointer auf Array" (aus zehn `int`s) + // oder wenn das Array ein Stringliteral ist, welches gebraucht wird um ein + // `char`-Array zu initialisieren. + char anderer_arr[] = "foobarbazquirk"; + // oder wenn es das Argument des des `sizeof` oder `alignof` Operators ist. + int dritter_array[10]; + int *ptr = dritter_array; // gleich wie: `int *ptr = &arr[0]` + printf("%zu, %zu\n", sizeof(dritter_array), sizeof(ptr)); + // Gibt wahrscheinlich "40, 4" oder "40, 8" aus + + // Pointer werden basierend auf dem Typ in- und dekrementiert + // Dies wird Pointer-Arithmetik genannt. + printf("%d\n", *(x_ptr + 1)); // => 19 + printf("%d\n", x_array[1]); // => 19 + + // Man kann zusammenhängende Speicherblöcke auch mit der Funktion `malloc` + // aus der Standardbibliothek dynamisch allozieren. Der Funktion `malloc` + // muss ein Argument des Typs `size_t` übergeben werden, welches bestimmt, + // wie viele Bytes alloziert werden sollen. (Normalerweise geschieht dies + // aus dem Heap - dies kann auf eingebetteten Systemen unterschiedlichen sein. + // Der C Standard sagt nichts darüber.) + int *mein_ptr = malloc(sizeof(*mein_ptr) * 20); + for (xx = 0; xx < 20; xx++){ + *(mein_ptr + xx) = 20 -xx; //mein_ptr[xx] = 20-xx + } // initialisiere Speicher zu 20, 19, 18, 17, ... 2, 1 (als `int`) + + // Sei vorsichtig beim Übergeben von Benutzerdefinierten Werten an `malloc`. + // Wenn du sicher sein willst, kannst du die Funktion `calloc` nutzen, welche + // (nicht wie `malloc`) auch den Speicher nullt. + int *mein_anderer_ptr = calloc(20, sizeof(int)); + + // Merke, dass es in C keinen Standard-Weg gibt, um die Länge eines dynamisch + // allozierten Arrays zu bestimmen. Auf Grund dessen sollte eine Variable + // erstellt werden, welche sich die Anzahl der Elemente im Array merkt, wenn + // die Arrays mehrmals im Programm gebraucht werden. + // Weitere Informationen stehen im Abschnitt Funktionen. + size_t groesse = 10; + int *mein_array = calloc(groesse, sizeof(int)); + // Füge dem Array ein Element hinzu + groesse++; + mein_array = realloc(mein_array, sizeof(int) *groesse); + if (mein_array == NULL){ + // Denke daran, realloc-Fehler zu prüfen + return + } + mein_array[10] = 5; + + // Das Dereferenzieren von nicht alloziertem Speicher führt zu einem + // Undefinierten Verhalten. + printf("%d\n", *(mein_ptr + 21)); // Gibt irgendwas aus. Das Programm kann auch abstürzen + + // Nachdem du fertig mit einem Block bist, welcher `malloc` verwendet hat, + // muss der Speicher befreit werden. Ansonsten kann dieser Speicherbereich + // niemand nutzen bis dein Programm beendet wird. + // Dies wird auch als "Speicherleck" (engl: memory leak) bezeichnet. + free(mein_ptr); + + // Obwohl Strings normalerweise als Pointer-to-Char (Pointer zum ersten + // Zeichen des Arrays) repräsentiert werden, sind Strings sind Arrays aus `char`s. + // Es ist eine gute Praxis, `const char *` zu verwenden, wenn man ein + // String-Literal referenziert, da String-Literale nicht modifiziert werden + // sollten (z.B. "foo"[0] = 'a' ist ILLEGAL) + const char *mein_str = "Das ist mein eigener String"; + printf("%c\n", *mein_str); // => D + + // Dies ist nicht der Fall, wenn der String ein Array (möglicherweise mit + // einem String-Literal initialisiert) ist, welcher im beschreibbaren Speicher + // bleibt, wie zum Beispiel in: + char foo[] = "foo"; + foo[0] = 'a'; // Dies ist legal, foo enthält jetzt "aoo" + + funktion_1(); +} // Ende der `main`-Funktion -- cgit v1.2.3 From b8d10209a6d645b63a64593debf047566284392e Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 04:30:57 +0100 Subject: added german translation to function in c --- de-de/c-de.html.markdown | 100 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index c9e01181..20aade8d 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -530,3 +530,103 @@ error: funktion_1(); } // Ende der `main`-Funktion + +//////////////////////////////////////////////// +// Funktionen +//////////////////////////////////////////////// + +// Syntax einer Funktionsdeklaration +// () + +int addiere_zwei_integer(int x1, int x2){ + return x1 + x2; // verwendet return, um einen Wert zurückzugeben +} + +/* + * Funktionen werden auf Grund des Wertes aufgerufen (call-by-value). Wenn eine + * Funktion aufgerufen wird, sind die Argumente Kopien der ursprüunglichen Werte + * (ausgenommen Arrays). Alles, was man innerhalb einer Funktion mit den Werten + * macht, hat keinen Einfluss auf die Originalwerte als die Funktion aufgerufen + * wurde + + * Verwende Pointer, um den Originalinhalt zu bearbeiten. + + * Beispiel: +*/ + +// Eine `void`-Funktion gibt keinen Wert zurück +void str_reverse(char *str_in){ + char tmp; + size_t ii = 0; + size_t laenge = strlen(str_in); + // `strlen()` ist ein Teil der C Standard-Bibliothek. + // Merke: Die Länge, welche von `strlen` zurückgegeben wird, ist ohne den + // Null-Byter Terminatur. + for (ii = 0; i < laenge /2; ii++){ // in C99 kann man `ii` direkt hier deklarieren. + tmp = str_in[ii]; + str_in[ii] = str_in[laenge - ii - 1]; //#ii'tes Zeichen vom Ende her + str_in[laenge - ii- 1] = tmp; + } +} +// Merke: Die `string.h`-Headerdatei muss inkludiert werden, bevor `strlen()` +// verwendet werden kann. + +/* + * char c[] = "Das ist ein Test"; + * str_reverse(c); + * printf("%s\n", c), => "tseT nie tsi saD" +*/ + +// Weil wir lediglich eine Variable zurückgeben können, kann zum Ändern mehrerer +// Variablen das Konzept call-by-reference verwendet werden. +void tausche_zwei_zahlen(int *a, int *b){ + int temp = *a; + *a = *b; + *b = temp; +} +int erste_zahl = 10; +int zweite_zahl = 20; +printf("Erste Zahl: %d\n Zweite Zahl: %d\n", erste_zahl, zweite_zahl); +tausche_zwei_zahlen(&erste_zahl, &zweite_zahl); +printf("Erste Zahl: %d\n Zweite Zahl: %d\n", erste_zahl, zweite_zahl); +// Werte sind vertauscht. + +/* +Wenn man Arrays betrachtet, so werden diese immer als Pointer übergeben. Auch +wenn die Arrays statisch alloziert werden (wie zum Beispiel `arr[10]`), werden +diese als Pointer zum ersten Element des Arrays übergeben. +Auch hier soll noch einmal erwähnt werden, dass keinen Standard gibt, wie die +Grösse eines dynamischen Arrays herausgefunden werden kann. +*/ +// Die Grösse des Arrays muss unbedingt mitgegeben werden. +// Sonst hat die Funktion keine Ahnung wie gross das Array ist. +void ausgabe_int_array(int *arr, size_t size){ + int i; + for (i = 0; i < size; i++){ + printf("arr[%d] ist %d\n", i, arr[i]); + } +} + +int mein_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +int groesse = 10; +ausgabe_int_array(mein_array, groesse); +// Wird folgendes ausgeben: "arr[0] ist 1" usw. + +// Wenn man auf externe Variable (ausserhalb der Funktion) referenziert, sollte +// man das Schlüsselwort `extern` verwenden. +int i = 0; +void test_funktion(){ + extern int i; //i braucht nun die externe Variable i +} + +// Das Schlüsselwort `static` macht, dass eine Variable ausserhalb der Kompilier- +// einheit nicht zugreifbar ist. (Auf den meisten Systemen ist eine Kompiliereinheit +// eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl global (zur Kompiliereinheit gehörende) +// Variablen, Funktionen und Funktionslokale Variablen angewendet werden. +// Wenn man `static` bei lokalen Variablen verwendet, so ist diese Variable global +// erreichbar und behält dessen Wert über Funktionsaufrufe hinweg, aber sie ist +// nur innerhalb der deklarierten Funktion verfügbar. Ausserdem werden statische +// Variablen mit 0 initialisiert, wenn sie nicht mit einem anderen Startwert +// initialisiert werden. +// Es ist auch möglich, Funktionen als statisch zu deklarieren, damit diese +// `private` sind. Private heisst, dass sie nur in diesem Kontekt sichtbar sind. -- cgit v1.2.3 From a0d2ed81aebd48f60135c554a959d8ad7a47984b Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 05:14:28 +0100 Subject: added user defined types and structs --- de-de/c-de.html.markdown | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 20aade8d..509e08fa 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -630,3 +630,56 @@ void test_funktion(){ // initialisiert werden. // Es ist auch möglich, Funktionen als statisch zu deklarieren, damit diese // `private` sind. Private heisst, dass sie nur in diesem Kontekt sichtbar sind. + + +//////////////////////////////////////////////// +// Benutzerdefinierte Typen und Strukturen (Structs) +//////////////////////////////////////////////// + +// `typdef`s können verwendet werden, um Typenaliase zu erstellen. +typedef int mein_typ; +mein_typ meine_typ_var = 0; + +// Structs sind lediglich Sammlungen von Daten, die Inhalte werden +// (in der Reihenfolge wie sie geschrieben wurden) sequentiell alloziert. +struct rechteck{ + int breite; + int hoehe; +}; + +// Allgemein ist es nicht so, dass folgender Ausdruck wahr ist. +// sizeof(struct rechteck) == sizeof(int) + sizeof(int) +// Dies ist so, weil potentiell ein Padding zwischen den Struktur-Inhalten +// möglich ist). siehe [1] + +void funktion_1(){ + struct rechteck mein_rechteck; + + // Greife auf Struct-Inhalte mit `.` zu. + mein_rechteck.breite = 10; + mein_rechteck.hoehe = 20; + + // Du kannst Pointer zu Structs deklarieren. + struct rechteck *mein_rechteck_ptr = &mein_rechteck; + + // Verwende Dereferenzierung, um Struct-Inhalte zu bearbeiten + (*mein_rechteck_ptr).breite = 30; + + //Noch besser: Verwende die Kurzschreibweise ->, um die Lesbarkeit zu verbessern. + mein_rechteck_ptr->hoehe = 10; // Das gleiche wie: (*mein_rechteck_ptr).hoehe = 10; +} + +// Aus Bequemlichkeitsgründen ist es möglich einem `struct` ein `typedef`hinzuzufügen. +typedef struct rechteck recht; + +int flaeche(recht r){ + return r.breite * r.hoehe; +} + +// Wenn du grosse Structs hast, kannst du diese mit dem Pointer kopieren, +// damit grosse Kopiervorgänge vermieden werden. +int flaecheptr(const recht *r){ + return r->breite * r->hoehe; +} + +[1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) -- cgit v1.2.3 From 38d3c33507d0d91103a8b1c7df9593e22938d960 Mon Sep 17 00:00:00 2001 From: caminsha Date: Fri, 31 Jan 2020 05:15:23 +0100 Subject: translated section of function pointers to German --- de-de/c-de.html.markdown | 72 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 509e08fa..946d8329 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -682,4 +682,76 @@ int flaecheptr(const recht *r){ return r->breite * r->hoehe; } +//////////////////////////////////////////////// +// Funktionspointer +//////////////////////////////////////////////// + +/* +Zur Laufzeit sind Funktionen in einer Speicheradresse gespeichert. +Funktionspointer sind wie normale Pointer (es wird einfach eine Speicheradresse +geseichert). Funktionspointer können verwendet werden, um Funktionen und +Handler (oder Callback-Funktionen) direkt aufzurufen. +Wie auch immer, die Syntax kann zu Beginn verwirrend wirken. + +Zum Beispiel: Verwende str_reverse von einem Pointer +*/ +void str_reverse_through_pointer(char *str_in){ + // Definiere eine Funktionspointer-Variable, welche f genannt wird. + void (*f)(char *); // Signatur sollte genau der Funktion entsprechen. + f = &str_reverse; // weise die Adresse der wirklichen Funktion zu (zur Laufzeit bestimmt) + // `f = str_reverse;` würde auch funktionieren, da Funktionen zu Pointern + // reduziert werden (ähnlich wie Arrays) + (*f)(str_in); // Die Funktion einfach mit dem Pointer aufrufen + // f(str_in); // Dies ist eine weitere gültige Alternative um eine Funktion auzurufen. +} + +/* +Solange die Signaturen der Funktionen übereinstimmen, kann man sämtliche Funktionen +demselben Pointer zuweisen. Funktionspointer sind auf Grund der Einfacheit und +Leserlichkeit normalerweise wie folgt `typedef`d +*/ +typedef void (*mein_fnp_type)(char *); +// Danach werden diese genutzt, um die wirkliche Pointervariable zu deklarieren. +// .. +// mein_fnp_type f; + +// Spezialzeichen +// Im folgenden sin die englischen Begriffe jeweils in Klammern geschrieben, +// da diese Begriffe auch im deutschten Sprachgebrauch verwendet werden. +'\a'; // Alarmzeichen (alert (bell) character) +'\n'; // Zeichen für neue Linie (newline character) +'\t'; // Tab (tab character (left justifies text)) +'\v'; // Vertikaler Tab (vertical tab) +'\f'; // Neue Seite (new page (form feed)) +'\r'; // Wagenrücklauf (carriage return) +'\b'; // Backspace-Zeichen (backspace character) +'\0'; // Null-Byte (NULL character). In C wird dieses Zeichen normalerweise am Ende eines Strings gesetzt. +// Beispiel: Hallo\n\0. \0 wird per Konvention verwendet, um das Ende eines Strings zu kennzeichnen. +'\\'; // Backslash (backslash) +'\?'; // Fragezeichen (question mark) +'\''; // einfaches Anführungszeichen (single quote) +'\"'; // doppeltes Anführungszeichen (double quote) +'\xhh'; // Hexadezimale Zahl (hexadecimal number.) Beispiel: '\xb' = Zeichen für vertikalen Tab +'\0oo'; // Oktalzahl (octal number). Beispiel \013 = Zeichen für vertikalen Tab + +//Ausgabeformatierung +"%d"; // Integer +"%3d"; // integer mit einer minimalen Länge von drei Zeichen. +"%s"; // String +"%f"; // Float +"%ld"; // Long +"%3.2f"; // Mindest drei Zeichen vor und drei nach dem Komma. +"%7.4s"; // (Kann auch mit Strings gemacht werden) +"%c"; // Char +"%p"; // Pointer. Merke: man muss den Pointer zu void umwandeln, bevor `printf`funktioniert. +"%x"; // Hexadezimal +"%o"; // Oktalzahl +"%%"; // Gibt % aus + + + + + + + [1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) -- cgit v1.2.3 From bc9c26d44c32fe6609f3434891efadad27ff5e6b Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 00:27:18 +0100 Subject: translated associativity of operators --- de-de/c-de.html.markdown | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 946d8329..36865900 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -748,7 +748,29 @@ typedef void (*mein_fnp_type)(char *); "%o"; // Oktalzahl "%%"; // Gibt % aus +//////////////////////////////////////////////// +// Reihenfolge der Auswertung +//////////////////////////////////////////////// +//-------------------------------------------------------// +// Operatoren | Assoziativität // +//-------------------------------------------------------// +// () [] -> . | linksassoziativ // +// ! ~ ++ -- + = *(type)sizeof | rechtsassoziativ // +// * / % | linksassoziativ // +// + - | linksassoziativ // +// << >> | linksassoziativ // +// < <= > >= | linksassoziativ // +// == != | linksassoziativ // +// & | linksassoziativ // +// ^ | linksassoziativ // +// | | linksassoziativ // +// && | linksassoziativ // +// || | linksassoziativ // +// ?: | rechtsassoziativ // +// = += -= *= /= %= &= ^= |= <<= >>= | rechtsassoziativ // +// , | linksassoziativ // +//-------------------------------------------------------// -- cgit v1.2.3 From f3975fdc0e1cc6001565c854b209e118fb323665 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 00:27:55 +0100 Subject: Translated part headerfiles to German --- de-de/c-de.html.markdown | 60 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 36865900..70f5cc94 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -773,7 +773,67 @@ typedef void (*mein_fnp_type)(char *); //-------------------------------------------------------// +//////////////////////////////////////////////// +// Header-Dateien +//////////////////////////////////////////////// +/* +Header-Dateien sind ein wichtiger Teil von C, da sie eine Verbindung zwischen +unterschiedlichen C-Quelldateien herstellen. Ausserdem vereinfachen Header-Dateien +den Code und Definitionen, da diese in separaten Daten geschrieben werden können. + +Header-Dateien sind von der Syntax her ähnlich zu C-Quelldateien, allerdings haben +die Header-Dateien die Dateiendung `.h`. Header-Dateien können im Quellcode mit +der `#include`-Anweisung eingebunden werden z.B. `#include "beispiel.h". Die +vorherige Anweisung geht davon aus, dass sich die Header-Datei im selben Ordner +befindet wie die C-Quelldatei. +*/ + +// Eine sichere Möglichkeit, einen Header mehrere Male zu definieren bietet, das +// folgende Statement. Die mehrfache Definition geschieht, wenn Kreisabhängigkeiten +// bestehen. +#ifndef BEISPIEL_H /* Wenn BEISPIEL_H noch nicht definiert wurde */ +#define BEISPIEL_H /* definiere das Makro BEISPIEL_H */ + +// Es könenn weitere Header innerhalb eines Headers eingebunden werden, was dazu +// führt, dass diese bereits in anderen Dateien eingebunden wurden. So kann eine +// Header-Datei in mehreren Dateien eingebunden werden. zum Beispiel: +#include +// Wie in den Quelldateien können auch in den Header-Dateien Makros definiert +// werden und in anderen Dateien verwendet werden, welche diesen Header einbinden. +#define BEISPIEL_NAME "Dennis Ritchie" + +// Funktionsmakros können auch definiert werden. +#define ADD(a, b) ((a) + (b)) + +// Beachte die Klammern, welche um die Argumente geschrieben wurden - diese sind +// wichtig, damit sichergestellt werden kann, dass a und b nicht unerwartet +// erweitert werden. Zum Beispiel: `MUL (x,y) (x * y)`; Bei der Verwendung von +// `MUL(1 + 2, 3)` würde dies wie folgt erweitert werden: `(1 + 2 * 3)`, was zu +// einem falschen Resultat führen würde. + +// Strukturen und Typendefinitionen können verwendet werden, um die Konsistenz +// zwischen unterschiedlichen Dateien beizubehalten. +typedef struct Knoten{ + int wert; + struct Knoten *naechster; +}Knoten; + +// Dies kann auch mit Aufzählungen gemacht werden. +enum ampel_status {GRUEN, GELB, ROT}; + +// Funktionsprototypen könenn auch in Header-Dateien definiert werden, um die +// Funktion in unterschiedlichen Dateien zu verwenden, aber dies wird als schlechte +// Praxis angesehen. Definitionen sollten in einer C-Datei erstellt werden. +Knoten erstelleVerketteteListe(int *werte, int laenge); + +// Ausser den oben genannten Elementen, sollten weitere Definitionen in einer +// C-Datei gemacht werden. Übermässige Includes und Definitionen sollten auch +// nicht einer Header-Datei gemacht werden. Stattdessen wird es empfohlen, diese +// in eine separate Header-Datei oder in eine C-Quelldatei zu schreiben. + +#endif /* Ende der Präprozessordirektive */ +``` [1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) -- cgit v1.2.3 From edeb77b89394e913054d74af178da7bdab429158 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 00:28:07 +0100 Subject: translated further reading --- de-de/c-de.html.markdown | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 70f5cc94..0b52284c 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -835,5 +835,27 @@ Knoten erstelleVerketteteListe(int *werte, int laenge); #endif /* Ende der Präprozessordirektive */ ``` +## Weiterführende Literatur + +Das Beste wird es sein, wenn man sich ein Exemplar des Buches +["The C Programming Language"](https://de.wikipedia.org/wiki/The_C_Programming_Language) besorgt. +Dieses Buch gilt als *das* Buch über die Programmiersprache C und wurde von Dennis Ritchie, +dem Erfinder der Programmiersprache C, und Brian Kernighan geschrieben. +Sei vorsichtig, da dieses Buch mittlerweile schon etwas älter ist und gewisse +Unkorrektheiten (d.h. Ideen, welche nicht mehr als gut empfunden werden.) oder +mittlerweile geänderte Praktiken enthält. [Hinweis: Das Buch wurde auf Englisch +geschrieben, es gibt aber auch eine Übersetzung davon] + +Eine weitere gute Resource ist [Learn C The Hard Way](http://learncodethehardway.org/c/). +[Englisch] + +Solltest du Fragen zu C haben, so lies die FAQ [compl.lang.c Frequently Asked Questions](http://c-faq.com).[Englisch] + +Ausserdem ist es wichtig, eine saubere Einrückung zu verwenden. Des weiteren ist +es wichtig, dass der Codestil möglichst konsistent ist. Es ist wichtiger, lesbaren +Code zu schreiben als Code, welcher clever und schnell ist. Es lohnt sich ein +Blick auf den [Codestil des Linuxkernel](https://www.kernel.org/doc/Documentation/process/coding-style.rst) zu werfen. [Englisch] + +Wenn die erwähnte Literatur dein Problem nicht löst, denke daran: "Google ist dein Freund" [1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) -- cgit v1.2.3 From 0996b5a20ed351046ad9e67f01d1593ffe769a34 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 01:00:55 +0100 Subject: Fixed some small typos in german translation --- de-de/c-de.html.markdown | 98 ++++++++++++++++++++++++------------------------ 1 file changed, 50 insertions(+), 48 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 0b52284c..db64b6df 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -13,11 +13,11 @@ Programmierer je brauchen werden. Die Geschwindigkeit von C ist enorm, allerding muss man sich stets der maneullen Speicherverwaltung bewusst sein. -> **Über Compiler Flags** +> **Über Compiler Optionen** > > Standardmässig sind `gcc` und `clang` ziemlich ruhig bezüglich Warnungen und > Fehlern, obwohl dies sehr nützliche Informationen sein können. Es wird -> empfohlen, strengere Compiler Flags zu verwenden. Hier sind einige empfohlene +> empfohlen, strengere Compiler Optionen zu verwenden. Hier sind einige empfohlene > Standards: > `-Wall -Wextra -Werror -O2 -std=c99 -pedantic` > @@ -33,7 +33,7 @@ mehrzeilige Kommentare sehen so aus. Diese funktionieren auch in C89 */ /* -mehrzeilige Kommentare können nicht verschaltelt werden /* Sei Vorsichtig! */ // Kommentar endet auf dieser Linie ... +mehrzeilige Kommentare können nicht verschachtelt werden /* Sei Vorsichtig! */ // Kommentar endet auf dieser Linie ... */ // ... nicht bei dieser! // Konstanten: #define @@ -89,7 +89,7 @@ int main (int argc, char** argv){ // Typen //////////////////////////////////////////////// - // Alle Variable müssen am Anfang des jetzigen Blocks deklariert werden. + // Alle Variablen müssen am Anfang des jetzigen Blocks deklariert werden. // Wir deklarieren die Variablen dynamisch im Code um die Lesbarkeit im // Tutorial zu verbessern. // C99-Konforme Compiler erlauben die Variablendeklaration an dem Punkt, an @@ -121,7 +121,7 @@ int main (int argc, char** argv){ unsigned int ux_int; unsigned long long ux_long_long; - // chars innerhalb von einfachen Anführungszeichen sind Integers im + // Zeichen innerhalb von einfachen Anführungszeichen sind Integers im // Maschinenzeichensatz '0'; // => 48 im ASCII-Zeichensatz 'A'; // => 65 im ASCII-Zeichensatz @@ -187,7 +187,7 @@ int main (int argc, char** argv){ // Strings sind lediglich Arrays von `chars`, welche mit einem Null-Byte // (0x00) beendet werden. In Strings wird das Nullbyte durch das Zeichen \0 // repräsentiert. Wir müssen das Null-Byte nicht angeben in String-Literalen; - // Der Compiler fügt es am Ende des Array automatisch hinzu. + // der Compiler fügt es am Ende des Array automatisch hinzu. char ein_string[20] = "Das ist ein String"; printf("%s\n", ein_string); // %s formattiert einen String @@ -222,9 +222,9 @@ int main (int argc, char** argv){ i1 + i2; // => 3 i2 - i1; // => 1 i2 * i1; // => 2 - i1 / i2; // 0 (0.5, aber abgeschnitten, da es int sind. + i1 / i2; // 0 (0.5, aber abgeschnitten, da es int sind.) - // Man muss mindestens ein Integer to einen float konvertieren, damit man als + // Man muss mindestens ein Integer zu einen float konvertieren, damit man als // Resultat eine Gleitkommazahl erhält. (float)i1 / i2; // => 0.5f i1 / (double)i2; // => 0.5 // das gleiche mit dem Typ `double` @@ -245,7 +245,7 @@ int main (int argc, char** argv){ 2 <= 2; // => 1 2 >= 2; // => 1 - // C ist nicht Python - Vergleiche können nicht verkettet werden. + // C ist nicht Python - Vergleiche können nicht einfach verkettet werden. // Warnung: die folgende Zeile wird kompilieren, aber es bedeutet `(0 < a) < 2`. // Dieser Ausdruck ist immer wahr, weil (0 < a) kann entweder 1 oder 0 sein. // In diesem Falle ist es 1, weil (0 < 1). @@ -278,8 +278,8 @@ int main (int argc, char** argv){ 0x0F & 0xF0; // => 0x00 (Bitweises UND) 0x0F | 0xF0; // => 0xFF (Bitweises ODER) 0x04 ^ 0x0F; // => 0x0B (Bitweises XOR) - 0x01 << 1; // => 0x02 (Bitweises Linksshift (left shift) (um 1)) - 0x02 >> 1; // => 0x01 (Bitweises Rechtsshift (right shift) (um 1)) + 0x01 << 1; // => 0x02 (Bitweises Linksverschiebung (left shift) (um 1)) + 0x02 >> 1; // => 0x01 (Bitweises Rechtsverschiebung (right shift) (um 1)) // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern - folgende Ausdrücke sind nicht definiert: // - Verschiebung in das Vorzeichenbit (int a = 1 << 31) @@ -325,18 +325,18 @@ int main (int argc, char** argv){ printf("\n"); // **Merke** - // Schleifen und Funktionen müssen einen Body haben. Wenn kein Body gebraucht + // Schleifen und Funktionen müssen einen Rumpf haben. Wenn kein Rumpf gebraucht // wird, kann folgendes gemacht werden: int i; for (i = 0; i <= 5; i++){ - ; // Semikolon wird als Body behandelt (Null-Anweisung) + ; // Semikolon wird als Rumpf behandelt (Null-Anweisung) } // Alternativ kann auch folgendes geschrieben werden: for (i = 0; i <= 5; i++); // Verzweigungen mit mehreren Möglichkeiten: `switch()` switch (a){ - case 0: //labels müssen integrale *konstante* Ausdrücke sein (z.B. Enums) + case 0: // Labels müssen integrale *konstante* Ausdrücke sein (z.B. Enums) printf("Hey, 'a' ist gleich 0!\n"); break; //Wenn du kein break einsetzt, so geht der Kontrollfluss durch die Labels case 1: @@ -405,10 +405,10 @@ error: // In diesem Tutorial wird das deutsche Wort Zeiger nicht verwendet, da es // bei einer weiteren Recherche einfacher ist, wenn man von Pointern ausgeht. - // Ausserdem ist der Begriff Pointer auf im deutschen Sprachgebrauch zu finden. + // Ausserdem ist der Begriff Pointer auch im deutschen Sprachgebrauch zu finden. // Ein Pointer ist eine Variable, welche deklariert wurde, um eine Speicher- - // Adresse zu speichern. Die Deklaration eines Pointers wird auch zeigen, + // adresse zu speichern. Die Deklaration eines Pointers wird auch zeigen, // auf welche Art von Daten der Pointer zeigt. Man kann die Speicheradresse // von Variablen abrufen und dann mit diesen herumspielen. @@ -461,7 +461,7 @@ error: // oder wenn das Array ein Stringliteral ist, welches gebraucht wird um ein // `char`-Array zu initialisieren. char anderer_arr[] = "foobarbazquirk"; - // oder wenn es das Argument des des `sizeof` oder `alignof` Operators ist. + // oder wenn es das Argument des `sizeof` oder `alignof` Operators ist. int dritter_array[10]; int *ptr = dritter_array; // gleich wie: `int *ptr = &arr[0]` printf("%zu, %zu\n", sizeof(dritter_array), sizeof(ptr)); @@ -515,7 +515,7 @@ error: free(mein_ptr); // Obwohl Strings normalerweise als Pointer-to-Char (Pointer zum ersten - // Zeichen des Arrays) repräsentiert werden, sind Strings sind Arrays aus `char`s. + // Zeichen des Arrays) repräsentiert werden, sind Strings Arrays aus `char`s. // Es ist eine gute Praxis, `const char *` zu verwenden, wenn man ein // String-Literal referenziert, da String-Literale nicht modifiziert werden // sollten (z.B. "foo"[0] = 'a' ist ILLEGAL) @@ -536,22 +536,22 @@ error: //////////////////////////////////////////////// // Syntax einer Funktionsdeklaration -// () +// () int addiere_zwei_integer(int x1, int x2){ return x1 + x2; // verwendet return, um einen Wert zurückzugeben } /* - * Funktionen werden auf Grund des Wertes aufgerufen (call-by-value). Wenn eine - * Funktion aufgerufen wird, sind die Argumente Kopien der ursprüunglichen Werte - * (ausgenommen Arrays). Alles, was man innerhalb einer Funktion mit den Werten - * macht, hat keinen Einfluss auf die Originalwerte als die Funktion aufgerufen - * wurde +Funktionen werden auf Grund des Wertes aufgerufen (call-by-value). Wenn eine +Funktion aufgerufen wird, sind die Argumente Kopien der ursprüunglichen Werte +(ausgenommen Arrays). Alles, was man innerhalb einer Funktion mit den Werten +macht, hat keinen Einfluss auf die Originalwerte als die Funktion aufgerufen +wurde - * Verwende Pointer, um den Originalinhalt zu bearbeiten. +Verwende Pointer, um den Originalinhalt zu bearbeiten. - * Beispiel: +Beispiel: */ // Eine `void`-Funktion gibt keinen Wert zurück @@ -561,7 +561,7 @@ void str_reverse(char *str_in){ size_t laenge = strlen(str_in); // `strlen()` ist ein Teil der C Standard-Bibliothek. // Merke: Die Länge, welche von `strlen` zurückgegeben wird, ist ohne den - // Null-Byter Terminatur. + // Null-Byte Terminator. for (ii = 0; i < laenge /2; ii++){ // in C99 kann man `ii` direkt hier deklarieren. tmp = str_in[ii]; str_in[ii] = str_in[laenge - ii - 1]; //#ii'tes Zeichen vom Ende her @@ -572,9 +572,9 @@ void str_reverse(char *str_in){ // verwendet werden kann. /* - * char c[] = "Das ist ein Test"; - * str_reverse(c); - * printf("%s\n", c), => "tseT nie tsi saD" +char c[] = "Das ist ein Test"; +str_reverse(c); +printf("%s\n", c), => "tseT nie tsi saD" */ // Weil wir lediglich eine Variable zurückgeben können, kann zum Ändern mehrerer @@ -595,7 +595,7 @@ printf("Erste Zahl: %d\n Zweite Zahl: %d\n", erste_zahl, zweite_zahl); Wenn man Arrays betrachtet, so werden diese immer als Pointer übergeben. Auch wenn die Arrays statisch alloziert werden (wie zum Beispiel `arr[10]`), werden diese als Pointer zum ersten Element des Arrays übergeben. -Auch hier soll noch einmal erwähnt werden, dass keinen Standard gibt, wie die +Auch hier soll noch einmal erwähnt werden, dass es keinen Standard gibt, wie die Grösse eines dynamischen Arrays herausgefunden werden kann. */ // Die Grösse des Arrays muss unbedingt mitgegeben werden. @@ -616,7 +616,7 @@ ausgabe_int_array(mein_array, groesse); // man das Schlüsselwort `extern` verwenden. int i = 0; void test_funktion(){ - extern int i; //i braucht nun die externe Variable i + extern int i; // i braucht nun die externe Variable i } // Das Schlüsselwort `static` macht, dass eine Variable ausserhalb der Kompilier- @@ -629,14 +629,14 @@ void test_funktion(){ // Variablen mit 0 initialisiert, wenn sie nicht mit einem anderen Startwert // initialisiert werden. // Es ist auch möglich, Funktionen als statisch zu deklarieren, damit diese -// `private` sind. Private heisst, dass sie nur in diesem Kontekt sichtbar sind. +// `private` sind. Privat heisst, dass sie nur in diesem Kontekt sichtbar sind. //////////////////////////////////////////////// // Benutzerdefinierte Typen und Strukturen (Structs) //////////////////////////////////////////////// -// `typdef`s können verwendet werden, um Typenaliase zu erstellen. +// `typedef`s können verwendet werden, um Typenaliase zu erstellen. typedef int mein_typ; mein_typ meine_typ_var = 0; @@ -650,7 +650,7 @@ struct rechteck{ // Allgemein ist es nicht so, dass folgender Ausdruck wahr ist. // sizeof(struct rechteck) == sizeof(int) + sizeof(int) // Dies ist so, weil potentiell ein Padding zwischen den Struktur-Inhalten -// möglich ist). siehe [1] +// möglich ist). (siehe [1, Englisch]) void funktion_1(){ struct rechteck mein_rechteck; @@ -669,7 +669,7 @@ void funktion_1(){ mein_rechteck_ptr->hoehe = 10; // Das gleiche wie: (*mein_rechteck_ptr).hoehe = 10; } -// Aus Bequemlichkeitsgründen ist es möglich einem `struct` ein `typedef`hinzuzufügen. +// Aus Bequemlichkeitsgründen ist es möglich einem `struct` ein `typedef` hinzuzufügen. typedef struct rechteck recht; int flaeche(recht r){ @@ -689,7 +689,7 @@ int flaecheptr(const recht *r){ /* Zur Laufzeit sind Funktionen in einer Speicheradresse gespeichert. Funktionspointer sind wie normale Pointer (es wird einfach eine Speicheradresse -geseichert). Funktionspointer können verwendet werden, um Funktionen und +gespeichert). Funktionspointer können verwendet werden, um Funktionen und Handler (oder Callback-Funktionen) direkt aufzurufen. Wie auch immer, die Syntax kann zu Beginn verwirrend wirken. @@ -725,8 +725,10 @@ typedef void (*mein_fnp_type)(char *); '\f'; // Neue Seite (new page (form feed)) '\r'; // Wagenrücklauf (carriage return) '\b'; // Backspace-Zeichen (backspace character) -'\0'; // Null-Byte (NULL character). In C wird dieses Zeichen normalerweise am Ende eines Strings gesetzt. -// Beispiel: Hallo\n\0. \0 wird per Konvention verwendet, um das Ende eines Strings zu kennzeichnen. +'\0'; // Null-Byte (NULL character). In C wird dieses Zeichen normalerweise am +// Ende eines Strings gesetzt. +// Beispiel: Hallo\n\0. "\0" wird per Konvention verwendet, um das Ende +// eines Strings zu kennzeichnen. '\\'; // Backslash (backslash) '\?'; // Fragezeichen (question mark) '\''; // einfaches Anführungszeichen (single quote) @@ -736,20 +738,20 @@ typedef void (*mein_fnp_type)(char *); //Ausgabeformatierung "%d"; // Integer -"%3d"; // integer mit einer minimalen Länge von drei Zeichen. +"%3d"; // Integer mit einer minimalen Länge von drei Zeichen. "%s"; // String -"%f"; // Float -"%ld"; // Long -"%3.2f"; // Mindest drei Zeichen vor und drei nach dem Komma. +"%f"; // Gleitkommazahl (float) +"%ld"; // genauere Gleitkommazahl (long) +"%3.2f"; // Mindestens drei Zeichen vor und drei nach dem Komma. "%7.4s"; // (Kann auch mit Strings gemacht werden) -"%c"; // Char -"%p"; // Pointer. Merke: man muss den Pointer zu void umwandeln, bevor `printf`funktioniert. +"%c"; // einzelnes Zeichen (char) +"%p"; // Pointer. Merke: man muss den Pointer zu void umwandeln, bevor `printf` funktioniert. "%x"; // Hexadezimal "%o"; // Oktalzahl "%%"; // Gibt % aus //////////////////////////////////////////////// -// Reihenfolge der Auswertung +// Reihenfolge der Auswertung von Operatoren //////////////////////////////////////////////// //-------------------------------------------------------// @@ -780,7 +782,7 @@ typedef void (*mein_fnp_type)(char *); /* Header-Dateien sind ein wichtiger Teil von C, da sie eine Verbindung zwischen unterschiedlichen C-Quelldateien herstellen. Ausserdem vereinfachen Header-Dateien -den Code und Definitionen, da diese in separaten Daten geschrieben werden können. +den Code und Definitionen, da diese in separaten Dateien geschrieben werden können. Header-Dateien sind von der Syntax her ähnlich zu C-Quelldateien, allerdings haben die Header-Dateien die Dateiendung `.h`. Header-Dateien können im Quellcode mit @@ -811,7 +813,7 @@ befindet wie die C-Quelldatei. // wichtig, damit sichergestellt werden kann, dass a und b nicht unerwartet // erweitert werden. Zum Beispiel: `MUL (x,y) (x * y)`; Bei der Verwendung von // `MUL(1 + 2, 3)` würde dies wie folgt erweitert werden: `(1 + 2 * 3)`, was zu -// einem falschen Resultat führen würde. +// einem falschen Resultat führt. // Strukturen und Typendefinitionen können verwendet werden, um die Konsistenz // zwischen unterschiedlichen Dateien beizubehalten. -- cgit v1.2.3 From 5ff9fd5659c308dc7a8e3767bef09934a04cc62b Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 01:05:29 +0100 Subject: Added suffix to filename because of contributing guidelines --- de-de/c-de.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index db64b6df..40c6489c 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -1,6 +1,6 @@ --- language: c -filename: learnc.c +filename: learnc-de.c contributors: - ["caminsha", "https://github.com/caminsha"] lang: de-de -- cgit v1.2.3 From 8041d796bbddf8ad61a3fb7e38acfb5f9659567b Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 02:18:13 +0100 Subject: Fixed small typo in include statement --- de-de/c-de.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 40c6489c..72928516 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -47,7 +47,7 @@ enum tage {SO=1, MO, DI, MI, DO, FR, SA}; // Importiere Header-Dateien mit #include #include -#include +#include #include // Dateien, welche zwischen stehen, sind Header-Dateien aus -- cgit v1.2.3 From a765253cd49af22d757b21c7725d22d892a8aae3 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 02:19:22 +0100 Subject: Changed italic typing to bold --- de-de/c-de.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 72928516..6670ac46 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -841,7 +841,7 @@ Knoten erstelleVerketteteListe(int *werte, int laenge); Das Beste wird es sein, wenn man sich ein Exemplar des Buches ["The C Programming Language"](https://de.wikipedia.org/wiki/The_C_Programming_Language) besorgt. -Dieses Buch gilt als *das* Buch über die Programmiersprache C und wurde von Dennis Ritchie, +Dieses Buch gilt als **das** Buch über die Programmiersprache C und wurde von Dennis Ritchie, dem Erfinder der Programmiersprache C, und Brian Kernighan geschrieben. Sei vorsichtig, da dieses Buch mittlerweile schon etwas älter ist und gewisse Unkorrektheiten (d.h. Ideen, welche nicht mehr als gut empfunden werden.) oder -- cgit v1.2.3 From 8e1372e08bf29428f9e59f10744f4182e29bbcc4 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sat, 1 Feb 2020 02:26:58 +0100 Subject: Changed some lines so that it is not more than 80 chars --- de-de/c-de.html.markdown | 75 +++++++++++++++++++++++++++++------------------- 1 file changed, 46 insertions(+), 29 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 6670ac46..64159c31 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -73,9 +73,10 @@ int main(void){ // dein Programm } -// Die Kommandozeilenargumente, welche gebraucht werden, damit dein Programm läuft, -// werden als Argumente der `main`-Funktion mitgegeben. -// argc steht für die Anzahl von Argumenten. - Der Programmname ist das erste Argument. +// Die Kommandozeilenargumente, welche gebraucht werden, damit dein Programm +// läuft, werden als Argumente der `main`-Funktion mitgegeben. +// argc steht für die Anzahl von Argumenten. - Der Programmname ist das erste +// Argument. // argv ist ein Array von Zeichenarrays, welche die Argumente beinhaltet. // argv[0] = Name des Programms // argv[1] = erstes Argument usw. @@ -116,7 +117,8 @@ int main (int argc, char** argv){ // doubles sind normalerweise 64-Bit Gleitkommazahlen double x_double = 0.0; // echte Zahlen ohne Suffix sind vom Typ double - // integer-Typen können vorzeichenlos (unsigned) sein (grösser oder kleiner als 0) + // integer-Typen können vorzeichenlos (unsigned) sein + // (grösser oder kleiner als 0) unsigned short ux_short; unsigned int ux_int; unsigned long long ux_long_long; @@ -129,7 +131,7 @@ int main (int argc, char** argv){ // sizeof(T) gibt die Grösse einer Variablen des Typen T in Bytes zurück. // sizeof(obj) ergibt die Grösse des Ausdrucks (Variable, Literal usw.) - printf("%zu\n", sizeof(int)); // => 4 (auf den meisten Rechnern mit einem 4-Byte-Wort) + printf("%zu\n", sizeof(int)); // => 4 (auf den Rechnern mit einem 4-Byte-Wort) // Wenn das Argument des `sizeof`-Operator ein Ausdruck ist, dann wird das // Argument nicht ausgewertet (ausser Arrays mit variabler Länge) @@ -174,7 +176,8 @@ int main (int argc, char** argv){ // In C99 (und als optionales Feature in C11) können Arrays mit variabler // Länge deklariert werden. Die Grösse eines solchen Array muss eine Konstante // zur Kompilierzeit sein. - printf("Geben Sie die Arraygrösse an: "); //Frag den Benutzer nach der Arraygrösse + printf("Geben Sie die Arraygrösse an: "); //Frag den Benutzer nach + // der Arraygrösse int array_size; fcsanf(stdin, "%d", &array_size); int var_length_array[array_size]; // deklariere Array mit variabler Länge @@ -234,8 +237,8 @@ int main (int argc, char** argv){ // Es gibt auch die Möglichkeit, Modulo zu rechnen 11 % 3; // => 2 - // Vergleichsoperatoren sind vielleicht schon bekannt, aber in C gibt es keinen - // Boolean-Typ. In C verwenden wir `int`. (Oder _Bool oder bool in C99.) + // Vergleichsoperatoren sind vielleicht schon bekannt, aber in C gibt es + // keinen Boolean-Typ. In C verwenden wir `int`. (Oder _Bool oder bool in C99) // 0 ist falsch, alles andere ist wahr (Die Vergleichsoperatoren ergeben // immer 1 oder 0. 3 == 2; // => 0 (falsch) @@ -274,14 +277,16 @@ int main (int argc, char** argv){ // das gleiche gilt für j-- und --j // Bitweise Operatoren - ~0x0F; // => 0xFFFFFFF0 (Bitweise Negation, "Einer-Komplement", Beispielresultat für 32-Bit int) + ~0x0F; // => 0xFFFFFFF0 (Bitweise Negation, "Einer-Komplement", + // Beispielresultat für 32-Bit int) 0x0F & 0xF0; // => 0x00 (Bitweises UND) 0x0F | 0xF0; // => 0xFF (Bitweises ODER) 0x04 ^ 0x0F; // => 0x0B (Bitweises XOR) 0x01 << 1; // => 0x02 (Bitweises Linksverschiebung (left shift) (um 1)) 0x02 >> 1; // => 0x01 (Bitweises Rechtsverschiebung (right shift) (um 1)) - // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern - folgende Ausdrücke sind nicht definiert: + // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern + // folgende Ausdrücke sind nicht definiert: // - Verschiebung in das Vorzeichenbit (int a = 1 << 31) // - Linksshift einer negativen Zahl (int a = -1 << 2) // - Shift um einen Offset, welcher >= die Breite des linken Ausdrucks ist. @@ -303,7 +308,8 @@ int main (int argc, char** argv){ // While-Schleifen existieren auch int ii = 0; while (ii < 10){ // JEDER Wert unter zehn ist wahr - printf("%d, " ii++); //i++ inkrementiert ii NACHDEM der Wert gebraucht wurde. + printf("%d, " ii++); //i++ inkrementiert ii NACHDEM der Wert gebraucht + // wurde. } // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " printf("\n"); @@ -338,12 +344,13 @@ int main (int argc, char** argv){ switch (a){ case 0: // Labels müssen integrale *konstante* Ausdrücke sein (z.B. Enums) printf("Hey, 'a' ist gleich 0!\n"); - break; //Wenn du kein break einsetzt, so geht der Kontrollfluss durch die Labels + break; //Wenn du kein break einsetzt, so geht der Kontrollfluss + // durch die Labels case 1: printf("Huh, 'a' ist gleich 1!\n"); break; - // Sei vorsichtig - wenn man das `break` vergisst, werden alle Anweisungen - // ausgeführt bis das nächste `break` erscheint. + // Sei vorsichtig - wenn man das `break` vergisst, werden alle + // Anweisungen ausgeführt bis das nächste `break` erscheint. case 3: case 4: printf("Schau mal ... 'a' ist entweder 3 oder 4.\n"); @@ -388,7 +395,7 @@ error: printf("%d\n", (char) x_hex); // => 1 // Typen werden überlaufen (overflow) ohne jegliche Warnung - printf("%d\n", (unsigned char) 257); // => 1 (Max char = 255 wenn char 8 Bit lang ist) + printf("%d\n", (unsigned char) 257); // => 1 (Max char=255 wenn char 8 Bit ist) // Um den maximalen Wert eines `char`, `signed char` oder `unsigned char` // herauszufinden, können die Makros `CHAR_MAX`, `SCHAR_MAX` und `UCHAR_MAX` @@ -413,7 +420,8 @@ error: // von Variablen abrufen und dann mit diesen herumspielen. int x = 0; - printf("%p\n", (void *)&x); // verwende & um die Adresse der Variable zu erhalten + printf("%p\n", (void *)&x); // verwende & um die Adresse der Variable + // zu erhalten // %p formattiert einen Objektpointer des Typen void*) // => Gibt eine Adresse im Speicher aus @@ -506,7 +514,8 @@ error: // Das Dereferenzieren von nicht alloziertem Speicher führt zu einem // Undefinierten Verhalten. - printf("%d\n", *(mein_ptr + 21)); // Gibt irgendwas aus. Das Programm kann auch abstürzen + printf("%d\n", *(mein_ptr + 21)); // Gibt irgendwas aus. + // Das Programm kann auch abstürzen // Nachdem du fertig mit einem Block bist, welcher `malloc` verwendet hat, // muss der Speicher befreit werden. Ansonsten kann dieser Speicherbereich @@ -562,7 +571,7 @@ void str_reverse(char *str_in){ // `strlen()` ist ein Teil der C Standard-Bibliothek. // Merke: Die Länge, welche von `strlen` zurückgegeben wird, ist ohne den // Null-Byte Terminator. - for (ii = 0; i < laenge /2; ii++){ // in C99 kann man `ii` direkt hier deklarieren. + for (ii = 0; i < laenge /2; ii++){ // in C99 kann man `ii` hier deklarieren. tmp = str_in[ii]; str_in[ii] = str_in[laenge - ii - 1]; //#ii'tes Zeichen vom Ende her str_in[laenge - ii- 1] = tmp; @@ -621,8 +630,9 @@ void test_funktion(){ // Das Schlüsselwort `static` macht, dass eine Variable ausserhalb der Kompilier- // einheit nicht zugreifbar ist. (Auf den meisten Systemen ist eine Kompiliereinheit -// eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl global (zur Kompiliereinheit gehörende) -// Variablen, Funktionen und Funktionslokale Variablen angewendet werden. +// eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl global +// (zur Kompiliereinheit gehörende) Variablen, Funktionen und Funktionslokale +// Variablen angewendet werden. // Wenn man `static` bei lokalen Variablen verwendet, so ist diese Variable global // erreichbar und behält dessen Wert über Funktionsaufrufe hinweg, aber sie ist // nur innerhalb der deklarierten Funktion verfügbar. Ausserdem werden statische @@ -665,8 +675,9 @@ void funktion_1(){ // Verwende Dereferenzierung, um Struct-Inhalte zu bearbeiten (*mein_rechteck_ptr).breite = 30; - //Noch besser: Verwende die Kurzschreibweise ->, um die Lesbarkeit zu verbessern. - mein_rechteck_ptr->hoehe = 10; // Das gleiche wie: (*mein_rechteck_ptr).hoehe = 10; + //Noch besser: Verwende die Kurzschreibweise ->, um die Lesbarkeit zu + // verbessern. + mein_rechteck_ptr->hoehe = 10; // Gleich wie: (*mein_rechteck_ptr).hoehe = 10; } // Aus Bequemlichkeitsgründen ist es möglich einem `struct` ein `typedef` hinzuzufügen. @@ -698,11 +709,13 @@ Zum Beispiel: Verwende str_reverse von einem Pointer void str_reverse_through_pointer(char *str_in){ // Definiere eine Funktionspointer-Variable, welche f genannt wird. void (*f)(char *); // Signatur sollte genau der Funktion entsprechen. - f = &str_reverse; // weise die Adresse der wirklichen Funktion zu (zur Laufzeit bestimmt) + f = &str_reverse; // weise die Adresse der wirklichen Funktion zu + // (zur Laufzeit bestimmt) // `f = str_reverse;` würde auch funktionieren, da Funktionen zu Pointern // reduziert werden (ähnlich wie Arrays) (*f)(str_in); // Die Funktion einfach mit dem Pointer aufrufen - // f(str_in); // Dies ist eine weitere gültige Alternative um eine Funktion auzurufen. + // f(str_in); // Dies ist eine weitere gültige Alternative um eine Funktion + // auzurufen. } /* @@ -733,7 +746,8 @@ typedef void (*mein_fnp_type)(char *); '\?'; // Fragezeichen (question mark) '\''; // einfaches Anführungszeichen (single quote) '\"'; // doppeltes Anführungszeichen (double quote) -'\xhh'; // Hexadezimale Zahl (hexadecimal number.) Beispiel: '\xb' = Zeichen für vertikalen Tab +'\xhh'; // Hexadezimale Zahl (hexadecimal number.) Beispiel: + // '\xb' = Zeichen für vertikalen Tab '\0oo'; // Oktalzahl (octal number). Beispiel \013 = Zeichen für vertikalen Tab //Ausgabeformatierung @@ -745,7 +759,8 @@ typedef void (*mein_fnp_type)(char *); "%3.2f"; // Mindestens drei Zeichen vor und drei nach dem Komma. "%7.4s"; // (Kann auch mit Strings gemacht werden) "%c"; // einzelnes Zeichen (char) -"%p"; // Pointer. Merke: man muss den Pointer zu void umwandeln, bevor `printf` funktioniert. +"%p"; // Pointer. Merke: man muss den Pointer zu void umwandeln, + // bevor `printf` funktioniert. "%x"; // Hexadezimal "%o"; // Oktalzahl "%%"; // Gibt % aus @@ -841,8 +856,9 @@ Knoten erstelleVerketteteListe(int *werte, int laenge); Das Beste wird es sein, wenn man sich ein Exemplar des Buches ["The C Programming Language"](https://de.wikipedia.org/wiki/The_C_Programming_Language) besorgt. -Dieses Buch gilt als **das** Buch über die Programmiersprache C und wurde von Dennis Ritchie, -dem Erfinder der Programmiersprache C, und Brian Kernighan geschrieben. +Dieses Buch gilt als **das** Buch über die Programmiersprache C und wurde +von Dennis Ritchie, dem Erfinder der Programmiersprache C, und Brian Kernighan +geschrieben. Sei vorsichtig, da dieses Buch mittlerweile schon etwas älter ist und gewisse Unkorrektheiten (d.h. Ideen, welche nicht mehr als gut empfunden werden.) oder mittlerweile geänderte Praktiken enthält. [Hinweis: Das Buch wurde auf Englisch @@ -858,6 +874,7 @@ es wichtig, dass der Codestil möglichst konsistent ist. Es ist wichtiger, lesba Code zu schreiben als Code, welcher clever und schnell ist. Es lohnt sich ein Blick auf den [Codestil des Linuxkernel](https://www.kernel.org/doc/Documentation/process/coding-style.rst) zu werfen. [Englisch] -Wenn die erwähnte Literatur dein Problem nicht löst, denke daran: "Google ist dein Freund" +Wenn die erwähnte Literatur dein Problem nicht löst, denke daran: +"Google ist dein Freund" [1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) -- cgit v1.2.3 From 4686ba1bbaaf72e94e3cfce3acac4f440dcff93e Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 20:27:41 +0100 Subject: Fixed small typo and added Abstraktionsniveau Typo: maneullen => manuelllen - Added new word because it makes the sentence more clear --- de-de/c-de.html.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 64159c31..bbb46f71 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -8,9 +8,10 @@ lang: de-de Ach, C. Immer noch **die** Sprache für modernes High-Performance Computing. -C ist wahrscheinlich die niedrigste Programmiersprache, welche die meisten -Programmierer je brauchen werden. Die Geschwindigkeit von C ist enorm, allerdings -muss man sich stets der maneullen Speicherverwaltung bewusst sein. +C ist wahrscheinlich die Programmiersprache mit dem niedrigsten Abstraktionsnvieau, +welche die meisten Programmierer je brauchen werden. +Die Geschwindigkeit von C ist enorm, allerdings muss man sich stets der +manuellen Speicherverwaltung bewusst sein. > **Über Compiler Optionen** -- cgit v1.2.3 From 28fe657526b2134457b9f08863ceba24b3bc3ae3 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:02:01 +0100 Subject: Changed german variables to english --- de-de/c-de.html.markdown | 174 +++++++++++++++++++++++------------------------ 1 file changed, 87 insertions(+), 87 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index bbb46f71..dee05954 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -39,12 +39,12 @@ mehrzeilige Kommentare können nicht verschachtelt werden /* Sei Vorsichtig! */ // Konstanten: #define // Konstanten werden laut der Konvention immer in GROSSBUCHSTABEN geschrieben -#define TAGE_IM_JAHR 365 +#define DAYS_IN_YEAR 365 // Konstanten können auch als Aufzählungskonstanten (Enums) definiert werden. // Alle Anweisungen müssen mit einem Semikolon beendet werden. -enum tage {SO=1, MO, DI, MI, DO, FR, SA}; -// MO wird automatisch zu 2, DI zu 3 etc. +enum days {SUN = 1, MON, TUE, WED, THU, FRI, SAT}; +// MON wird automatisch zu 2, TUE zu 3 etc. // Importiere Header-Dateien mit #include #include @@ -58,13 +58,13 @@ enum tage {SO=1, MO, DI, MI, DO, FR, SA}; // Funktionssignaturen werden entweder vorher in einer .h-Datei deklariert oder // am Anfang der .c-Datei. -void funktion_1(); -int funktion_2(void); +void function_1(); +int funkcion_2(void); // Es muss ein Funktionsprototyp deklariert werden vor der `main()` Funktion, // wenn die Funktion nach der `main()` Funktion gebraucht wird. -int addiere_zwei_integer(int x1, int x2); // Funktionsprototyp -// Auch wenn der Ausdrck `int addiere_zwei_integer(int, int)` auch valid wäre, +int add_two_ints(int x1, int x2); // Funktionsprototyp +// Auch wenn der Ausdrck `int add_two_ints(int, int)` auch valid wäre, // ist es empfohlen, dass man die Namen der Argumente hinschreibt für eine // einfachere Analyse. @@ -147,19 +147,19 @@ int main (int argc, char** argv){ // Gibt "sizeof(a++) = 4, wobei a=1 ist" aus (mit einer 32-Bit-Architektur) // Arrays müssen mit einer Grösse initialisiert werden. - char mein_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes - int mein_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes. + char my_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes + int my_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes. // unter der Voraussetzung eines 4-Byte-Worts. // Ein Array kann auf diese Weise mit 0 initialisiert werden. - char mein_array[20] = {0}; + char my_array[20] = {0}; // Hierbei ist der Teil "{0}" der "Array Initialisierer". // Beachte, dass die Länge des Arrays nicht explizit definiert werden muss, // wenn er auf derselben Linie initialisiert wird. // Folgende Deklaration ist gleichwertig: - char mein_array[] = {0}; + char my_array[] = {0}; // Allerdings muss die Länge des Arrays dann zur Laufzeit ausgewertet werden: - size_t mein_array_size = sizeof(mein_array) / sizeof(mein_array[0]); + size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]); // WARNUNG: Wenn dieser Ansatz gewählt wird, muss man sicherstellen, dass die // Grösse des Arrays ermittelt werden *bevor* dieser einer Funktion als // Argument weitergegeben wird (siehe Diskussion weiter unten), weil Arrays @@ -168,11 +168,11 @@ int main (int argc, char** argv){ // Das Indexieren eines Arrays funktioniert wie in anderen Sprache - resp. // in anderen Sprachen funktioniert es gleich wie in C. - mein_array[0]; // => 0 + my_array[0]; // => 0 // Arrays sind veränderbar; es ist nur Arbeitsspeicher! - mein_array[1] = 2; - printf("%d\n", mein_array[1]); // => 2 + my_array[1] = 2; + printf("%d\n", my_array[1]); // => 2 // In C99 (und als optionales Feature in C11) können Arrays mit variabler // Länge deklariert werden. Die Grösse eines solchen Array muss eine Konstante @@ -192,10 +192,10 @@ int main (int argc, char** argv){ // (0x00) beendet werden. In Strings wird das Nullbyte durch das Zeichen \0 // repräsentiert. Wir müssen das Null-Byte nicht angeben in String-Literalen; // der Compiler fügt es am Ende des Array automatisch hinzu. - char ein_string[20] = "Das ist ein String"; - printf("%s\n", ein_string); // %s formattiert einen String + char a_string[20] = "Das ist ein String"; + printf("%s\n", a_string); // %s formattiert einen String - printf("%d\n", ein_string[18]); // => 0 + printf("%d\n", a_string[18]); // => 0 // Hier ist das Byte #19 0 (wie auch Byte #20) // Wenn wir Zeichen zwischen einfachen Anführungszeichen haben, ist es ein @@ -427,10 +427,10 @@ error: // => Gibt eine Adresse im Speicher aus // Pointer starten mit einem * zu Beginn der Deklaration. - int *px, kein_pointer; // px ist ein Pointer zu einem int. + int *px, not_a_pointer; // px ist ein Pointer zu einem int. px = &x; // Speichert die Adresse von x in px printf("%p\n", (void *)px); // => Gibt eine Adresse im Speicher aus - printf("%zu, %zu\n", sizeof(px), sizeof(kein_pointer)); + printf("%zu, %zu\n", sizeof(px), sizeof(not_a_pointer)); // Gibt auf einem typischen 64-Bit-System folgendes aus: "8, 4" // Um den Wert einer Adresse, auf welche ein Pointer zeigt, herauszufinden, @@ -465,15 +465,15 @@ error: // Pointer zugewiesen wird, wird es zu einem Pointer reduziert (implizites Casting) // Ausnahme: Wenn das Array das Argument des Operators `&` ist. int arr[10]; - int (*ptr_zu_arr)[10] = &arr; //`&arr` ist nicht vom Typ `int *`! + int (*ptr_to_arr)[10] = &arr; //`&arr` ist nicht vom Typ `int *`! // Es ist vom Typem "Pointer auf Array" (aus zehn `int`s) // oder wenn das Array ein Stringliteral ist, welches gebraucht wird um ein // `char`-Array zu initialisieren. - char anderer_arr[] = "foobarbazquirk"; + char other_arr[] = "foobarbazquirk"; // oder wenn es das Argument des `sizeof` oder `alignof` Operators ist. - int dritter_array[10]; - int *ptr = dritter_array; // gleich wie: `int *ptr = &arr[0]` - printf("%zu, %zu\n", sizeof(dritter_array), sizeof(ptr)); + int third_array[10]; + int *ptr = third_array; // gleich wie: `int *ptr = &arr[0]` + printf("%zu, %zu\n", sizeof(third_array), sizeof(ptr)); // Gibt wahrscheinlich "40, 4" oder "40, 8" aus // Pointer werden basierend auf dem Typ in- und dekrementiert @@ -487,50 +487,50 @@ error: // wie viele Bytes alloziert werden sollen. (Normalerweise geschieht dies // aus dem Heap - dies kann auf eingebetteten Systemen unterschiedlichen sein. // Der C Standard sagt nichts darüber.) - int *mein_ptr = malloc(sizeof(*mein_ptr) * 20); + int *my_ptr = malloc(sizeof(*my_ptr) * 20); for (xx = 0; xx < 20; xx++){ - *(mein_ptr + xx) = 20 -xx; //mein_ptr[xx] = 20-xx + *(my_ptr + xx) = 20 -xx; //my_ptr[xx] = 20-xx } // initialisiere Speicher zu 20, 19, 18, 17, ... 2, 1 (als `int`) // Sei vorsichtig beim Übergeben von Benutzerdefinierten Werten an `malloc`. // Wenn du sicher sein willst, kannst du die Funktion `calloc` nutzen, welche // (nicht wie `malloc`) auch den Speicher nullt. - int *mein_anderer_ptr = calloc(20, sizeof(int)); + int *my_other_ptr = calloc(20, sizeof(int)); // Merke, dass es in C keinen Standard-Weg gibt, um die Länge eines dynamisch // allozierten Arrays zu bestimmen. Auf Grund dessen sollte eine Variable // erstellt werden, welche sich die Anzahl der Elemente im Array merkt, wenn // die Arrays mehrmals im Programm gebraucht werden. // Weitere Informationen stehen im Abschnitt Funktionen. - size_t groesse = 10; - int *mein_array = calloc(groesse, sizeof(int)); + size_t size = 10; + int *my_array = calloc(size, sizeof(int)); // Füge dem Array ein Element hinzu - groesse++; - mein_array = realloc(mein_array, sizeof(int) *groesse); - if (mein_array == NULL){ + size++; + my_array = realloc(my_array, sizeof(int) *size); + if (my_array == NULL){ // Denke daran, realloc-Fehler zu prüfen return } - mein_array[10] = 5; + my_array[10] = 5; // Das Dereferenzieren von nicht alloziertem Speicher führt zu einem // Undefinierten Verhalten. - printf("%d\n", *(mein_ptr + 21)); // Gibt irgendwas aus. + printf("%d\n", *(my_ptr + 21)); // Gibt irgendwas aus. // Das Programm kann auch abstürzen // Nachdem du fertig mit einem Block bist, welcher `malloc` verwendet hat, // muss der Speicher befreit werden. Ansonsten kann dieser Speicherbereich // niemand nutzen bis dein Programm beendet wird. // Dies wird auch als "Speicherleck" (engl: memory leak) bezeichnet. - free(mein_ptr); + free(my_ptr); // Obwohl Strings normalerweise als Pointer-to-Char (Pointer zum ersten // Zeichen des Arrays) repräsentiert werden, sind Strings Arrays aus `char`s. // Es ist eine gute Praxis, `const char *` zu verwenden, wenn man ein // String-Literal referenziert, da String-Literale nicht modifiziert werden // sollten (z.B. "foo"[0] = 'a' ist ILLEGAL) - const char *mein_str = "Das ist mein eigener String"; - printf("%c\n", *mein_str); // => D + const char *my_str = "Das ist mein eigener String"; + printf("%c\n", *my_str); // => D // Dies ist nicht der Fall, wenn der String ein Array (möglicherweise mit // einem String-Literal initialisiert) ist, welcher im beschreibbaren Speicher @@ -538,7 +538,7 @@ error: char foo[] = "foo"; foo[0] = 'a'; // Dies ist legal, foo enthält jetzt "aoo" - funktion_1(); + function_1(); } // Ende der `main`-Funktion //////////////////////////////////////////////// @@ -548,16 +548,16 @@ error: // Syntax einer Funktionsdeklaration // () -int addiere_zwei_integer(int x1, int x2){ +int add_two_ints(int x1, int x2){ return x1 + x2; // verwendet return, um einen Wert zurückzugeben } /* Funktionen werden auf Grund des Wertes aufgerufen (call-by-value). Wenn eine -Funktion aufgerufen wird, sind die Argumente Kopien der ursprüunglichen Werte +Funktion aufgerufen wird, sind die Argumente Kopien der ursprünglichen Werte (ausgenommen Arrays). Alles, was man innerhalb einer Funktion mit den Werten macht, hat keinen Einfluss auf die Originalwerte als die Funktion aufgerufen -wurde +wurde. Verwende Pointer, um den Originalinhalt zu bearbeiten. @@ -568,14 +568,14 @@ Beispiel: void str_reverse(char *str_in){ char tmp; size_t ii = 0; - size_t laenge = strlen(str_in); + size_t size = strlen(str_in); // `strlen()` ist ein Teil der C Standard-Bibliothek. // Merke: Die Länge, welche von `strlen` zurückgegeben wird, ist ohne den // Null-Byte Terminator. - for (ii = 0; i < laenge /2; ii++){ // in C99 kann man `ii` hier deklarieren. + for (ii = 0; i < size /2; ii++){ // in C99 kann man `ii` hier deklarieren. tmp = str_in[ii]; - str_in[ii] = str_in[laenge - ii - 1]; //#ii'tes Zeichen vom Ende her - str_in[laenge - ii- 1] = tmp; + str_in[ii] = str_in[size - ii - 1]; //#ii'tes Zeichen vom Ende her + str_in[size - ii- 1] = tmp; } } // Merke: Die `string.h`-Headerdatei muss inkludiert werden, bevor `strlen()` @@ -589,16 +589,16 @@ printf("%s\n", c), => "tseT nie tsi saD" // Weil wir lediglich eine Variable zurückgeben können, kann zum Ändern mehrerer // Variablen das Konzept call-by-reference verwendet werden. -void tausche_zwei_zahlen(int *a, int *b){ +void swap_two_numbers(int *a, int *b){ int temp = *a; *a = *b; *b = temp; } -int erste_zahl = 10; -int zweite_zahl = 20; -printf("Erste Zahl: %d\n Zweite Zahl: %d\n", erste_zahl, zweite_zahl); -tausche_zwei_zahlen(&erste_zahl, &zweite_zahl); -printf("Erste Zahl: %d\n Zweite Zahl: %d\n", erste_zahl, zweite_zahl); +int first = 10; +int seconde = 20; +printf("Erste Zahl: %d\n Zweite Zahl: %d\n", first, second); +swap_two_numbers(&first, &second); +printf("Erste Zahl: %d\n Zweite Zahl: %d\n", first, second); // Werte sind vertauscht. /* @@ -610,28 +610,28 @@ Grösse eines dynamischen Arrays herausgefunden werden kann. */ // Die Grösse des Arrays muss unbedingt mitgegeben werden. // Sonst hat die Funktion keine Ahnung wie gross das Array ist. -void ausgabe_int_array(int *arr, size_t size){ +void print_int_arrray(int *arr, size_t size){ int i; for (i = 0; i < size; i++){ printf("arr[%d] ist %d\n", i, arr[i]); } } -int mein_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; -int groesse = 10; -ausgabe_int_array(mein_array, groesse); +int my_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; +int size = 10; +print_int_array(my_array, size); // Wird folgendes ausgeben: "arr[0] ist 1" usw. // Wenn man auf externe Variable (ausserhalb der Funktion) referenziert, sollte // man das Schlüsselwort `extern` verwenden. int i = 0; -void test_funktion(){ +void test_function(){ extern int i; // i braucht nun die externe Variable i } // Das Schlüsselwort `static` macht, dass eine Variable ausserhalb der Kompilier- // einheit nicht zugreifbar ist. (Auf den meisten Systemen ist eine Kompiliereinheit -// eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl global +// eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl bei globalen // (zur Kompiliereinheit gehörende) Variablen, Funktionen und Funktionslokale // Variablen angewendet werden. // Wenn man `static` bei lokalen Variablen verwendet, so ist diese Variable global @@ -648,50 +648,50 @@ void test_funktion(){ //////////////////////////////////////////////// // `typedef`s können verwendet werden, um Typenaliase zu erstellen. -typedef int mein_typ; -mein_typ meine_typ_var = 0; +typedef int my_type; +my_type my_type_var = 0; // Structs sind lediglich Sammlungen von Daten, die Inhalte werden // (in der Reihenfolge wie sie geschrieben wurden) sequentiell alloziert. -struct rechteck{ - int breite; - int hoehe; +struct rectangle{ + int width; + int height; }; // Allgemein ist es nicht so, dass folgender Ausdruck wahr ist. -// sizeof(struct rechteck) == sizeof(int) + sizeof(int) +// sizeof(struct rectangle) == sizeof(int) + sizeof(int) // Dies ist so, weil potentiell ein Padding zwischen den Struktur-Inhalten // möglich ist). (siehe [1, Englisch]) -void funktion_1(){ - struct rechteck mein_rechteck; +void function_1(){ + struct rectangle my_rectangle; // Greife auf Struct-Inhalte mit `.` zu. - mein_rechteck.breite = 10; - mein_rechteck.hoehe = 20; + my_rectangle.width = 10; + my_rectangle.height = 20; // Du kannst Pointer zu Structs deklarieren. - struct rechteck *mein_rechteck_ptr = &mein_rechteck; + struct rectangle *my_rectangle_ptr = &my_rectangle; // Verwende Dereferenzierung, um Struct-Inhalte zu bearbeiten - (*mein_rechteck_ptr).breite = 30; + (*my_rectangle_ptr).width = 30; //Noch besser: Verwende die Kurzschreibweise ->, um die Lesbarkeit zu // verbessern. - mein_rechteck_ptr->hoehe = 10; // Gleich wie: (*mein_rechteck_ptr).hoehe = 10; + my_rectangle_ptr->height = 10; // Gleich wie: (*my_rectangle_ptr).height = 10; } // Aus Bequemlichkeitsgründen ist es möglich einem `struct` ein `typedef` hinzuzufügen. -typedef struct rechteck recht; +typedef struct rectangle rect; -int flaeche(recht r){ - return r.breite * r.hoehe; +int area(rect r){ + return r.width * r.height; } // Wenn du grosse Structs hast, kannst du diese mit dem Pointer kopieren, // damit grosse Kopiervorgänge vermieden werden. -int flaecheptr(const recht *r){ - return r->breite * r->hoehe; +int area_ptr(const rect *r){ + return r->width * r->height; } //////////////////////////////////////////////// @@ -724,10 +724,10 @@ Solange die Signaturen der Funktionen übereinstimmen, kann man sämtliche Funkt demselben Pointer zuweisen. Funktionspointer sind auf Grund der Einfacheit und Leserlichkeit normalerweise wie folgt `typedef`d */ -typedef void (*mein_fnp_type)(char *); +typedef void (*my_fnp_type)(char *); // Danach werden diese genutzt, um die wirkliche Pointervariable zu deklarieren. // .. -// mein_fnp_type f; +// my_fnp_type f; // Spezialzeichen // Im folgenden sin die englischen Begriffe jeweils in Klammern geschrieben, @@ -810,8 +810,8 @@ befindet wie die C-Quelldatei. // Eine sichere Möglichkeit, einen Header mehrere Male zu definieren bietet, das // folgende Statement. Die mehrfache Definition geschieht, wenn Kreisabhängigkeiten // bestehen. -#ifndef BEISPIEL_H /* Wenn BEISPIEL_H noch nicht definiert wurde */ -#define BEISPIEL_H /* definiere das Makro BEISPIEL_H */ +#ifndef EXAMPLE_H /* Wenn EXAMPLE_H noch nicht definiert wurde */ +#define EXAMPLE_H /* definiere das Makro EXAMPLE_H */ // Es könenn weitere Header innerhalb eines Headers eingebunden werden, was dazu // führt, dass diese bereits in anderen Dateien eingebunden wurden. So kann eine @@ -820,7 +820,7 @@ befindet wie die C-Quelldatei. // Wie in den Quelldateien können auch in den Header-Dateien Makros definiert // werden und in anderen Dateien verwendet werden, welche diesen Header einbinden. -#define BEISPIEL_NAME "Dennis Ritchie" +#define EXAMPLE_NAME "Dennis Ritchie" // Funktionsmakros können auch definiert werden. #define ADD(a, b) ((a) + (b)) @@ -833,18 +833,18 @@ befindet wie die C-Quelldatei. // Strukturen und Typendefinitionen können verwendet werden, um die Konsistenz // zwischen unterschiedlichen Dateien beizubehalten. -typedef struct Knoten{ - int wert; - struct Knoten *naechster; -}Knoten; +typedef struct Node{ + int value; + struct Node *next; +}Node; // Dies kann auch mit Aufzählungen gemacht werden. -enum ampel_status {GRUEN, GELB, ROT}; +enum traffic_light_state {GREEN, YELLOW, RED}; // Funktionsprototypen könenn auch in Header-Dateien definiert werden, um die // Funktion in unterschiedlichen Dateien zu verwenden, aber dies wird als schlechte // Praxis angesehen. Definitionen sollten in einer C-Datei erstellt werden. -Knoten erstelleVerketteteListe(int *werte, int laenge); +Node create_linked_list(int *value, int length); // Ausser den oben genannten Elementen, sollten weitere Definitionen in einer // C-Datei gemacht werden. Übermässige Includes und Definitionen sollten auch -- cgit v1.2.3 From 4670481fa27d60d59e837052d33740cfe21b4823 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:04:40 +0100 Subject: Added description for argc and argv --- de-de/c-de.html.markdown | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index dee05954..be74053b 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -76,9 +76,10 @@ int main(void){ // Die Kommandozeilenargumente, welche gebraucht werden, damit dein Programm // läuft, werden als Argumente der `main`-Funktion mitgegeben. -// argc steht für die Anzahl von Argumenten. - Der Programmname ist das erste -// Argument. -// argv ist ein Array von Zeichenarrays, welche die Argumente beinhaltet. +// argc (argument counter) steht für die Anzahl von Argumenten. +// Der Programmname ist das erste Argument. +// argv (argument vector) ist ein Array von Zeichenarrays, welche die +// Argumente beinhaltet. // argv[0] = Name des Programms // argv[1] = erstes Argument usw. int main (int argc, char** argv){ -- cgit v1.2.3 From 603af4b36e57e72f20f02c51f220923df47f8852 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:08:18 +0100 Subject: =?UTF-8?q?Changed=20gross=20to=20gro=C3=9F=20because=20it's=20de-?= =?UTF-8?q?de?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- de-de/c-de.html.markdown | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index be74053b..fee30734 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -98,18 +98,18 @@ int main (int argc, char** argv){ // C99-Konforme Compiler erlauben die Variablendeklaration an dem Punkt, an // welchem die Variable verwendet wird. - // integer sind normalerweise 4 Bytes gross + // integer sind normalerweise 4 Bytes groß int x_int = 0; - // shorts sind normalerweise 2 Bytes gross + // shorts sind normalerweise 2 Bytes groß short x_short = 0; - // chars sind garantiert 1 Byte gross + // chars sind garantiert 1 Byte groß char x_char = 0; char y_char = 'y'; // Charakterliterale werden mit '' gekennzeichnet. - // longs sind oft 4 bis 8 Bytes gross. long long sind garantiert mindestens - // 8 Bytes gross. + // longs sind oft 4 bis 8 Bytes groß. long long sind garantiert mindestens + // 8 Bytes groß. long x_long = 0; long long x_long_long = 0; @@ -610,7 +610,7 @@ Auch hier soll noch einmal erwähnt werden, dass es keinen Standard gibt, wie di Grösse eines dynamischen Arrays herausgefunden werden kann. */ // Die Grösse des Arrays muss unbedingt mitgegeben werden. -// Sonst hat die Funktion keine Ahnung wie gross das Array ist. +// Sonst hat die Funktion keine Ahnung wie groß das Array ist. void print_int_arrray(int *arr, size_t size){ int i; for (i = 0; i < size; i++){ @@ -689,8 +689,8 @@ int area(rect r){ return r.width * r.height; } -// Wenn du grosse Structs hast, kannst du diese mit dem Pointer kopieren, -// damit grosse Kopiervorgänge vermieden werden. +// Wenn du große Structs hast, kannst du diese mit dem Pointer kopieren, +// damit große Kopiervorgänge vermieden werden. int area_ptr(const rect *r){ return r->width * r->height; } -- cgit v1.2.3 From 06c51c70e1f79a54c9d99b48bdb1dd66d64818e6 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:19:06 +0100 Subject: Made whitespace more consistent --- de-de/c-de.html.markdown | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index fee30734..e5beb28f 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -270,7 +270,7 @@ int main (int argc, char** argv){ int e = 5; int f = 10; int z; - z = ( e > f) ? e : f; // => // => 10 "wenn e > f ist, gib e zurück, sonst f." + z = ( e > f ) ? e : f; // => // => 10 "wenn e > f ist, gib e zurück, sonst f." // Inkrementierungs- und Dekrementierungsoperatoren int j = 0; @@ -297,13 +297,13 @@ int main (int argc, char** argv){ //////////////////////////////////////////////// // Kontrollstrukturen //////////////////////////////////////////////// - if (0) { + if (0){ printf("Ich werde nie ausgeführt."); } else if (0){ printf("Ich werde auch nie ausgeführt."); } - else { + else{ printf("Ich gebe etwas aus."); } @@ -317,9 +317,9 @@ int main (int argc, char** argv){ printf("\n"); int kk = 0; - do { + do{ printf("%d, ", kk); - } while(++kk < 10); //++kk inkrementiert kk BEVOR der Wert gebraucht wurde. + }while(++kk < 10); //++kk inkrementiert kk BEVOR der Wert gebraucht wurde. // => gibt folgendes aus: "0, 1, 2, 3, 4, 5, 6, 7, 8, 9, " printf("\n"); -- cgit v1.2.3 From ec76a960a6e9f04b5fe75faa7301d5fa5eed7fdb Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:20:09 +0100 Subject: Removed section about goto --- de-de/c-de.html.markdown | 17 ----------------- 1 file changed, 17 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index e5beb28f..fceec5d4 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -364,23 +364,6 @@ int main (int argc, char** argv){ break; } - // Verwendung von "goto" in C - typedef enum { false, true } bool; - bool desaster = false; - int i, j; - for(i=0; i < 100; ++i){ - for (j=0; j < 100; ++j){ - if ((i + j ) >= 150){ - desaster = true; - } - if (desaster){ - goto error; - } - } - } -error: - printf("Ein Fehler ist aufgetreten bei i = %d & j ? %d\n", i, j); - //////////////////////////////////////////////// // Typenumwandlung //////////////////////////////////////////////// -- cgit v1.2.3 From 8ab886330e8cf8dc19301d16155c849371f35e66 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:25:23 +0100 Subject: reordered section about operators and changed variables to numbers --- de-de/c-de.html.markdown | 165 ++++++++++++++++++++++++----------------------- 1 file changed, 83 insertions(+), 82 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index fceec5d4..e493a303 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -88,6 +88,89 @@ int main (int argc, char** argv){ // \n steht für eine neue Zeile printf("%d\n",0); // => Gibt 0 aus. + //////////////////////////////////////////////// + // Operatoren + //////////////////////////////////////////////// + + // Kurzschreibweise für mehrere Deklarationen + int i1 = 1, i2 = 2; + flaot f1 = 1.0, f2 = 2.0; + + int b,c; + b = c = 0; + + // Arithmetik ist unkompliziert + 1 + 2; // => 3 + 2 - 1; // => 1 + 2 * 1; // => 2 + 1 / 2; // 0 (0.5, aber abgeschnitten, da es int sind.) + + // Man muss mindestens ein Integer zu einen float konvertieren, damit man als + // Resultat eine Gleitkommazahl erhält. + (float)1 / 2; // => 0.5f + 1 / (double)2; // => 0.5 // das gleiche mit dem Typ `double` + 1.0 / 2.0; // => 0.5, plus oder minus Epsilon + // Gleitkommazahlen und deren Berechnungen sind nicht exakt. + + // Es gibt auch die Möglichkeit, Modulo zu rechnen + 11 % 3; // => 2 + + // Vergleichsoperatoren sind vielleicht schon bekannt, aber in C gibt es + // keinen Boolean-Typ. In C verwenden wir `int`. (Oder _Bool oder bool in C99) + // 0 ist falsch, alles andere ist wahr (Die Vergleichsoperatoren ergeben + // immer 1 oder 0. + 3 == 2; // => 0 (falsch) + 3 != 2; // => 1 (wahr) + 3 > 2; // => 1 + 3 < 2; // => 0 + 2 <= 2; // => 1 + 2 >= 2; // => 1 + + // C ist nicht Python - Vergleiche können nicht einfach verkettet werden. + // Warnung: die folgende Zeile wird kompilieren, aber es bedeutet `(0 < a) < 2`. + // Dieser Ausdruck ist immer wahr, weil (0 < a) kann entweder 1 oder 0 sein. + // In diesem Falle ist es 1, weil (0 < 1). + int zwischen_0_und_2 = 0 < a < 2; + // Benutze stattdessen folgende Schreibweise: + int zwischen_0_und_2 = 0 < a && a < 2; + + // Logik funktioniert auch mit ints + !3; // => 0 (logisches Nicht) + !0; // => 1 + 1 && 1; // => 1 (logisches Und) + 0 && 1; // => 0 + 0 || 1; // => 1 (logisches Oder) + 0 || 0; // => 0 + + // Bedingter ternärer Ausdruck ( ? : ) + int e = 5; + int f = 10; + int z; + z = ( e > f ) ? e : f; // => // => 10 "wenn e > f ist, gib e zurück, sonst f." + + // Inkrementierungs- und Dekrementierungsoperatoren + int j = 0; + int s = j++; // gib j zurück und erhöhe danach j. (s = 0, j = 1) + s = ++j; // erhöhe zuerst j und gib dann j zurück (s = 2, j = 2) + // das gleiche gilt für j-- und --j + + // Bitweise Operatoren + ~0x0F; // => 0xFFFFFFF0 (Bitweise Negation, "Einer-Komplement", + // Beispielresultat für 32-Bit int) + 0x0F & 0xF0; // => 0x00 (Bitweises UND) + 0x0F | 0xF0; // => 0xFF (Bitweises ODER) + 0x04 ^ 0x0F; // => 0x0B (Bitweises XOR) + 0x01 << 1; // => 0x02 (Bitweises Linksverschiebung (left shift) (um 1)) + 0x02 >> 1; // => 0x01 (Bitweises Rechtsverschiebung (right shift) (um 1)) + + // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern + // folgende Ausdrücke sind nicht definiert: + // - Verschiebung in das Vorzeichenbit (int a = 1 << 31) + // - Linksshift einer negativen Zahl (int a = -1 << 2) + // - Shift um einen Offset, welcher >= die Breite des linken Ausdrucks ist. + // int a = 1 << 32; // undefiniertes Verhalten, wenn int 32-Bit ist. + + //////////////////////////////////////////////// // Typen //////////////////////////////////////////////// @@ -212,88 +295,6 @@ int main (int argc, char** argv){ // Auf Elemente zugreifen: int array_int = multi_array[0][2]; // => 3 - //////////////////////////////////////////////// - // Operatoren - //////////////////////////////////////////////// - - // Kurzschreibweise für mehrere Deklarationen - int i1 = 1, i2 = 2; - flaot f1 = 1.0, f2 = 2.0; - - int b,c; - b = c = 0; - - // Arithmetik ist unkompliziert - i1 + i2; // => 3 - i2 - i1; // => 1 - i2 * i1; // => 2 - i1 / i2; // 0 (0.5, aber abgeschnitten, da es int sind.) - - // Man muss mindestens ein Integer zu einen float konvertieren, damit man als - // Resultat eine Gleitkommazahl erhält. - (float)i1 / i2; // => 0.5f - i1 / (double)i2; // => 0.5 // das gleiche mit dem Typ `double` - f1 / f2; // => 0.5, plus oder minus Epsilon - // Gleitkommazahlen und deren Berechnungen sind nicht exakt. - - // Es gibt auch die Möglichkeit, Modulo zu rechnen - 11 % 3; // => 2 - - // Vergleichsoperatoren sind vielleicht schon bekannt, aber in C gibt es - // keinen Boolean-Typ. In C verwenden wir `int`. (Oder _Bool oder bool in C99) - // 0 ist falsch, alles andere ist wahr (Die Vergleichsoperatoren ergeben - // immer 1 oder 0. - 3 == 2; // => 0 (falsch) - 3 != 2; // => 1 (wahr) - 3 > 2; // => 1 - 3 < 2; // => 0 - 2 <= 2; // => 1 - 2 >= 2; // => 1 - - // C ist nicht Python - Vergleiche können nicht einfach verkettet werden. - // Warnung: die folgende Zeile wird kompilieren, aber es bedeutet `(0 < a) < 2`. - // Dieser Ausdruck ist immer wahr, weil (0 < a) kann entweder 1 oder 0 sein. - // In diesem Falle ist es 1, weil (0 < 1). - int zwischen_0_und_2 = 0 < a < 2; - // Benutze stattdessen folgende Schreibweise: - int zwischen_0_und_2 = 0 < a && a < 2; - - // Logik funktioniert auch mit ints - !3; // => 0 (logisches Nicht) - !0; // => 1 - 1 && 1; // => 1 (logisches Und) - 0 && 1; // => 0 - 0 || 1; // => 1 (logisches Oder) - 0 || 0; // => 0 - - // Bedingter ternärer Ausdruck ( ? : ) - int e = 5; - int f = 10; - int z; - z = ( e > f ) ? e : f; // => // => 10 "wenn e > f ist, gib e zurück, sonst f." - - // Inkrementierungs- und Dekrementierungsoperatoren - int j = 0; - int s = j++; // gib j zurück und erhöhe danach j. (s = 0, j = 1) - s = ++j; // erhöhe zuerst j und gib dann j zurück (s = 2, j = 2) - // das gleiche gilt für j-- und --j - - // Bitweise Operatoren - ~0x0F; // => 0xFFFFFFF0 (Bitweise Negation, "Einer-Komplement", - // Beispielresultat für 32-Bit int) - 0x0F & 0xF0; // => 0x00 (Bitweises UND) - 0x0F | 0xF0; // => 0xFF (Bitweises ODER) - 0x04 ^ 0x0F; // => 0x0B (Bitweises XOR) - 0x01 << 1; // => 0x02 (Bitweises Linksverschiebung (left shift) (um 1)) - 0x02 >> 1; // => 0x01 (Bitweises Rechtsverschiebung (right shift) (um 1)) - - // Sei vorsichtig beim Shift mit vorzeichenbehafteten Integern - // folgende Ausdrücke sind nicht definiert: - // - Verschiebung in das Vorzeichenbit (int a = 1 << 31) - // - Linksshift einer negativen Zahl (int a = -1 << 2) - // - Shift um einen Offset, welcher >= die Breite des linken Ausdrucks ist. - // int a = 1 << 32; // undefiniertes Verhalten, wenn int 32-Bit ist. - //////////////////////////////////////////////// // Kontrollstrukturen //////////////////////////////////////////////// -- cgit v1.2.3 From ca042dcb65e65af210c5ee26de5237478d911d23 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 21:44:15 +0100 Subject: =?UTF-8?q?Changed=20all=20occurences=20of=20ss=20to=20=C3=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit I have changed all occurences of 'ss' to 'ß' according to duden.de --- de-de/c-de.html.markdown | 48 ++++++++++++++++++++++++------------------------ 1 file changed, 24 insertions(+), 24 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index e493a303..ffa64bcc 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -16,7 +16,7 @@ manuellen Speicherverwaltung bewusst sein. > **Über Compiler Optionen** > -> Standardmässig sind `gcc` und `clang` ziemlich ruhig bezüglich Warnungen und +> Standardmäßig sind `gcc` und `clang` ziemlich ruhig bezüglich Warnungen und > Fehlern, obwohl dies sehr nützliche Informationen sein können. Es wird > empfohlen, strengere Compiler Optionen zu verwenden. Hier sind einige empfohlene > Standards: @@ -203,7 +203,7 @@ int main (int argc, char** argv){ double x_double = 0.0; // echte Zahlen ohne Suffix sind vom Typ double // integer-Typen können vorzeichenlos (unsigned) sein - // (grösser oder kleiner als 0) + // (größer oder kleiner als 0) unsigned short ux_short; unsigned int ux_int; unsigned long long ux_long_long; @@ -213,24 +213,24 @@ int main (int argc, char** argv){ '0'; // => 48 im ASCII-Zeichensatz 'A'; // => 65 im ASCII-Zeichensatz - // sizeof(T) gibt die Grösse einer Variablen des Typen T in Bytes zurück. - // sizeof(obj) ergibt die Grösse des Ausdrucks (Variable, Literal usw.) + // sizeof(T) gibt die Größe einer Variablen des Typen T in Bytes zurück. + // sizeof(obj) ergibt die Größe des Ausdrucks (Variable, Literal usw.) printf("%zu\n", sizeof(int)); // => 4 (auf den Rechnern mit einem 4-Byte-Wort) // Wenn das Argument des `sizeof`-Operator ein Ausdruck ist, dann wird das - // Argument nicht ausgewertet (ausser Arrays mit variabler Länge) + // Argument nicht ausgewertet (außer Arrays mit variabler Länge) // Der Wert, der in diesem Fall zurückgegeben wird, ist eine Konstante zur // Kompillierzeit. int a = 1; //size_t ist ein vorzeichenloser Integer Typ mit mindestens 2 Byte um die - // Grösse eines Objekts zu repräsentieren. + // Größe eines Objekts zu repräsentieren. size_t size = sizeof(a++); // a++ wird nicht ausgewertet printf("sizeof(a++) = %zu, wobei a=%d ist\n", size, a); // Gibt "sizeof(a++) = 4, wobei a=1 ist" aus (mit einer 32-Bit-Architektur) - // Arrays müssen mit einer Grösse initialisiert werden. + // Arrays müssen mit einer Größe initialisiert werden. char my_char_array[20]; // Dieses Array beinhaltet 1 * 20 = 20 Bytes int my_int_array[20]; // Dieses Array beinhaltet 4 * 20 = 80 Bytes. // unter der Voraussetzung eines 4-Byte-Worts. @@ -245,7 +245,7 @@ int main (int argc, char** argv){ // Allerdings muss die Länge des Arrays dann zur Laufzeit ausgewertet werden: size_t my_array_size = sizeof(my_array) / sizeof(my_array[0]); // WARNUNG: Wenn dieser Ansatz gewählt wird, muss man sicherstellen, dass die - // Grösse des Arrays ermittelt werden *bevor* dieser einer Funktion als + // Größe des Arrays ermittelt werden *bevor* dieser einer Funktion als // Argument weitergegeben wird (siehe Diskussion weiter unten), weil Arrays // einer Funktion nur als Zeiger übergeben werden. => Das obere Statement // würde innerhalb einer Funktion ein falsches Resultat liefern. @@ -259,17 +259,17 @@ int main (int argc, char** argv){ printf("%d\n", my_array[1]); // => 2 // In C99 (und als optionales Feature in C11) können Arrays mit variabler - // Länge deklariert werden. Die Grösse eines solchen Array muss eine Konstante + // Länge deklariert werden. Die Größe eines solchen Array muss eine Konstante // zur Kompilierzeit sein. - printf("Geben Sie die Arraygrösse an: "); //Frag den Benutzer nach - // der Arraygrösse + printf("Geben Sie die Arraygröße an: "); //Frag den Benutzer nach + // der Arraygröße int array_size; fcsanf(stdin, "%d", &array_size); int var_length_array[array_size]; // deklariere Array mit variabler Länge printf("sizeof array =%zu\n", sizeof var_length_array); // Zum Beispiel: - // > Geben Sie die Arraygrösse an: 10 + // > Geben Sie die Arraygröße an: 10 // > sizeof array = 40 // Strings sind lediglich Arrays von `chars`, welche mit einem Null-Byte @@ -398,7 +398,7 @@ int main (int argc, char** argv){ // In diesem Tutorial wird das deutsche Wort Zeiger nicht verwendet, da es // bei einer weiteren Recherche einfacher ist, wenn man von Pointern ausgeht. - // Ausserdem ist der Begriff Pointer auch im deutschen Sprachgebrauch zu finden. + // Außerdem ist der Begriff Pointer auch im deutschen Sprachgebrauch zu finden. // Ein Pointer ist eine Variable, welche deklariert wurde, um eine Speicher- // adresse zu speichern. Die Deklaration eines Pointers wird auch zeigen, @@ -433,7 +433,7 @@ int main (int argc, char** argv){ // Arrays sind eine gute Möglichekit, einen zusammenhängenden Block von // Speicher zu allozieren. - int x_array[20]; // deklariert einen Array der Grösse 20 (Grösse kann + int x_array[20]; // deklariert einen Array der Größe 20 (Größe kann // nicht geändert werden.) int xx; for (xx =0; xx < 20; xx++){ @@ -591,9 +591,9 @@ Wenn man Arrays betrachtet, so werden diese immer als Pointer übergeben. Auch wenn die Arrays statisch alloziert werden (wie zum Beispiel `arr[10]`), werden diese als Pointer zum ersten Element des Arrays übergeben. Auch hier soll noch einmal erwähnt werden, dass es keinen Standard gibt, wie die -Grösse eines dynamischen Arrays herausgefunden werden kann. +Größe eines dynamischen Arrays herausgefunden werden kann. */ -// Die Grösse des Arrays muss unbedingt mitgegeben werden. +// Die Größe des Arrays muss unbedingt mitgegeben werden. // Sonst hat die Funktion keine Ahnung wie groß das Array ist. void print_int_arrray(int *arr, size_t size){ int i; @@ -607,25 +607,25 @@ int size = 10; print_int_array(my_array, size); // Wird folgendes ausgeben: "arr[0] ist 1" usw. -// Wenn man auf externe Variable (ausserhalb der Funktion) referenziert, sollte +// Wenn man auf externe Variable (außerhalb der Funktion) referenziert, sollte // man das Schlüsselwort `extern` verwenden. int i = 0; void test_function(){ extern int i; // i braucht nun die externe Variable i } -// Das Schlüsselwort `static` macht, dass eine Variable ausserhalb der Kompilier- +// Das Schlüsselwort `static` macht, dass eine Variable außerhalb der Kompilier- // einheit nicht zugreifbar ist. (Auf den meisten Systemen ist eine Kompiliereinheit // eine `.c`-Datei.) Das Schlüsselwort `static` kann sowohl bei globalen // (zur Kompiliereinheit gehörende) Variablen, Funktionen und Funktionslokale // Variablen angewendet werden. // Wenn man `static` bei lokalen Variablen verwendet, so ist diese Variable global // erreichbar und behält dessen Wert über Funktionsaufrufe hinweg, aber sie ist -// nur innerhalb der deklarierten Funktion verfügbar. Ausserdem werden statische +// nur innerhalb der deklarierten Funktion verfügbar. Außerdem werden statische // Variablen mit 0 initialisiert, wenn sie nicht mit einem anderen Startwert // initialisiert werden. // Es ist auch möglich, Funktionen als statisch zu deklarieren, damit diese -// `private` sind. Privat heisst, dass sie nur in diesem Kontekt sichtbar sind. +// `private` sind. Privat heißt, dass sie nur in diesem Kontekt sichtbar sind. //////////////////////////////////////////////// @@ -782,7 +782,7 @@ typedef void (*my_fnp_type)(char *); /* Header-Dateien sind ein wichtiger Teil von C, da sie eine Verbindung zwischen -unterschiedlichen C-Quelldateien herstellen. Ausserdem vereinfachen Header-Dateien +unterschiedlichen C-Quelldateien herstellen. Außerdem vereinfachen Header-Dateien den Code und Definitionen, da diese in separaten Dateien geschrieben werden können. Header-Dateien sind von der Syntax her ähnlich zu C-Quelldateien, allerdings haben @@ -831,8 +831,8 @@ enum traffic_light_state {GREEN, YELLOW, RED}; // Praxis angesehen. Definitionen sollten in einer C-Datei erstellt werden. Node create_linked_list(int *value, int length); -// Ausser den oben genannten Elementen, sollten weitere Definitionen in einer -// C-Datei gemacht werden. Übermässige Includes und Definitionen sollten auch +// Außer den oben genannten Elementen, sollten weitere Definitionen in einer +// C-Datei gemacht werden. Übermäßige Includes und Definitionen sollten auch // nicht einer Header-Datei gemacht werden. Stattdessen wird es empfohlen, diese // in eine separate Header-Datei oder in eine C-Quelldatei zu schreiben. @@ -855,7 +855,7 @@ Eine weitere gute Resource ist [Learn C The Hard Way](http://learncodethehardway Solltest du Fragen zu C haben, so lies die FAQ [compl.lang.c Frequently Asked Questions](http://c-faq.com).[Englisch] -Ausserdem ist es wichtig, eine saubere Einrückung zu verwenden. Des weiteren ist +Außerdem ist es wichtig, eine saubere Einrückung zu verwenden. Des weiteren ist es wichtig, dass der Codestil möglichst konsistent ist. Es ist wichtiger, lesbaren Code zu schreiben als Code, welcher clever und schnell ist. Es lohnt sich ein Blick auf den [Codestil des Linuxkernel](https://www.kernel.org/doc/Documentation/process/coding-style.rst) zu werfen. [Englisch] -- cgit v1.2.3 From e48d05c98d3415a5c5edd7d8c3931cd5e68976f5 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 23:08:38 +0100 Subject: added link to useful compiler options --- de-de/c-de.html.markdown | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index ffa64bcc..05b26dd2 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -22,6 +22,11 @@ manuellen Speicherverwaltung bewusst sein. > Standards: > `-Wall -Wextra -Werror -O2 -std=c99 -pedantic` > +> Da gewisse Optionen (inbesondere der C-Standard) sehr stark vom Projekt +> abhängen, lohnt es sich, wenn die unterschiedlichen Optionen genauer +> angeschaut werden. Eine Übersicht über die Compiler-Optionen findet man unter +> [diesem](https://stackoverflow.com/questions/3375697/useful-gcc-flags-for-c) Stackoverflow-Beitrag. +> > Für weitere Informationen, was diese und weitere Optionen genau machen, > sollte die Man-Page des C-Compilers aufgerufen werden (z.B. `man 1 gcc`). > Alternativ kann auch online nach den unterschiedlichen Optionen gesucht werden. -- cgit v1.2.3 From e24e38a1b984307bb5e68d231060f7024d908618 Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 23:08:55 +0100 Subject: Fixed small typo Resource => Ressource --- de-de/c-de.html.markdown | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 05b26dd2..1976a6e8 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -855,7 +855,7 @@ Unkorrektheiten (d.h. Ideen, welche nicht mehr als gut empfunden werden.) oder mittlerweile geänderte Praktiken enthält. [Hinweis: Das Buch wurde auf Englisch geschrieben, es gibt aber auch eine Übersetzung davon] -Eine weitere gute Resource ist [Learn C The Hard Way](http://learncodethehardway.org/c/). +Eine weitere gute Ressource ist [Learn C The Hard Way](http://learncodethehardway.org/c/). [Englisch] Solltest du Fragen zu C haben, so lies die FAQ [compl.lang.c Frequently Asked Questions](http://c-faq.com).[Englisch] -- cgit v1.2.3 From fbb24b487e0f847a54b6317dea22dfd6b850c12e Mon Sep 17 00:00:00 2001 From: caminsha Date: Sun, 2 Feb 2020 23:09:36 +0100 Subject: Removed unnecessary lines about google --- de-de/c-de.html.markdown | 3 --- 1 file changed, 3 deletions(-) (limited to 'de-de') diff --git a/de-de/c-de.html.markdown b/de-de/c-de.html.markdown index 1976a6e8..3dcb5ab9 100644 --- a/de-de/c-de.html.markdown +++ b/de-de/c-de.html.markdown @@ -865,7 +865,4 @@ es wichtig, dass der Codestil möglichst konsistent ist. Es ist wichtiger, lesba Code zu schreiben als Code, welcher clever und schnell ist. Es lohnt sich ein Blick auf den [Codestil des Linuxkernel](https://www.kernel.org/doc/Documentation/process/coding-style.rst) zu werfen. [Englisch] -Wenn die erwähnte Literatur dein Problem nicht löst, denke daran: -"Google ist dein Freund" - [1] [Why isn't sizeof for a struct equal to the sum of sizeof of each member?](http://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member) -- cgit v1.2.3