02 - Grundlagen

Alexander Krause

IRB

🚀 by Decker

Das erste Programm - Hello World

#include <stdio.h> // Verwende den Baukasten stdio (fĂĽr printf)

int main() { // Einstiegspunkt jedes C-Programms
    printf("Hello World");

    printf("");

    printf("");
    return 0;
}
cpp
  • main() ist der Einstiegspunkt jedes C-Programms
  • Erstmal nur printf und main() → Rest folgt!

Aber: Wie werden Informationen im Computer abgebildet?

Hier: Der Text (String) "Hello World"

Darstellung von Informationen

  • Was wollen wir speichern?
    • Name
    • Matrikelnummer
    • Temperatur
    • …
  • Bestimmte Formen dieser Daten haben gemeinsame, typische Eigenschaften

Name:

Matrikelnummer:

Temperatur:

Anordnung von Buchstaben (Zeichenkette)

nicht-negative ganze Zahl

nicht-negative reelle Zahl

Dies alles nennt man Datentypen

Binärformat

  • Computer speichert Informationen im Binärformat:

    1 oder 0 (= genannt Bit)

  • Kombination von mehreren Ziffern bildet Binärzahl: 1001

  • Jede Stelle der Binärzahl steht fĂĽr eine Zweierpotenz:

    \(2^0 = 1, 2^1 = 2, 2^2 = 4, 2^3 = 8, ...\)

  • Summe der einzelnen Werte ergibt Zahl im Dezimalsystem

  • Beispiel: 79 = 64 + 8 + 4 + 2 + 1 = 26 + 23 + 22 + 21 + 20
27 = 128 26 = 64 25 = 32 24 = 16 23 = 8 22 = 4 21 = 2 20 = 1
0 1 0 0 1 1 1 1

8 Bits ergeben dabei 1 Byte →
28 = 256 mögliche Werte pro Byte

Binärformat

  • Zahlen \(> 255\) werden genauso dargestellt, bestehen aber aus mehreren Bytes
  • Beispiel: 591 = 512 + 79
512 256 128 64 32 16 8 4 2 1
1 0 0 1 0 0 1 1 1 1
  • 591 =0000 0010 x 256 +0100 1111

Binärformat

  • Byte mit dem höchsten/niedrigsten Wert heiĂźt Most/Least Significant Byte (MSB bzw. LSB)
  • Reihenfolge der Bytes heiĂźt Byte Order: Entweder von MSB zu LSB (Big Endian) oder von LSB zu MSB (Little Endian)
  • Analog fĂĽr Bits: Most/Least Significant Bit (MSBit bzw. LSBit)
128 64 32 16 8 4 2 1
0 (MSBit) 1 0 0 1 1 1 1 (LSBit)

Binärformat

  • 🚨 Achtung: Zahlen können gleich aussehen, aber in unterschiedlichen Zahlensystemen stehen
  • Beispiel: 110 (Binär) ≠ 110 (Dezimal)
  • Unterscheidung bei gemischten Zahlensystemen ĂĽber Index: 110B = 6D
  • Gibt mehrere gängige Zahlensysteme:
    • Dezimal → D oder dec
    • Binär → B oder bin
    • Hexadezimal → H oder hex
    • Oktal → O oder oct

Hexadezimale Darstellung

  • Dezimal: Zahlen von 0-9
  • Hexadezimal: Erweiterung der dezimalen Darstellung auf 0-15
  • Beispiele:
    • 32D = 20H = 0010 0000B
    • 255D = FFH = 1111 1111B
    • 1000D = 3E8H = 11 1110 1000B
Dez. Hex. Dez. Hex.
0 0 8 8
1 1 9 9
2 2 10 A
3 3 11 B
4 4 12 C
5 5 13 D
6 6 14 E
7 7 15 F

Vorteile der hexadezimalen Darstellung

