Einführung in C++

01 - Übersicht und Imperative Programmierung in C(++)

Prof. Dr. Malte Schilling

Autonomous Intelligent Systems Group

🚀 by Decker

Ziele des Kurses

  • Erlernen grundlegender Konzepte und Sprachelemente von C++ (aufbauend auf C).
  • Anwenden von grundlegenden Konzepten imperativer Programmierung auf neue Programmiersprache.
  • Analyse: Unterschiede zu anderen OO Programmiersprachen (Java) verstehen und einordnen können
  • Diese direkt einüben an Beispielaufgaben und Problemstellungen, sowie in einem finalen Beispielprojekt (oo)
  • Teilnehmende sollen durch diesen Kurs in der Lage sein, sich selbstständig erweiterte Kenntnisse anzueignen.

Grenzen des Kurses

Dieser Kurs kann nicht abdecken:

Tiefgehende Kenntnisse über die Entwicklung von größeren Projekten.

../data/01/rn_image_picker_lib_temp_27d6d96a-0ef2-4810-aa99-e869c9f010df.jpg ../data/01/rn_image_picker_lib_temp_27d6d96a-0ef2-4810-aa99-e869c9f010df_B.jpg

Umsetzung: Angewandtes Lernen

Arten von Lernen

  • symbolische Erfahrung (d. h. Lernen durch Abstraktion).
  • ikonisch (d. h. Lernen durch Beobachten)
  • enaktiv (d. h. Lernen durch Handeln),

Ursprüngliche Kegel als Metapher gedacht, um Progression von Lernerfahrungen vom Konkreten zum Abstrakten zu zeigen (nicht als Abstufung/ Wertung von Ebenen!).

../data/01/dale_cone_experience.png
Dale’s Cone of Experience

Als Taxonomie für Lernen

Voraussetzungen

Kurs richtet sich an Programmierer, damit

  • aufbauend auf bestehenden grundlegenden Konzepten
  • und Erfahrungen in Programmierung
  • sowie objektorientiertem Design.

Bloom’s Taxonomie

../data/01/revised-blooms-taxonomy.jpeg

Überblick heutige Termin

  • Perspektive auf Software Engineering und Themen des Kurses
  • Organisatorisches
  • Entwicklung von C und C++
  • Imperative Programmierung
  • Kontrollfluss

Ziel: Erste C++ Programm auf dem Hub laufen lassen und hierin grundlegende Kontrollstrukturen anwenden können.

Vorstellung Lehrende

Malte Schilling

  • seit Wintersemester 2022 an der Universität Münster
  • Davor:
    • komme ursprünglich aus Münster
    • Studium in Informatik in Bielefeld (Schwerpunkt KI und Robotik) und Biologie (dezentrale Steuerung von laufenden Robotern)
    • Forschung zu Sprachmodellen in Berkeley, Kalifornien
    • und Forschungsaufenthalte zu Lernen in Neuronalen Netzen in visuellen Tasks mit Sony CSL, Tokyo

Meine Forschung

  • Forschungsinteresse ist das Verständnis und die Modellierung autonomer intelligenter Systeme.
  • Verstehen, wie Agenten intelligent handeln können: mit einer Umgebung interagieren. Fortbewegung und Manipulation als zwei Paradebeispiele für den adaptiven Umgang mit solchen realen Umgebung.
  • Machine Learning und im speziellen Neuronale Netze und Generative Modelle.
../data/01/cowalski.jpg
Cowalski

Perspektiven auf die Programmierung und Softwareentwicklung

Why should anyone learn to program?

The answer consists of two parts. First, it is indeed true that traditional forms of programming are useful for just a few people. But, programming as we the authors understand it is useful for everyone: the administrative secretary who uses spreadsheets as well as the high-tech programmer.

Programming activities

“To design a program properly, a student must:

  1. analyze a problem statement, typically stated as a word problem;
  2. express its essence, abstractly and with examples;
  3. formulate statements and comments in a precise language;
  4. evaluate and revise these activities in light of checks and tests; and
  5. pay attention to details.

All of these are activities that are useful for a businessman, a lawyer, a journalist, a scientist, an engineer, and many others.“

Kennzeichen von Programmier-Anfängerinnen und -Anfängern

  • wenig spezifizierte Herangehensweise.
  • Lokale, zeilenbasierte Arbeitsweise.
  • Keine Verwendung von Planungs- und Testtechniken.

Sicht auf Programmierung und Softwareentwicklung

../data/01/software_engineering_overview_01.png ../data/01/software_engineering_overview_02.png ../data/01/software_engineering_overview_03.png ../data/01/software_engineering_overview_04.png ../data/01/software_engineering_overview_05.png ../data/01/software_engineering_overview_06.png

Kennzeichen von Programmier-Expertinnen und -Experten

  • Verfügbarkeit effizient organisierter und spezialisierter Wissensschemata.
  • Wissensorganisation gemäß funktionaler Charakteristiken.
  • Anwenden allgemeiner Problemlösungsmuster und spezieller Strategien.
  • Anwendung spezialisierter Schemata für das Zerlegen und Verstehen von Programmen. Bereitschaft, mehrere Strategien zu erproben und Hypothesen zu verwerfen.
  • Verfügbarkeit korrespondierender Test- und Fehlersuchstrategien.

Unterwegs zum Informatiker: Inhalte in A-und-D

Vorstellung verschiedener Paradigmen zur Modellierung und Programmierung.

  • Einführung in datengetriebene Modellierung.
  • Einführung in testgetriebene Programmierung.
  • Formalisierung des Entwicklungsprozesses. Erlernen des Handwerkszeugs.
  • (Programmiersprachen als konkrete Beispiele für die betrachteten Paradigmen.)
  • Hilfe bei der Entwicklung hin zur Expertin/zum Experten.

Organisatorisches

Inhalte

In der Vorlesung wird die Sprache C++ anhand von praxisnahen Beispielen vorgestellt. Themen sind u.a.:

  • Kontrollfluss und Kontrollstrukturen
  • Funktionen, Template Funktionen
  • Datentypen (eingebaute Typen, Aufzählungen, …)
  • Pointer, Referenzen
  • Strukturen (C), Klassen (C++), Vererbung, Polymorphismus
  • Bibliotheken, Standard Template Library (STL)

Termine Kurs

Nr. Termin Thema
1 17.4. Einführung, Perspektiven Sofware Eng., Imperative Progr.
2 24.4. Datenstrukturen in C und C++: Pointer und Referenzen, Structs, …
Task 15.5. (Generative Sprachmodelle realisieren als einfacher ChatBot)
3 5.6. Objektorientierte Programmierung und Systementwicklung
Task 12.6. Zweites Beispieltask
4 19.6. Test-basierte Entwicklung, STL
5/6 26.6. Programmierwerkzeuge und KI-gestützte Entwicklung, Zusammenfassung
Abgabe finale Task bis Ende August 2024

Organisatorisches

  • Webseite für Kurs: jupyter-book mit Inhalten
  • darin auch link auf Folien (ebenfalls in html gesetzt)
  • interaktive, fortlaufende Programmierbeispiele und Aufgaben zu jeder Einheit
  • Anmeldung zum C/C++-Kurs im SlCM/QISPOS nicht vergessen!

Fragen und Materialien im Kurs

Fragen während des Kurses dürfen sehr gerne direkt gestellt werden.

  • Ebenfalls im Learnweb: Möglichkeit eines Austauschs untereinander (Forum).
  • Hinweis: Board-Regeln/Netiquette beachten.
  • Hinweis: Lehrende lesen mit ;-). Dies ist gewollt, da hier Fragen, die für alle von Interesse sind, gestellt und beantwortet werden.
  • Verwendete bzw. weiterführende Literatur wird zu den einzelnen Kapiteln angegeben.

Bearbeitung Tasks

Bearbeitung in Kleingruppen von zwei oder drei Personen sinnvoll.

Lerneffekt tritt nur ein, wenn jede(r) an der Bearbeitung aller Aufgaben beteiligt ist.

Honor Code: Angeben von Quellen und von Zusammenarbeit.

Arbeitsaufwand

Vorlesung wird mit 2 LP kreditiert, dies entspricht 60 Arbeitsstunden (inkl. Arbeit für die Abgabe) über die gesamte Vorlesungszeit.

Warum C++?

C++ ist immer noch eine sehr beliebte Sprache

../data/01/tiobe_index.png
Tiobe Index, 2021

Vergleich mit anderen Programmiersprachen

Vergleich mit Python

Comparison

Can Python do everything C++ can?

As a whole, Python can do the same thing that C++.

There are some slight differences, but Python can use C libraries and C can use Python libraries, so it’s possible to replace one language with another in most cases.