Vorteile der hexadezimalen Darstellung:

  • 16 Werte → \(2^4\) → 4 Bit zur Darstellung → 2 x 4 Bit → 1 Byte

    → Darstellung von 1 Byte mit nur zwei Zeichen

  • Deutlich leserlicher als eine Binärzahl!

  • Hexadezimal ist vielfaches von Binärsystem → einfache Umwandlung

    • Besonders bei groĂźen Zahlen sehr praktisch, weil Binärsystem unhandlich wird
    • Beispiel: FF FFH besser als 1111 1111 1111 1111B

MaĂźeinheiten fĂĽr Bytes

  • Bei Bytes gibt es oft Verwirrung bei den Präfixen fĂĽr Einheiten: Kilo, Mega, …

  • Hersteller verwenden Dezimalsystem!

    → 1000 Bytes = 1 Kilobyte

  • Programmierer:innen denken hingegen im Binärsystem

    → 210 = 1024 Bytes = 1 Kilobyte

  • Daher Unterscheidung ĂĽber zusätzliches Präfix

    → Beispiel: Anstatt Kilobyte, nun Kibibyte

  • Faustformel: Erweiterung um 10 Bits ist eine Erhöhung um den Faktor ~1000 (gut fĂĽr ungefähre Größenabschätzung) 106

Einheitenpräfixe für Bytes

Bytes (dezimal) Bezeichnung Bytes (binär) Bezeichnung
103 Kilobyte (KB) 210 Kibibyte (KiB)
106 Megabyte (MB) 220 Mebibyte (MiB)
109 Gigabyte (GB) 230 Gibibyte (GiB)
1012 Terabyte (TB) 240 Tebibyte (TiB)
1015 Petabyte (PB) 250 Pebibyte (PiB)
1018 Exabyte (EB) 260 Exbibyte (EiB)

Das erste Programm (Fortsetzung)

#include <stdio.h>

int main() {
    int i = 3; // Befehl 1: Erzeuge Variable mit Ganzzahl (Integer)
    i = i + 5; // Befehl 2: Addiere 5, weise die Summe i zu
    printf("%d", i); // Befehl 3: Nun gib i aus
    return 0;
}
cpp
  • Diese Art der Programmierung heiĂźt imperativ
  • Jeder Befehl in C endet mit dem Semikolon (;)

Kommentare

  • Kommentare sind wertvoll, um komplexeren Code zu erklären oder auf TĂĽcken hinzuweisen
  • Zwei Arten von Kommentaren: Einzeilig und Blockkommentar
#include <stdio.h>

int main() {
    int i = 3; // Einzeilen-Kommentar, beginnt immer mit //
    // und endet mit der Zeile
    /* Blockkommentar beginnt immer mit /* und endet mit */
    /*
        Beliebiger Text dazwischen möglich
    */
    return 0;
}

Anlegen von Variablen

Anlegen der Variable num: int num = 3;

  • int: Typ der Variable
  • num: Bezeichner, fĂĽhrt den Namen num ein
  • 3: Initialisierung, initialisiert num mit 3
  • Was passiert hier?
    1. Ăśbersetzer reserviert Speicher:
    2. Wertevorrat wird festgelegt (int)
    3. Name num ist von nun an eine Variable
  • num kann ab Deklaration „abwärts” weiterverwendet werden

Elementare Datentypen

  • Einfache Datentypen sind elementar → nicht auf andere Typen zurĂĽckfĂĽhrbar

    (pod = plain old datatypes)

  • Beispiele:

    • (nicht-negative) ganze Zahlen (Integers) → int i = 3;
    • Zahlen mit Nachkommastellen (Floats). → float f = 3.14;
    • Zeichen (Characters) → char c = 'c';
  • Achtung: verzeichenlos ↔︎ verzeichenbehaftet

    • Zusatz signed bzw. unsigned beim Datentyp: unsigned int num = 3;
    • Bei signed wird ein Bit geopfert fĂĽr das Vorzeichen

Nicht-negative Ganzzahlen

Bits Bytes Werte Name in C/C++ Min. Breite Typ. Breite Feste Breite
8 1 0…255 unsigned char 8 8 uint8_t
16 2 0…65 535 unsigned short 16 16 uint16_t
32 4 0…4 294 967 295 unsigned int 16 32 uint32_t
64 8 0…4 294 967 295 unsigned long int 32 32 uint32_t
64 8 0…18 446 744 073 709 551 615 unsigned long long int 64 64 uint64_t