Which is more in-demand (2022)

According to Indeed USA, Python is more in-demand than C++.

  • 44,311 jobs available for Python developers
  • 15,778 jobs for C++ developers.

In terms of salary, C++ developers are paid better than Python developers (\$113,561 on average versus \$107,397).

Eigenschaften von C++

Mit C++ lernt man automatisch Informatik-Grundlagen

  • C++ ist eine High-Level Programmiersprache, die eine höhere Abstraktion bietet als C.
  • Dabei nutzt C++ Zeiger und manuelle Speicherverwaltung.
  • Schwerpunkt liegt so auf Informatikkonzepten, Leistung und Flexibilität und nicht zuerst auf der Einfachheit der Entwicklung.

Eigenschaften von C++ 2

Mächtige Programmiersprache

  • komplexen Sprachsyntax (C++ hat 60 Schlüsselwörter)
  • vielseitigen Standardbibliothek,
  • hardwareorientierten Entwicklungsumgebung.

Dadurch: Benötigt mehr Zeit im Erlernen.

Aber: Dies ermöglicht schnelles Erlernen anderer Programmiersprachen aufbauend auf C++-Kenntnissen.

../data/01/kuhlmann_3rd.png

Eigenschaften von C++ 3

Flexible Programmiersprache

C++ ist eine multi-paradigmatische und vielseitige Programmiersprache.

Daher: kann für eigenen Programmierstil genutzt werden und eigenen Best Practices für das Schreiben von Code mit C++ können etabliert werden.

Eigenschaften von C++ 4

Erstellen von leistungsstarken und einfache Lösungen mit C++

  • C++ erzeugt nach wie vor vom Umfang kleine Binärdateien und ist so beste Wahl für die Entwicklung leistungsorientierter Softwaresysteme.
  • C++-Kenntnisse helfen, bessere technische Entscheidungen zu treffen (nah an der Hardware)

../data/01/games_using_cpp.png

Warum C++?

Geschwindigkeit

../data/01/cpp_fast.png

C++ kann sehr schnell (und Speicher-effizient) sein.

Kontrolle auf unterer Ebene

../data/01/cpp_ebene.png

C++ ist relativ hardware-nah.

Entwicklung C und C++

Was ist C++? – C++ Code

#include <iostream>

int main() {
	std::cout << "Hello, world!" << std::endl;
	return 0 ;
}

Auch dies ist C++ Code (und C)

#include "stdio.h"
#include "stdlib.h"

int main(int argc, char *argv) {
	printf("%s", "Hello, world!\n");
	// eine C-Funktion!
	return EXIT_SUCCESS;
}

Technisch gesehen auch C++ Code

#include "stdio.h"
#include "stdlib.h"
int main(int argc, char *argv) {
	asm( "sub $0x20,%rsp\n\t" // assembly code!
		  "movabs $0x77202c6f6c6c6548,%rax\n\t"
		  "mov %rax,(%rsp)\n\t"
		  "movl $0x646c726f, 0x8(%rsp)\n\t"
		  "movw $0x21, 0xc(%rsp)\n\t"
		  "movb $0x0,0xd(%rsp)\n\t"leaq (%rsp),%rax\n\t"
		  "mov %rax,%rdi\n\t"
		  "call __Z6myputsPc\n\t"
		  "add $0x20, %rsp\n\t"
	); return (^) EXIT_SUCCESS;
}

C++ Vorläufer: Assembly

Vorteile:

  • Unglaublich einfache Anweisungen
  • Extrem schnell (wenn gut geschrieben)
  • Vollständige Kontrolle über ein Programm

Warum verwenden wir nicht immer Assembly?

… Assembly sieht so aus

section   .text
global		_start	;must be declared  for linker (ld)

_start:	;tell linker entry point
	mov edx,len	;message length
	mov ecx,msg 	;message to write
	mov ebx, 1	;file descriptor (stdout)
	mov eax, 4 	;system call number (sys_write)
	int 0x80 		;call kernel
	mov eax, 1 	;system call number (sys_exit)
	int 0x80		;call kernel

section .data		
msg db 'Hello, world!',0xa	;our string
len equ $ - msg				;length of our string

C++ Vorläufer: Assembly

Vorteile

  • Unglaublich einfache Anweisungen
  • Extrem schnell (wenn gut geschrieben)
  • Vollständige Kontrolle über ein Programm