🚨 Breite in Bits ist abhängig von der Hardwarearchitektur! 🚨

Ganzzahlen mit Vorzeichen

Bits Bytes Werte Name in C/C++ Min. Breite Typ. Breite Feste Breite
8 1 -128…127 char 8 8 int8_t
16 2 -32768…32767 short 16 16 int16_t
32 4 -2 147 483 648…2 147 483 647 int 16 32 int32_t
64 8 -2 147 483 648…2 147 483 647 long int 32 32 int32_t
64 8 -263 … 263-1 long long int 64 64 int64_t

🚨 Breite in Bits ist abhängig von der Hardwarearchitektur! 🚨

Zusammengesetzte Datentypen

  • Entstehen baukastenartig durch Zusammensetzen von elementaren Datentypen
  • Beispiele:
    • Koordinate: Ein Paar aus zwei ganzen Zahlen
    • Zeichenkette: besteht aus mehreren einzelnen Characters
    • Adresse: besteht aus PLZ, Ort und StraĂźe, Hausnummer
struct Koordinate {
    int x;
    int y;
};

Vorschriften fĂĽr Bezeichner

  • Es dĂĽrfen nur Buchstaben a-z sowie A-Z, Ziffern 0-9 und der Unterstrich _ vorkommen
  • Kein Leerzeichen erlaubt
  • Das erste Zeichen muss ein Buchstabe oder ein Unterstrich sein
  • Prinzipiell keine (in der Realität erreichbare) Längenbeschränkung
  • SchlĂĽsselwörter dĂĽrfen nicht verwendet werden
  • Trennung zwischen Datentypen und Variablen ĂĽber Whitespace-Zeichen (Leerzeichen, Tabulator, New Line)

Beispiele fĂĽr Bezeichner

Zulässig Nicht zulässig
Winkel nichtOk!
EinkomSteuer 7CR
einkom_steuer x-2
wichtigeVariable wichtige Variable
_OK int
x3 float
__x3_und_x4_
_99

Einschub: Schlüsselwörter in C

Schlüsselwörter sind reservierte Wörter der jeweiligen Programmiersprache!

auto break case char const continue
default do double else enum extern
float for goto if inline int
long register restrict return short signed
sizeof static struct switch typedef union
unsigned void volatile while true (C23) false (C23)

Einschub: Schlüsselwörter in C++

Zusätzliche Schlüsselwörter in C++ (auszugsweise, siehe cppreference.com)

and and_eq asm bitand bitor catch
class compl constexpr const_cast delete dynamic_cast
explicit for friend false namespace new
noexcept not not_eq nullptr operator or
or_eq private protected public reinterpret_cast static_cast
template this throw true try typename
using virtual xor xor_eq

Konventionen fĂĽr Bezeichner

  • Es gibt zahlreiche Möglichkeiten fĂĽr die Benennung

  • Am weitesten verbreitete Konventionen

    • Snake Case
    • Camel Case
  • Snake Case

    • Variablen werden klein geschrieben
    • Leerzeichen durch _ ersetzt
    • Bsp.: int count_variable_1 = 0;
  • Konstante Variablen, deren Wert sich nicht verändert, werden nur groĂź geschrieben

    (Bsp.: const int RESISTOR_VAL_470 = 470;)

Konventionen fĂĽr Bezeichner

  • Camel Case
    • Bezeichner beginnt mit Kleinbuchstaben
    • Wörter werden aneinander gehängt
    • ein neues Wort mit GroĂźbuchstaben signalisiert
  • Bsp.: int countVariable2 = 0;
  • Faustformeln
    • In C ist Snake Case weiter verbreitet → deswegen wird diese Notation auch hier verwendet
    • Interne oder temporäre Variablen beginnen meist mit _

Arithmetische Operationen

Operation Operator
Addition +
Subtraktion -
Multiplikation *
Division /
Division mit Rest (Modulo) %

Modulo-Operator

  • Modulo-Operation: Division zweier Zahlen, Ergebnis entspricht dem Rest

  • Beispiel: Ăśberlauf abfangen bei einer Uhr

#include <stdio.h>

int main() {
    int stunde = 22;
    int minute = 59;
    minute = (minute + 1) % 60;
    stunde = (stunde + 1) % 24;
    printf("%d:%d", stunde, minute);
    return 0;
}
cpp

Beispiel zu arithmetischen Operationen

#include <stdio.h>

int main() {
    int i = 3;
    i = i + 13;
    i = i * 5;
    i = i / 8;
    i = i % 3;
    printf("%d", i);
    return 0;
}
  • 0
  • 3.333
  • 1
  • 3

Beispiel zu arithmetischen Operationen

#include <stdio.h>

int main() {
    int i = 3;
    i = i + 13; // 16
    i = i * 5; // 80
    i = i / 8; // 10
    i = i % 3; // 1 => 9/3 und Rest 1
    printf("%d", i);
    return 0;
}
cpp

Arithmetische Operationen Reloaded

Arithmetische Operation und Zuweisung in einem

Operation Operator
Addition +=
Subtraktion -=
Multiplikation *=
Division /=
Division mit Rest (Modulo) %=

Beispiel arithmetische Operationen mit Zuweisung

#include <stdio.h>

int main() {
    int i = 3;
    i += 13;
    i *= 5;
    i /= 8;
    i %= 3;
    printf("%d", i);
    return 0;
}
c

Wissensspeicher 1

  • Ihr kennt bereits das erste C-Programm 🥳
  • Ihr wisst, wie
    • Ihr Variablen anlegt,
    • man Zahlen abspeichert und
    • mit Variablen rechnet.

Increment/Decrement

  • Die häufigste Operation auf Zahlen: Addition / Substraktion von 1
  • Es gibt dafĂĽr zwei eigene Operatoren
    • ++ (Increment)
    • -- (Decrement)
  • Operatoren können vor einer Variable stehen → Pre-Increment, ++i
  • …aber auch einer Variable folgen → Post-Increment, i++
  • Analog dazu Dekrement: --i, i--
  • Unterschied
    • Pre-Increment: Erst erhöhen, dann die Variable verwenden
    • Post-Increment: Erst die Variable verwenden, dann erhöhen
  • Empfehlung: Benutzt Pre-Increment, wenn möglich

Beispiel zu Pre-Post-Increment

#include <stdio.h>

int main() {
    int i = 0;
    ++i;
    ++i;
    ++i;
    --i;
    printf("%d", i);
    return 0;
}
cpp

Konkatenation von Operationen

#include <stdio.h>

int main() {
    int i = 3;
    i = ((i + 13) * 5) / 8) % 3;
    printf("%d", i);
    return 0;
}
cpp

( Hier sind Klammern wichtig, die Operatoren haben wie in der Mathematik auch eine unterschiedliche Wichtigkeit)

Operator-Präzedenz

  • Spielt eine Rolle, wenn keine Klammerung vorhanden ist

  • Beschreibt die Bindung an Operanden

  • Operatoren sind in Gruppen eingeteilt

    • Von 1-17
    • 1 ist die höchste Präzedenz
  • Je höher die Präzedenz, desto stärker binden sie an die Werte / Variablen

    (=„je größer die Präzedenz, desto stärker die Anziehungskraft”)

Operator-Präzedenz

  • Vollständige Tabelle aller Operatoren findet sich hier unter cppreference.com

  • Muss nicht auswendig gelernt werden!

  • Die meisten Präzendenzen ergeben sich intuitiv,

    aber am Anfang muss man ggf. häufiger nachschauen

  • Tipp: Im Zweifelsfall Klammern setzen (erhöht auch meistens die Lesbarkeit)

Beispiel Operator-Präzedenz

#include <stdio.h>

int main() {
    int i = 1;
    i = i++;
    printf("%d", i);
    return 0;
}
cpp
  • 1
  • 3
  • 2
  • Nicht definiert

Häufige Fehler mit Integers

Angenommen eine Variable hat den höchsten darstellbaren Wert

und wird dann erhöht: uint16_t i = 65535; ++i;