Nachteile

  • Eine Menge Code für einfache Aufgaben benötigt
  • Sehr schwer zu verstehen
  • schwer auf vers. Systemen zum Laufen zu bringen = nicht portabel

Weiterentwicklung von Assembly: Die Erfindung von C

Die Idee:

  • Der Quellcode kann in einer intuitiveren Sprache geschrieben werden.
  • Ein zusätzliches Programm kann ihn in Assembler umwandeln
  • Dieses zusätzliche Programm ist der Compiler.

Sprache # Assembler Instruktionen für eine Instruktion der PS
C 2.5
C++ 6
Fortran 4
Java 6
Modula-2 4
Pascal 4
Python 7

Entwicklung von C

  • 1972 wurde C entwickelt von Ken Thompson and Dennis Ritchie
  • C hilft dabei, Code zu schreiben, der
    • schnell,
    • einfach und
    • plattformübergreifend ist.

../data/01/thompson_ritchie.png
Ken Thompson und Dennis Ritchie

Entwicklung von C 2

  • C folgt einem imperativen Programmierparadigma.
  • Hiermit beschäftigen wir uns die ersten zwei Einheiten.
  • Standardisierung 1990 in ANSI-C, auf allen gängigen Systemen verfügbar
    • C99 = 1999 – Viele Detailverbesserungen, teilweise inspiriert durch C++.
    • C11 = 2011 – Detailverbesserungen und Features, z.B. multi-threading support.
    • C18 = 2018 – Aktualisierter Standard. Bug fixes.

Erfolg von C

  • C war beliebt, weil es einfach war.
  • Das war aber auch seine Schwäche:
    • Keine Objekte oder Klassen
    • Schwierig, generischen Code zu schreiben
    • Mühsam beim Schreiben großer Programme

Programmiersprachen als Werkzeuge

Unterschiedliche Programmiersprachen sind für unterschiedliche Probleme besser geeignet.

  • C erlaubt die hardwarenahe Programmierung, daher gut geeignet für:
    • Betriebssysteme
    • Mikrocontroller (z.B. Autos, Flugzeuge)
    • Eingebettete Prozessoren (z.B. Smartphones)
  • C erlaubt hohe Kontrolle über die Hardware und damit sehr performante Implementierungen

  • Aber: C ist inhärent unsicher!
    • Eingeschränkte Typsicherheit zur Compilezeit
    • Keine Typüberprüfungen zur Laufzeit
    • Keine out-of-bounds Checks
    • Einfache Fehler bei Speicherverwaltung
    • usw.

Übersicht Entwicklung Programmiersprachen

Einführung von C++

  • Im Jahr 1983 wurden die Anfänge von C++ von Bjarne Stroustrup entwickelt.
  • Ziel war eine Sprache, die:
    • Schnell,
    • Einfach zu benutzen und
    • plattformübergreifend ist, sowie
    • High-Level-Funktionen anbietet.

../data/01/stroustrup.png
Bjarne Stroustrup

Entwicklung C++

code-99d788ee.tex.svg
  • C++20 Aktuellster Standard, viele neue Features
  • C++17 Erweiterungen zu Template Programmierung, und Typinferenz, UTF-8, …
  • C++14 Kleine Korrekturen und Erweiterungen zu C++11.
  • C++11 Umfangreiche Erweiterung der Sprache und der Standardbibliothek, u. a.: Lambda-Funktionen, Variadic Templates, Move-Semantik, Rvalue-Referenzen, Unterstützung von Threads, …
  • C++98 Erster Standard – auf allen gängigen Systemen verfügbar.

Designphilosophie von C++

  • Eigenschaften werden nur zur Programmiersprache hinzugefügt, wenn sie ein echtes Problem lösen!
  • Programmierer können ihren eigenen Stil wählen.
  • Aufteilung des Codes in Unterheiten ist ein zentraler Gedanke.
  • Der Programmierer hat die volle Kontrolle über Abläufe (wenn er will).
  • Leistung und Effizienz werden zuallerletzt geopfert …
  • Erzwinge Sicherheit schon zur Kompilierzeit (wann immer möglich).

C++: Grundlegende Syntax

Syntax

  • Semikolons als End-of-Line
  • Primitive Typen (ints, doubles, etc.)
  • Grundlegende Grammatikregeln