Was wird passieren?

  • 0
  • Nimmt 17 Bits ein (65536D = 1 0000 0000 0000 0000)
  • -65535
  • Wird nicht ĂĽbersetzt

Integers Overflow/Underflow

  • Ăśberlauf (Overflow)
    • Größtmögliche Zahl und dann um 1 erhöhen
    • Kleinste Zahl tritt auf
  • Unterlauf (Underflow)
    • Kleinmögliche Zahl und dann um 1 erniedrigen
    • Größte Zahl tritt auf
  • Besonders unschön:
    • Ist nur fĂĽr vorzeichlenlose definiert
    • Bei vorzeichenbehafteten Zahlen ist dies undefiniertes Verhalten (undefined behavior)
fig/overflow-underflow-cropped.svg

Undefiniertes Verhalten

  • Tritt auf, wenn im Standard das Verhalten nicht definiert ist
  • Kann alles bedeuten
    • Vom erwarteten Verhalten (Wrap-Around)
    • Absturz des Programms
    • Es erscheint ein Clown
    • …
  • Abhilfe: Nächstgrößeren Datentyp nehmen
    • Bei der Zahl 256 nicht 1 Byte (8 Bit) sondern 2 Byte (16 Bit)
  • Programmiert defensiv
    • Trefft lieber Vorkehrungen, wie KonsistenzprĂĽfungen der Werte
    • „Macht der Wert so ĂĽberhaupt Sinn?” 🤔

Verlasst euch nie auf undefiniertes Verhalten!

Beispiel häufige Fehler mit Integern

#include <stdio.h>

int main() {
    int wert = 22;
    wert = wert / 5 * 5;
    printf("%d", wert);
    return 0;
}
cpp

Auch Teilschritte sind betroffen!

Darstellung von reellen Zahlen

Bits Bytes Werte Name in C/C++
32 4 \(+/- 3.4 * 10^{38}\) float
64 8 \(+/- 1.7 * 10^{308}\) double
  • In zwei Geschmacksrichtungen
    • Einfache Genauigkeit: 32 bit → float
    • Zweifache Genauigkeit: 64 bit → double
  • Repräsentation ist standardisiert nach IEEE 754 (1985)
  • Sind fĂĽr viele Zwecke gut, aber auch kein Allheilmittel
  • Zur internen Darstellung und TĂĽcken von Gleitkommazahlen später mehr (→ Kapitel 6)

Beispiel - Grenzen der FlieĂźkommadarstellung

#include <stdio.h>

int main() {
    float f = 3.11231231231231231231231f;
    double d = 3.11231231231231231231231;
    printf("%.20f\n", f);
    printf("%.20f\n", d);
}
cpp

Einschub: Oktal- und Hexadezimalzahlen

  • Es gibt neben den bekannten Dezimal-, Hexdezimal- und Binärsystemen noch ein weiteres
  • Oktalsystem Zahlen von 0-7
\(8^3\) \(8^2\) \(8^1\) \(8^0\)
0 2 0 2

→ \(2 \cdot 8^2 + 2 \cdot 8^0 = 2 \cdot 64_D + 2 \cdot 1 = 130_D\)

  • Häufig in Programmcode verwendet, gerade wenn Bitdarstellungen notwendig sind

Zahlennotation in C/C++

  • Hexadezimalzahlen fangen in C mit dem Präfix 0x an: 0x42 = 66D
  • Oktalzahlen beginnen mit einer 0: 042 = 34D
  • Binärzahlen haben das Präfix 0b: 0b101 = 5D (nur C++; seit C++14)
  • Ebenfalls nur in C++: Visuelle Trennung einer Zahl mit ' zwecks Leserlichkeit: 10'500'000

Das erste Programm (Fortsetzung)

#include <stdio.h>

int main() {
    int i = 3;
    i = i + 5;
    printf("%d", i);
    return 0;
}
cpp

Jetzt fehlt nur noch printf()

Darstellung Zeichen

  • Durchnummerieren aller Zeichen (darstellbar und nicht-darstellbar)
  • Festlegung durch ASCII (American Standard Code for Information Interchange)
    • Spendieren 7 Bit fĂĽr die Darstellung (≠ 1 Byte!)
    • Bei 1 Byte werden unteren 7 Bit genutzt: 01101011
  • Heute wird ein Zeichen durch 1 Byte (z. B. UTF-8) dargestellt
  • In C/C++ durch ein char repräsentiert: char c = 'a';

ASCII-Zeichensatz

fig/ASCII_Code_Chart.svg

Spezielle Zeichen im ASCII-Zeichensatz

  • Darstellbar sind auch Sonderzeichen: !, @, >, <, ?, [, ], …
  • Aber es gibt auch nicht-darstellbare Zeichen
  • Die sog. Steuerzeichen dienen der Steuerung der Ausgabe
  • FrĂĽher bei Terminals relevant
  • Darstellung in „unserer Welt” durch vorangestelltes Backslash
    • Zeilenumbruch: '\n'
    • Terminierung einer Zeichenkette: '\0'

ASCII-Zeichensatz

fig/ASCII_Code_Chart_highlight.svg

Erklärung nicht-darstellbarer ASCII-Zeichen

Zeichen Bedeutung
\t Horizontaler TAB
\0 NUL
\n New line
\" AnfĂĽhrungszeichen
\' Hochkomma
\\ Backslash

Dualismus zw. Zeichen und Zahlenwerten

#include <stdio.h>

int main() {
    char c1 = 'A';
    char c2 = 'a';
    printf("%d\n", c1);
    printf("%d\n", c2);
    return 0;
}
cpp
  • Zeichen werden als Zahlen gespeichert – siehe ASCII-Tabelle
  • Rechnen mittels Zeichen möglich: int a = 'A' - 'a';
  • Vergleich von Zeichen und Zahlen: 'a' == 65

Zeichenketten (Strings)

  • Aneinanderreihung von Zeichen zu einem festen Ausdruck (Literal)
  • Gekennzeichnet durch AnfĂĽhrungszeichen: "
  • Beispiel: char * text = "Hello World";
  • Genaue Bedeutung von char * → Kapitel 9
  • 🚨 Wichtig: Zeichenketten sind immer NULL-terminiert
    • Am Ende jeder Zeichenkette steht das sog. NULL-Byte ('\0')
    • Zeichenketten belgen daher immer 1 Byte mehr
  • Beispiel: "Hello World"
    • Länge: 11 (sichtbare) Zeichen)
    • Belegt aber 12 Bytes: "Hello World\0"

Einschub: Ein-/Ausgabe

Wir waren hiermit gestartet …

#include <stdio.h>

int main() {
    int i = 3;
    i = i + 5;
    printf("%d", i);
    return 0;
}
cpp

ZurĂĽck zu printf()!

Einschub: Ein-/Ausgabe

  • Fast jedes sinnvolle Programm benötigt irgendeine Form von Informationseingabe bzw. -ausgabe
  • Häufige Bezeichnung: Input/Output (I/O)
  • Einfachste Möglichkeit fĂĽr Ausagbe in C:printf()
  • printf() verwendet sogenannten Formatstring, um an entsprechenden Stellen den Inhalt von Variablen einzusetzen
Spezifizierer Umwandlung
%d Ganzzahl (Dezimal)
%x Ganzzahl (Hexadezimal)
%s String
%c Character
%f Float

Einschub: Ein-/Ausgabe

  • printf() wandelt die gegebenen Variablen in Text um/ fĂĽgt sie in den Formatstring ein
  • Vollständige Liste von Spezifizierern unter cppreference.com
  • Beispiel: Float mit 2 Nachkommastellen printf("%.2f", 3.14159); → 3.14
Spezifizierer Umwandlung
%d Ganzzahl (Dezimal)
%x Ganzzahl (Hexadezimal)
%s String
%c Character
%f Float

Einschub: Ein-/Ausgabe

  • Eingabe analog zur Ausgabe mittels scanf()
  • Benötigt ebenfalls Formatstring, um Text in gewĂĽnschten Datentyp umwandeln zu können
#include <stdio.h>