Die STL

  • Unmengen von allgemeinen Funktionalitäten
  • Eingebaute Klassen wie Maps, Mengen, Vektoren
  • Der Zugriff erfolgt über den Namespace std::
  • Extrem leistungsfähig und gut gewartet.

Vergleich

C++ JAVA PYTHON
Kompilierte Programmiersprache Kompilierte Programmiersprache Interpretierte Programmiersprache
Unterstützt Operatorüberladung Unterstützt keine Operatorüberladung Unterstützt Operatorüberladung
Bietet sowohl Einfach- als auch Mehrfachvererbung Bietet teilweise Mehrfachvererbung über Schnittstellen Bietet sowohl Einfach- als auch Mehrfachvererbung
Plattformabhängig Plattformunabhängig Plattformunabhängig

Imperative Programmierung

Modellbildung

Ziel der Modellbildung: Lösung eines Problems.

Festlegen (durch Spezifikation), welches Ziel gelöst werden soll.

Methoden zur Modellbildung: Logische Strukturen, Graphen, Grammatiken, Automatenmodelle, Petri-Netze, UML-Diagramme …

Präzisierung des Modells

Datenmodellierung

  • Angabe der Datenobjekte, mit denen die Realität nachgebildet wird.
  • Notwendig hierzu:Konstruktion von Datentypen und-objekten.

Ablaufmodellierung

  • Beschreibung der Verarbeitung der Datenobjekte.
  • Darstellungsformen: imperative/ funktionale/ prädikative/ objektorientierte Form.

Beschreibung des “imperativen Baukastens”:

  • Modell: Registermaschine für natürliche Zahlen mit Befehlen +1, −1, Test auf Null.
  • Programm: Zusammenstellung von Befehlen und Anweisungen.
  • Elementare Bestandteile: Zuweisung, Konkatenation, Alternative, Iteration.
  • Variablenkonzept: Orientierung an von-Neumann-Architektur; Behälterprinzip.
  • Start eines Programms: Ausführung der ersten Anweisung.

Datentypen und Kontrollfluss

Variablen in C

Variable

Eine Variable ist ein Name für eine Stelle im Speicher, an der ein Datum abgespeichert wird. Variablen haben dabei einen Gültigkeitsbereich (engl. scope), in dem auf die Variable zugegriffen werden kann.

  • Der Gültigkeitsbereich endet in C immer am Ende des Blocks (oder des Programms für statische Variablen), in dem die Variable deklariert wurde.
  • Ein Block wird von geschweiften Klammern umschlossen.
  • Ein Variablenname muss (in seinem Block) eindeutig sein.
  • Die Werte von uninitialisierten Variablen sind undefiniert.

Statische und Datei-weite Variablen

  • Statische Variablen können in einer Datei deklariert werden und sind in der Datei zugreifbar.
  • Das Schlüsselwort static erlaubt es statische Variablen innerhalb von Funktionen zu deklarieren (analog zu Java).
  • Statische und Datei-weite Variablen werden automatisch mit einem Null-Wert initialisiert.

Vorsicht: Die Verwendung solcher Variablen sollte vermieden werden, da sie zu schwierig zu entdeckenden Fehlern führen kann!

Datentyp

Datentyp

Ein Datentyp ist eine Menge von Werten zusammen mit einer Menge von Operationen, die auf diesen Werten definiert sind.

Elementarer Datentyp

Ein elementarer Datentyp ist ein Datentyp, dessen Wertemenge nicht weiter in Datentypen zerlegt werden kann.

Datentypen in C

In C gibt es eine Reihe von Basisdatentypen:

  • Für Buchstaben: charchar c = ’a’;
  • Für ganze Zahlen (Integer-Typen): char, short, int, long, long longint i = 42;
  • Für Gleitkommazahlen: float, double, long doubledouble d = 42.23;

Die Größe der Basisdatentypen ist systemabhängig. Abfrage über sizeof-Operator, z.B. sizeof(int). Der Datentyp char ist jedoch immer auf 1 Byte festgelegt.

Datentypen in C

  • Alle Integer-Typen sind standardmäßig vorzeichenbehaftet.
  • Integer-Typen ohne Vorzeichen: unsigned

Beispiele:

  • char c; //-128 .. 127 = signed char c; //-128 .. 127
  • unsigned char c; //0 .. 255

Mit dem Typqualifizierer const können Konstanten definiert werden.

Beispiel: const double PI = 3.1415927;

Häufig wird in C stattdessen ein Makro definiert: #define PI 3.1415927

typedef und Fixed Width Integer Types

  • Mit einer typedef-Deklaration kann ein neuer Name für einen Typ vereinbart werden.

Beispiel: typedef unsigned int uint;uint wird damit als weiterer Name für den Typ unsigned int deklariert und kann anschließend überall dort verwendet werden, wo auch der ursprüngliche Typname verwendet werden kann.

Im Header <stdint.h> sind Integer-Typen mit fester, systemunabhängiger Größe nach folgendem Muster vordefiniert: [u]intx_t mit \(x=8, 16, 32 \lor 64\). Beispiele:

  • int8_t = int mit einer Größe von 1 Byte (entspricht char).
  • uint64_t - unsigned int mit einer Größe von 8 Byte.

Die Typen müssen aber von der Zielplattform unterstützt werden!

Ausgabe: In C printf

Wie gibt man den Wert einer Zahl n aus?

int n = 42;
printf("n hat den Wert ...");
  • Der Ausgabe-String der printf-Funktion darf Platzhalter enthalten, z. B. %i für Integer-Typen und %f für Fließkommazahlen.
  • Die Platzhalter werden durch zusätzliche Argumente von printf ersetzt.
Input: printf("Ein Integer: %i. Eine Fließkommazahl: %f.", 10, 5.2);
Output: Ein Integer: 10. Eine Fließkommazahl: 5.2.

In C++ wird std::cout << genutzt (dafür muss iostream eingebunden werden: include <iostream>).

Aufgabe: Datentypen

Geben Sie die Größe der folgenden Datentypen auf Ihrem System aus:

  • char
  • short
  • int
  • long

  • long long
  • float
  • double
  • long double

Hinweise

  • Nutzen Sie den sizeof-Operator.

Demo - launch jupyter-book

Im jupyter-book sind verschiedene Aufgaben angegeben:

Jupyter-Book Link

Hierüber kann dann direkt auf dem Hub eine Umgebung gestartet werden, in der C++ interpretiert wird (wird die ersten Termine genutzt):

JupyterHub Link

Lösung: Datentypen in C

// datentypen.cpp
//In C use: #include <stdio.h>
#include <iostream>

int main() { 
    char c;
    short s;
    int i;
    /* sizeof kann auf Variablen ... */
    // In C use: printf("char:         %lu\n", sizeof(c));
    std::cout << "char:        " << sizeof(c) << std::endl;
    std::cout << "short:       " << sizeof(s) << std::endl;
    std::cout << "int:         " << sizeof(i) << std::endl;
    /* ... oder Datentypen angewandt werden */
    std::cout << "long:        " << sizeof(unsigned long) << std::endl;
    std::cout << "long long:   " << sizeof(long long) << std::endl;
    std::cout << "float:       " << sizeof(float) << std::endl;
    std::cout << "double:      " << sizeof(double) << std::endl;
    std::cout << "long double: " << sizeof(long double) << std::endl;
    return 0;
}
// Mögliche Ausgabe
char:         1 
short:        2 
int:          4 
long:         8 
long long:    8 
float:        4 
double:       8 
long double:  16

Wahrheitswerte und Kontrollfluss

In C gibt es erst seit dem C99-Standard einen Boolean-Datentyp (_Bool, durch inbinden von stdbool.h lässt sich _Bool als bool schreiben).

Generell gilt: Beliebige ganzzahlige Werte können als Wahrheitswerte verwendet werden.

  • Alle Werte \(\neq 0\)true
  • Wert \(=0\)false

Vorsicht bei Boolean

Zuweisungen

Zuweisungen haben den zugewiesenen Wert als Rückgabe:

a = b = 42;

Es ist auch die Zuweisung in if-Anweisungen legal:

if(a = b) { ... } // Kein Compiler-Fehler ,
if(a == b) { ... } // obwohl meist das hier gemeint ist.

Bitweise Operatoren

Bei logischen Verknüpfungen gibt es Unterschiede zu Java:

  • & und | haben nicht die gleiche Bedeutung, wie in Java, sondern bezeichnen bitweise Verknüpfungen:
    • & : Bitweises Und;
    • | : Bitweises Oder.

Arrays

Definition eines Arrays: int data1[42];

  • Statt der expliziten Größenangabe kann ein Array auch implizit mit einer Initialisierungsliste definiert werden: int data2[] = {1, 2, 3, 44, 55, 110};