int main() {
    float f1; // Speicherort anlegen
    float f2;   // Speicherort anlegen
    scanf("%f %f", &f1, &f2); // BefĂĽllung der Variablen
    printf("%f", f1 + f2);
    return 0;
}

Wir können nun mit unserem Programm interagieren 🥳

Mehrfach das Gleiche

Wie lege ich z. B. fĂĽnfmal einen Integer an?

int a_1;
int a_2;
int a_3;
int a_4;
int a_5;

Und fĂĽr 1000 Werte?

Das will man so nicht!

Felder (Arrays)

  • Ermöglicht das Zusammenfassen von n Instanzen des gleichen Typs
  • Alles landet in einer Variablen
  • Variablendeklaration um Größe und eckige Klammern erweitern
    • Vorher: int num_array; → ein Integer
    • Jetzt: int num_array[5]; → ein Feld mit fĂĽnf Integern
  • 👆 Jetzt wird auch klar, wie Zeichenketten abgelegt werden
    • char a = "Hello World"; → geht nicht!
    • char a[] = "Hello World";

Arrays

int num_array[5];

  • Erstellt Variable namens num_array als

    aufeinanderfolgende und zusammenhängende Menge von 5 int-Werten

  • Zugriff auf einzelne Elemente ĂĽber Index

    • Zählung beginnt bei 0
    • Indizes im Bereich [0, n-1]
    • Hier: [0,4]
  • Zugriff auf erstes Element mit [0] → printf("%d", num_array[0]);

  • Schreiben ist äquivalent dazu: num_array[0] = 1;

Arrays

int num_array[5];

  • Initialisierung erfolgt …
    • separat fĂĽr jeden Index: num_arrays[0] = 1;
    • vollständig bei Deklaration: int num_arras[5] = {1, 2, 3, 4, 5};
    • teilweise bei der Deklaration: int num_arras[5] = {1, 2};
  • 🚨 Achtung: Standardwerte fĂĽr restliche Werte variiert (→ später mehr dazu)
  • Bis hier: Initialisiert bitte jedes Element eines Feldes

Beispiel zu Feldern

#include <stdio.h>

int main() {
    float f[3] = {1.0, 2.3};
    printf("f[0] = %.1f\n", f[0]);
    printf("f[1] = %.1f\n", f[1]);
    printf("f[2] = %.1f\n", f[2]);
    return 0;
}
cpp

Regeln fĂĽr Arrays:

  • Können von beliebigem Typ sein
  • Alle Elemente sind vom gleichen Typ
  • Typ kann nicht mehr geändert werden
  • Länge ist ebenfalls fest!
  • Grund dafĂĽr ist einfach:

    Menge an benötigtem Speicher muss vorher bekannt sein

    (→ aufeinanderfolgend und zusammenhängend)

Denkt vorher über die Array-Größe nach!

Exkurs: Variable Length Arrays (VLAs)

  • Variable Length Arrays (VLAs) sind ein (gescheiterter) Versuch,

    Arrays mit dynamischer Länge zu ermöglichen

  • Nur in C möglich (ab C99), nicht in C++

  • Notation

#include <stdio.h>

int main() {
    int n = 10;
    int vla[n]; // Variable Length
    return 0;
}
  • Hat eine Reihe von Problemen → Vermeiden!

Exkurs: Klammern in C/C++

  • Bis hierhin wurden drei verschiedene Klammern eingefĂĽhrt ((), {}, [])
  • Im Englischen wird unterschieden
    • () → Parentheses (Parenthesen)
    • {} → Braces / Curly Braces (Akkoladen)
    • [] → Brackets (Eckige Klammern)
  • AuĂźerdem gibt es noch spitze Klammern bzw. Angled Brackets (<>) (Winkelklammern)

Zusammenfassung

  • Anhand von Hello World-Beispiel die GrundzĂĽge
    • der Darstellung von Zahlen behandelt,
    • erläutert wie Zeichenketten abgelegt werden,
    • Felder vorgestellt und
    • das Zusammenfassen von mehreren Variablen zu einem Feld erklärt.
Logo Sys
02 - Grundlagen