Zugriff auf Elemente:

int a = data2[0]; // a == 1
data2 [1] = a;

Achtung:

  • Keine Exception bei unerlaubtem Zugriff wie z. B. data2[6] = 24;
  • Es gibt keine Funktion array_name.length()! Die Länge eines Arrays muss separat gespeichert/an Funktionen übergeben werden.

Task: Arrays

Erstellen Sie ein Array mit 1000 Zufallszahlen vom Typ int und geben Sie anschließend die Anzahl der Elemente aus, die größer als RAND_MAX/2 sind.

Hinweise:

  • Beachten Sie die Dokumentation der Funktion rand() unter http://en.cppreference.com/w/c/numeric/random/rand.
  • Nutzen Sie eine for-Schleife, um über die Elemente des Arrays zu iterieren.

Beispiel for-Schleife in C

for(int i = 0; i < grenze; ++i) 
{
  // ...
}

Lösung: Arrays

// array.c
#include <stdio.h> // printf
#include <time.h> // time
#include <stdlib.h> // rand und RAND_MAX

int main() {
  const int SIZE = 1000;
  const int THRESHOLD = RAND_MAX /2;
  
  int a[SIZE]; 
  int count = 0;
  
  srand(time(NULL)); // Initialisierung des Zufallszahlengenerators
  
  // Befüllen des Arrays mit Zufallszahlen
  for(int i = 0; i < SIZE; ++i) {
    a[i] = rand();
    if( a[i] > THRESHOLD ) ++count;
  }
  printf("%i Elemente sind groesser %i.\n", count, THRESHOLD); 
}

Strings

In C gibt es keinen Datentyp String!

  • Strings werden als Arrays vom Typ char realisiert.
  • Das Ende eines Strings wird durch das (Steuer-)Zeichen ’\0’ angegeben.

Beispiel: Der String "hello" entspricht {’h’, ’e’, ’l’, ’l’, ’o’, ’\0’}

Umständlich! → Kurzschreibweise:

char s[] = "hello"; // statt ...
char s[] = {’h’, ’e’, ’l’, ’l’, ’o’, ’\0};
  • Beliebte Fehlerquelle: \0 am Ende vergessen.

Task: Strings

Ersetzen Sie jedes Vorkommen eines Leerzeichens im String s durch einen Unterstrich. Nutzen Sie hierfür eine while-Schleife (Hilfe Kontrollstrukturen).

#include <iostream>

int main () {
    char s[] = "In C, string literals are of type char[], and can be assigned directly to a (non-const) char*.";
    
    // Ersetzen Sie in s jedes Leerzeichen durch ’_’
    // TODO

    std::cout << s << std::endl; 
}

Lösung: Strings

// stringreplace.cpp
#include <iostream>
int main () {
    char s[] = "In C, string literals are of type char[], and can be assigned directly to a (non-const) char*.";
    
    // Ersetzen Sie in s jedes Leerzeichen durch ’_’
    int i = 0;
    while(s[i] != '\0') {
        if(s[i] == ' ') {
            s[i] = '_'; 
        }
        ++i; 
    }

    std::cout << s << std::endl; 
}

References

Anderson, Lorin W., und David R. Krathwohl, Hrsg. 2001. A Taxonomy for Learning, Teaching, and Assessing. A Revision of Bloom’s Taxonomy of Educational Objectives. 2. Aufl. New York: Allyn & Bacon.
Dale, Edgar. 1969. Audiovisual methods in teaching. 3rd ed. N.York: Dryden Press.
Farooq, Sher Afzal AND Ahmad, Muhammad Shoaib AND Khan. 2014. „An Evaluation Framework and Comparative Analysis of the Widely Used First Programming Languages“. PLOS ONE 9 (2). Public Library of Science: 1–25. doi:10.1371/journal.pone.0088941.
Felleisen, Matthias, Robert Bruce Findler, Matthew Flatt, und Shriram Krishnamurthi. 2001. How to Design Programs. An Introduction to Computing and Programming. Cambridge, Massachusetts London, England: The MIT Press.
Robins, Anthony, Janet Rountree, und Nathan Rountree. 2003. „Learning and teaching programming: A review and discussion“. Computer science education 13 (2). Taylor & Francis: 137–72.
Vahrenhold, Jan. 2022. „Informatik I: Grundlagen der Programmierung, 1 Einführung“. Lecture Notes, University of Münster.