0% found this document useful (0 votes)
7 views159 pages

Programming I en

The document outlines a programming course focusing on C and C++, covering topics such as structured programming, control structures, functions, data structures, and software design. It includes information about the course structure, grading, bonus points, and external resources for learning. Additionally, it discusses the importance of programming in various careers and provides insights into using Integrated Development Environments (IDEs) and debugging techniques.

Uploaded by

toppayy.fb
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
7 views159 pages

Programming I en

The document outlines a programming course focusing on C and C++, covering topics such as structured programming, control structures, functions, data structures, and software design. It includes information about the course structure, grading, bonus points, and external resources for learning. Additionally, it discusses the importance of programming in various careers and provides insights into using Integrated Development Environments (IDEs) and debugging techniques.

Uploaded by

toppayy.fb
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Motivation & Organization

"I'm lazy by nature. If I have to repeat a task 10 times, I prefer to write a


script that does the work for me.

Programming takes three times longer, but it's worth it to me!"

Every Coding-Nerd, always

“The good thing about computers is that they do exactly what you tell
them to do - the bad thing about them is that they do exactly what you
tell them to do.”
The Universe

Why would I need programming in my career? I don't want to become a


pure developer!

Programming I en Page 1
Programming I en Page 2
Contents Programming 1

Introduction IDE
Editor
Debugger
Translation process

Basics of structured programming


Variables, data types, internal representation (number
systems)
Simple source code documentation
Operators
Boolean algebra (truth tables)

Control structures
Conditional statement / alternative (if-else)
Control structure case query (switch)
Header and footer-controlled loop (while)
Counting loop (for)

Functions
Return values
Input/return parameters

Data structures
Arrays
Structs
Enums

Memory management
Dynamic arrays

Software Design
Pseudo code
UML: Activity diagram
Design/documentation of methods/algorithms with the
help of design methods

Recursion

Modules / Storage classes

Testing
Creating a test plan
Desk test as test protocol

File management

Programming I en Page 3
About me

Prof. Dr. Martin Sonntag


Master of Computer Science (University of Paderborn)

PhD in Cooperation with Diebold-Nixdorf, Topic: Model-based


evaluation of SOA

Solution Architect and project leader at GMS Development (Service1)


-> Field service solutions for Miele, Vaillant, Roche Diagnostics, …

Teacher and Lecturer for Siemens Energy


Field of Teaching: Software Engineering

Programming I en Page 4
Bonus points

The written examination (90 min) determines 100% of the grade for the course.
Bonus points can be earned.

Bonus points
▪ Can only be credited if the exam is passed
▪ Max 15%
▪ 10% assignments (Moodle test, approx. 10 assignments)
▪ 4% code walkthrough of assignment tasks
▪ with comprehension questions
▪ 1% per assignment
▪ Only one assignment per date
▪ 1% presentation of an assignment task to the exercise group
▪ with comprehension questions and hints from the group
▪ Focus is on the use of technical language and constructive dialogue, a
completely correct solution is not required
▪ The bonus points are also valid for the following semester (no more after that)

Assignments (Moodle tests)


Tasks that you should work on and solve independently.
--> Help from the study group or the AI, if necessary Bonus points are awarded
according to the number of task packages, up to a maximum of 10%.

Programming I en Page 5
Why C as first language

Index of most widely used programming languages


[Link]
[Link]

Simple syntax
The syntax of C is comparatively simple and clearly structured. It is
used in a similar way by other programming languages. For example,
in C++, C#, Objective-C, Java, JavaScript, Ceylon, Rust, Perl, Go, Kotlin,
Swift, …

Understanding of basic concepts


Learning C helps to understand basic concepts of procedural
programming. For example, Variables, operations, conditions, loops or
functions.

Wide range of applications


C is used in many areas, including operating systems, compilers,
databases, game development and embedded systems.

Portability
C code can be used on different platforms and operating systems.
programs written in C can be ported to other systems relatively easily.

Control over hardware


C enables direct control over the hardware of a computer. It provides
access to memory addresses and allows the manipulation of individual
bits. This is important in the development of system software, drivers
and embedded systems.

Programming I en Page 6
Basis of C++
Building on C, we will learn object-orientation with C++. You can use
the knowledge you have acquired in C.

Programming I en Page 7
How to deal with the Coderunner

Plugin on the Moodle learning platform that compiles and tests code.

Coderunner only compares the string output of the programme, so you


have to pay close attention to every character.

This text fulfils the requirements, but was not


copied from the test case.

Marks the smallest changes, including double spaces.

Each row corresponds to a test case for which the programme


is executed.
The Input column simulates an input from the keyboard. The
programme must therefore contain one scanf() function per
line within a test case.

Programming I en Page 8
Lectures and exercise groups

Lecture
Course content
Build up and understand basic knowledge
Working on small tasks

Homework
Self-learning with Moodle tests

Exercises (in PC labs)


Code-walkthroughs and reviews
Repetition of content
Joint work on more complex tasks (moodle tasks)

Learning groups (self-organised)


Preparation/reworking of content from the exercises/lectures
Preparation for the exam

Programming I en Page 9
External Learning platforms

[Link]
Teaches the basics with small tests, smartphone app available.
Good for the couch or when travelling

[Link]
Enables the solving of coding tasks. Shows rated solutions from
other developers, offers ranking system.
Basic knowledge is required.
Example task: Hello

[Link]
Coding exercises with a strong gamification influence. Enables
online coding competitions against others.
Basic knowledge is required.

Programming I en Page 10
External sources

Englisch
▪ [Link]
▪ [Link]
in-c-january-iap-2010/pages/lecture-notes/

Deutsch
▪ Skript Uni Bochum [Link]
[Link]/[Link]/pic/[Link]
▪ Heimo Gaicher: Programmieren in C, Tredition, 2007
▪ Markus Neumann: C Programmieren für Einsteiger: Der
leichte Weg zum C-Experten, BMU Verlag, 2020
▪ Jürgen Wolf: C von A bis Z: Das umfassende Handbuch für C-
Programmierer, ‎‎ ‎ ‎ ‎‎ ‎ ‎ ‎ ‎ ‎‎ ‎ ‎ ‎ ‎ ‎ ‎‎ ‎ ‎‎‎ ‎‎‎ ‎ ‎‎ ‎‎ ‎ ‎‎‎ ‎ ‎ ‎
▪ Paul‎Barry,‎David‎Griffiths:‎C‎von‎Kopf‎bis‎Fuß,‎O'Reilly‎
Media, 2012

Videos:
C Programming

Programming I en Page 11
Quiz organizational matters

1. The tasks for bonus points (assignments)


A - can improve the grade by up to 1.0, but do not help to
reach the pass mark
B - help with passing
C - can also be done after the submission deadline

[Link]

2. The Moodle plugin Coderunner


A - Tests the entered code and announces the result
B - Is an AI that allows many similar solutions
C - Shows you the correct solution on request

### end of lecture 26.09.2025

Programming I en Page 12
Programming languages

Programming languages are very precise artificial languages for formulating programs.

They must not allow any ambiguities when creating a programme so that the computer
can execute the programme correctly.

When defining a programming language, the following three parts must be defined:

Lexis
The lexis of a programming language defines the valid characters or words that may be
used to compose programmes in the programming language may be composed of.

Syntax
The syntax of a programming language defines the correct structure of sentences made
up of valid characters or words, i.e. it determines the order in which lexically correct
characters or words may appear in the programme.

Semantics
Semantics defines the meaning/execution of syntactically correct constructs. Syntactically
correct code has exactly one semantics or exactly one way in which it is executed.

Programming I en Page 13
Who talks machine language - Not a single human being!

Machine code Assembler C


8B 45 F8 mov eax, DWORD PTR [rbp-8] int c = a + b;
8B 55 FC mov edx, DWORD PTR [rbp-4]
01 D0 add eax, edx
89 45 F4 mov DWORD PTR [rbp-12], eax

Machine language (1st generation)


Language as a sequence of bits that is made for the specific machine (CPU type).

Assembler (2nd generation)


Language with simple talking instructions that is tailored to the instruction set of the processor.

Higher programming languages (3rd generation)


The higher programming languages allow computer programs to be developed more quickly due to
the higher degree of abstraction. They are command-orientated and strongly adapted to humans.
Examples: Java, Cobol, C++, C#, javascript

Descriptive programming languages (4th generation)


Languages that only describe the result and not how it is determined.
Example: SQL (Structured Query Language)

SELECT Author, Title, Year


FROM Library
WHERE Title = "The Hitchhiker’s Guide to the Galaxy"

Programming I en Page 14
Interpreter

Interpretation
The source text is translated line by line and the commands are executed directly.

E.g. PHP, javascript

Advantage
▪ Fast program development
▪ Quick program start
▪ Programme changes are possible during runtime
▪ Processor and platform-independent, provided an interpreter is
available

Disadvantage
▪ Slow runtime
▪ Late error detection
▪ The source code is required to run the program (javascript can be
seen in the browser)

Programming I en Page 15
Compiler

Compilation
The source code is compiled and the machine code is saved in a
file. The linker compiles the machine code of the file and the
function libraries into an executable programme.

E.g. Delphi
C / C++

Advantages
▪ Fast runtime
▪ Syntactic errors are recognised immediately during compilation
▪ The same sometimes applies to simple semantic errors
▪ The source code does not have to be passed on to the user

Disadvantages
▪ Slow translation process
▪ Must be translated individually for different target systems (OS)

Programming I en Page 16
Compiler with runtime environment

Translation into an intermediate language


A complete pre-translation is carried out into an easily translatable intermediate
language, which is interpreted at runtime.

Language Runtime environment


Java Java virtual machine, JVM
C# .NET Framework

Advantages
▪ Platform independence
▪ Security checks are possible before execution
▪ Additional features, such as automatic memory
management and managed code (Microsoft languages)

Disadvantages
▪ A runtime environment is required
Programming I en Page 17
▪ A runtime environment is required

Programming I en Page 18
Quiz programming languages

1. What happens if the interpreter code for a server


programme (e.g. PHP) is changed during runtime (in
productive operation)?

- The changes take effect the next time the server


programme is restarted
- The changes take effect immediately (beware of side
effects)
- The changes only take effect when the server
programme is recompiled and restarted

2. One advantage of a programming language with a runtime


environment is
- The programme does not have to be compiled for each
individual platform, as the runtime environment
compensates for differences
- The programme usually runs faster than an interpreted
programme, as it has already been precompiled
- Nothing needs to be installed apart from the
programme, as the runtime environment is included in
the programme

Programming I en Page 19
IDE (Integrated Development Environment)

IDEs you can use:


1. Install Clion
CLion (recommended)
2. Activate the license
▪ Low installation effort
3. Get the example code running
▪ Available in the HSHL
▪ Student licence free of charge

Clion License activation

1. Start CLion
2. After starting, select the licence server in the licence dialogue
3. enter the following URL of the licence vault under Server address:
[Link]
4. log in to your personal JetBrains account or create one. Only
@[Link] and @[Link] are permitted as e-mail domains.
5. confirm any dialogues that appear
6. After activating the licence, CLion will display: Licensed to: Hamm-
Lippstadt University of Applied Sciences

Microsoft Visual Studio (slightly recommended)


▪ Medium installation effort
▪ Available in the HSHL
▪ Community licence free of charge

Solo-Learn Sandbox (to try out)


▪ Works out of the box (in the browser)
▪ Almost no features
▪ Alternative [Link]

Programming I en Page 20
CLion

1 Project folder with source code files


2 Source code editor
3 Console (input & output)
4 Other views (for example Problems ->
Notes on errors)

Programming I en Page 21
Rename und Autocomplete

Rename
If variables are to be renamed, the command Refactor->Rename can be
used in Clion.
This renames all variable occurrences in the code at the same time.

Auto-Complete
Ctrl + spacebar calls up a context menu that gives suggestions for the next
element. Tab accepts the suggestion.

Programming I en Page 22
Remove errors or how to avoid frustration

The Coderunner compiler reports the following:

Errors that you do not understand can quickly become frustrating.

What can I do?


1. Read the error message carefully, possibly have it translated by deepl
2. Google the error
3. Ask Chat-GPT what this error means
4. Give Chat-GPT my code and ask them to correct exactly the error WITHOUT correcting the rest.
5. Ask my fellow students
6. Ask about it in the exercise group

If the programme runs but does not do what it is supposed to, the debugger should always be used first.

‘But why? Chat-GPT can do everything right from the start!’

What are the disadvantages if Chat-GPT does everything?

Programming I en Page 23
Debugging (important!!1!)

If the programme is running but is not behaving as it should, the debugger allows
you to retrace the process step by step.

1 Start debugger
2 Breakpoint (execution is stopped here)
3 Current state of the variables (programme state)
4 Function stack
5 Watches (have your own expressions evaluated)
6 Control:
▪ To the next breakpoint
▪ Stop running programme
▪ Next line
▪ Jump to function call

partyYear = 32759 -> WTF???

Programming I en Page 24
Quiz IDE

What is part of an IDE?


- Debugger
- Grammar generator
- Refactoring tools (e.g. rename across multiple files)
- Compiler

What must be defined in order to be able to debug?


- Compiler setting
- Breakpoint
- Special Interpreter line

Programming I en Page 25
Names of basic elements and basic rules

/**
Program to calculate the year when a person's next big birthday party happens
author: Rosalie Brauer 0
version: 1.0
**/
0 Header comment of the program
#include <stdio.h> 1
10 Calculation operator
int main() { 2 13 Indentation -> expresses affiliation to a block. A block must be defined by {...}.
int birthYear, age, years, partyYear; 3 9 Assignment (date on right-hand side is saved in variable on left-hand side)
3 Declaration of several variables, separated by a comma
// Welcome message 4
printf("Welcome to the Party Year Generator\n"); 5 8 Parameter list, separated by a comma
6 14 Alternative if condition is not true
// Ask for the user's year of birth 11 Keyword for conditional statement / case differentiation
printf("In which year were you born?\n"); 7 Returns a keyboard input
scanf("%d", &birthYear); 7 6 Parameter of the character array data type (instead of string as in other
8 languages)
12 Logical condition (becomes true or false)
5 Function for output to the console
// Calculate the age
1 Integrating a library (header)
age = 2024 - birthYear;
9 10 2 Main-function
4 Single-line comment
if (birthYear > 2005) {
12 15 Exit the function (0 means ok)
11
years = 18 - age;
13 partyYear = 2024 + years;
printf("Your next big party for your 18th birthday will be in: %d\n", partyYear);
} else {
years = age % 10;
partyYear = 2024 + 10 - years;
if (years > 0) {
printf("Your next big party for a milestone birthday will be in: %d\n", partyYear);
} else {
printf(
14 "If you've already had a big birthday party this year, the next chance for a milestone birthday is in: %d\n",partyYear);
}
}
return 0; 15
}

Basic rules
• The program is always run line by line
• Each instruction is terminated with a semicolon
• Each program starts with the main function
• Functions (in C) usually return 0 if no errors have occurred.
• A function is a jump to previously written code and with a return to the call location at the end
• Libraries are other files that contain such functions, among other things
• Functions can also be written and used by the developer
• Blocks {…} contain a set of instructions and can be nested one in another

Programming I en Page 26
Naming conventions

Example identifier Convention


myOldCigaretteBrand camelCase
PressureGasTankLeft PascalCase
danger_noodle snake_case
der-geraet-schweissfrei kebab-case
myoldfiatmultipla Just ugly ;-) -> no-go

Keywords (if, true etc.) may not be used as identifiers.


Identifiers may not begin with numbers and may only contain a
few special characters.

German‎umlauts‎such‎as‎ö,ü,ä‎are‎usually‎replaced‎by‎oe‎ue‎or‎
ae, although this is now technically possible in most
programming languages.

In C, snake_case is predominant.

Variable minor my_age = 74


Function minor printf("7"), separate_by_line_endings()
Struct major struct Point{
int x; int y;}
Class (C++) major class Person

Reserved Keywords

Programming I en Page 27
More Details on C-Keywords:
[Link]

Programming I en Page 28
Number Systems

Addition - a piece of cake!

3
+ 8
+ 1516
= 2016

Programming I en Page 29
It's the basis that counts (place value system)

Place value system

In a place value system, a base number is defined first. The position of a


digit in a number determines the significance of the digit.

Example: 35010

3 * 10^2 +
5 * 10^1 +
0 * 10^0

Common place value systems:

Dezimalsystem

Example: 35010

3 * 10^2 +
5 * 10^1 +
0 * 10^0

Octal system (The Simpsons)

Example: 3508
chmod file 7 read 1 write 2 execute 4

3 * 8^2 + 20 21 22
5 * 8^1 + 1 0 1
0 * 8^0
= 23210

Hexadecimal system

Programming I en Page 30
Example: 35016

3 * 16^2 +
5 * 16^1 +
0 * 16^0
= 84810

Binary system Example: 1102

1 * 2^2 +
1 * 2^1 +
0 * 2^0
= 610

Programming I en Page 31
Binary numbers

Hexadecimal Decimal Binary


Example conversion from binary to decimal
0 0 0 0 0 0
1 1 0 0 0 1

2 2 0 0 1 0

3 3 0 0 1 1

4 4 0 1 0 0

5 5 0 1 0 1

6 6 0 1 1 0

7 7 0 1 1 1

8 8 1 0 0 0

9 9 1 0 0 1
There are 10 types of people
A 1 0 1 0 1 0 0 those who know the binary system
B 1 1 1 0 1 1
1 those who don't
C 1 2 1 1 0 0
D 1 3 1 1 0 1
E 1 4 1 1 1 0
F 1 5 1 1 1 1

Programming I en Page 32
Floating point numbers

Floating point numbers can be very large or very small. To avoid having to save every digit, the IEEE-754 format
can be used

Format
V * M * 2E

Exponent E
Exponent with which the base is exponentiated -> 2E

Mantissa M
factor with which 2E is multiplied out to represent the numbers between the full powers of two

Sign V
Single Bit for the sign 1 / -1

Example:

V = 0 -> +

E = 0110 01112 -> 10310

M = 0001 11…2 -> 945 99310

Float = +1 * 945 99310 * 2103

-> 9,593508 * 1036

After 7 significant decimal digits there is a cut. More precise numbers are not possible with 32 bit floats.

0.110 would be infinitely long as a float --> rounding problems. Actual value is 0.100000001in C

Programming I en Page 33
Quiz naming conventions and number systems

Which naming conventions correspond to their own


convention?

1. SNAKE_CASE
2. CamelCase
3. PascalCase
4. kebab-case

Which statements about binary numbers are true?

1. they can be infinitely long


2. some floating point numbers can only be stored imprecisely
3. the value range of integers is smaller than that of floating
point numbers with the same number of bits.

Programming I en Page 34
Data types

What has gone wrong here?

Sensor delivers 0,2 bis


0,53V.
Meaning is a temperature
of -50 to +80°C

Programm

U in V

Programming I en Page 35
Primary data types in C

Primary data types are also referred to as basic or primitive data types.

Table of the most common primitive data types in C


*Sizes are system/compiler-specific
** 0 == false, otherwise == true , module <stdbool.h> must be included

Minimum and maximum values are defined in the header file ‘limits.h’,
e.g. INT_MIN, INT_MAX

There are other types of data types, some of which are covered later:
Source: GeeksforGeeks

Programming I en Page 36
Primary data types in C++

Data Type Size (in bytes) Range


short int 2 -32,768 to 32,767
unsigned short int 2 0 to 65,535
unsigned int 4 0 to 4,294,967,295
int 4 -2,147,483,648 to 2,147,483,647
long int 4 -2,147,483,648 to 2,147,483,647
unsigned long int 4 0 to 4,294,967,295
long long int 8 -(2^63) to (2^63)-1
unsigned long long int 8 0 to 18,446,744,073,709,551,615
signed char 1 -128 to 127
unsigned char 1 0 to 255
float 4 -3.4×10^38‎to‎3.4×10^38
double 8 -1.7×10^308‎to1.7×10^308
long double 12 -1.1×10^4932‎to1.1×10^4932
wchar_t 2 or 4 1 wide character
Aus <[Link]

Programming I en Page 37
Literals

A literal expresses a value that a variable with a primitive data


type can assume. Each data type is expressed slightly differently
by literals.

float variable = 1;

Common literal types, for more details see here

###end of lecture 10.10.2025

Example:

float fuell_druck = 1.5f


long long int particles = 100000000000000L;

Constants
Each data type can be saved as a constant in a variable.
Constants can no longer be changed during the course of the
programme.

const double GRAVITY = 9.80665;


const double E = 2.7182818f;
const double ALCOHOL_DENSITY = 0.8;

Programming I en Page 38
Pointer

The pointer data type is briefly outlined here without covering it in detail:

Source: [Link]

#include <stdio.h>
int main()
{
int var = 10;

// declare pointer variable


int* ptr;

//assign the adress of var to ptr


//note that data type of ptr and var must be same
ptr = &var;

// assign the address of a variable to a pointer


printf("Value at ptr = %p \n", ptr); //00000007963ff944
printf("Value at var = %d \n", var); //10
printf("Value at *ptr = %d \n", *ptr); //10

return 0;
}

Programming I en Page 39
In- and output on the console

//Declare variable
int birthYear;
// fill it with input from the console
scanf("%d", &birthYear);
//print it as an int (%d stands for decimal)
printf("Your birthyear is %d!", birthYear);

Explanation
printf("Your birthyear is %d!", name);
%d is a placeholder that also specifies a format (see data types).
The second parameter is the variable that is used.

scanf("%d", &birthYear);
▪ scanf reads a value from the keyboard
▪ Parameter ‘%d’ specifies that the input is interpreted as an
integer number.
▪ Caution: If letters are entered, there is no error message
or warning. The letters are simply interpreted as numbers.
▪ The variable into which the read value is to be saved must
be of the same type as the format specification above (‘%d’
<-> int).
▪ The variable name must be preceded by the & (the reason
for this will be explained later)

Programming I en Page 40
Quiz data types
Which statements about data types are true?
1. Letters are also a data type
2. All data types are stored internally with only 0, 1 or letters
3. There is a data type that contains only the address to one byte
in RAM

What applies to the float and double data types


1. The actual number is stored in two parts, which must be added
together
2. Can represent about 80 respectively 160 significant decimal
places
3. It is better not to use it in programs with financial transactions

Programming I en Page 41
Characters and Strings

Strings
Strings are technically implemented in C with character arrays (series of letters).
Terminated with \0, as the array can be longer than the string.

char movie[15] = "Dark Knight\n";

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
'D' 'a' 'r' 'k' '' 'K' 'n ' 'i' 'g' 'h' 't' \n \0

A character set also contains non-printable characters (control characters), such as \n


Control char Meaning
\t Tabulator
\n LF (Linux, Mac) or CR LF (Windows) Line Feed
\0 String terminator (marks the end of the string in the array)

Character
The characters are encoded in various standards, e.g. ASCII, CP1252 or UTF-8 (silver
bullet).
Char in C uses ASCII. There is also wchar_t, with 16 or 32 bits (depending on the
system)

ASCII encoding table


UTF-8 encoding table
A character is stored internally as a number -> characters can be compared with each
other like numbers!

▪ 'a' < 'b' -> true


▪ 'a' < 'A' -> false
▪ '0' < '1' -> true

Max Müller
Programming I en Page 42
Max Müller

"Max M�ller" appears on the screen? -> wrong character encoding, use UTF-8 or a
another encoding

Programming I en Page 43
Formatting strings with printf and sprintf

printf() -> #include <stdio.h>

Stands for "print formatted"


Multiple variables can be inserted into a string by placeholders like %d
Placeholders can contain formatting options

%.2f outputs a decimal number that has two digits after the decimal point (dot)
%08f 0 -> left fill number with 0, 8 -> Number is 8 digits wide
%08.2f Left fill number with 0, but 2 digits are reserved after the decimal point (rounded)

int age = 25;


float height = 1.75;
char name[] = "John";
printf("Name: %s, Age: %d, Height: %.2f meters\n", name, age, height);

sprintf() -> #include <stdio.h>


Creates a string instead of printing it.
Useful for assembling strings with it later or passing it to other functions
int age = 25;
char buffer[50];
sprintf(buffer, "Age is: %d", age);
printf("%s\n", buffer);

Programming I en Page 44
Formatting strings with strcpy and strcat

strcpy() und strcat()-> #include <string.h>


strcpy() copies a string literal("I am a string literal")
strcat() puts two strings together

#include <stdio.h>
#include <string.h>
int main() {
char result[100] = ""; // Initialize an empty result string
char buffer[10] ; // Temporary buffer for the elements

strcpy(buffer, "Element1\n"); //Fill the buffer with the string and a line break
/* the next line would lead to an error, because buffer is an
array and "Loop1 " is a pointer to (memory address of) an array. */
//buffer = "Element1\n"; // Do not try this

strcat(result, buffer); // Concatenate the buffer and the result


strcpy(buffer, "Element2\n"); // Create second element in buffer
strcat(result, buffer); // Concatenate the new buffer and the old result
printf("%s\n", result); // Final concatenated result

return 0;
} Step Result Buffer
1 ""
What is printed by the program?
2 ? ?
3 ? ?
4 ? ?
5 ? ?

Programming I en Page 45
Quiz Strings

What applies to strings?


1. Strings consist of a sequence (array) of characters
2. A C variable representing a string can be assigned any string in the course of the program
3. char result[100] = ""; //create variable
result = "42"; //variable now contains "42"

###end of lecture 17.10.2025

Programming I en Page 46
Exercise repeat name

Task Console query: Inputs and outputs on the console

Implement a console output in C:


- which queries your name
- saves the input in a variable,
- and then outputs the name (value in the variable) on the
console.

What data type is to be stored in the variable?

Feel free to use this template:

#include <stdio.h>
int main() {
char name[10] = "";
//use scanf to read name

//use printf to print name

return 0;
}

You may use your IDE or


[Link]

Programming I en Page 47
Operators

What is the result of the expression?

5 + 3 *7

List of operators and their precedence

Description
Operator

() Brackets (function call)


strong
++ , — Increment, decrement
+/– Unary plus, minus
! Logical NOT (int)5.7f
(type) Cast Operator
* Dereferenciation-Operator
& Adress-of-Operator 5/2 -> 2
5%2 -> 1
sizeof size in Bytes
*/ % Multiplication, division, modulo 28%5 -> 3
+ - addition, subtraction
<< , >> Bitwise shifting
< , <=, > , >= less/greater than
== , != is equal to, is not equal to
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
&& Logical AND
|| Logical OR
Programming I en Page 48
| Bitwise inclusive OR
&& Logical AND
|| Logical OR
= Assignment
+= , -= Addition, subtraction assignment
*= , /= Multiplication, division assignment
weak

Programming I en Page 49
stark

Programming I en Page 50
Comparison Operators

Operator Meaning
Comparison operators return values of the bool data type:
== Equality
!= Inequality int year = 2022;
> Greater than year > 2023; //false
float gradC = 99.5f
< Less than gradC != 127.6; //true
>= Greater or equal
<= Less or equal bool isRetired, isYoung, hasJob, freeEntry;
&& And int age = 22;
hasJob = true;
|| Or isRetired = age >= 65;
^ Exclusive OR (XOR) isYoung = age <= 21;
freeEntry = (isRetired || isYoung) && !hasWork;
! Not

== is not useful for comparisons of strings. It is


permitted, but always returns false

char color[10] = "red" ;


0x0 0000
if (strcmp(color, "red")== 0) //correct color 0x1 0x3
//instead of
0x2
0x3 'r'
if (color == "red") //wrong
0x4 'e'

Note: color here is a pointer to a string that contains


an address. == only compares the address

strcmp returns 0 when the strings are equal,


but zero is interpreted as false. Therefore == 0 is
required here.

--> see Pointers

Programming I en Page 51
Operators and data types

The data type of the result depends on the operands. In


principle, the following applies: input data type equals output
data type

Expressio Result Data types: Remark


n value operand x
operand -->
result
3+5 8 int + int --> int
4.2 + 3.8 8.0 double +
double -->
double
4.2 + 3 7.2 double + Different operand types are
double --> not possible, so int
double automatically becomes
double
4.5f / 3.0f float / float -->
1.5f float
23/4 5 int / int --> int Pure integer division. Very
fast compared to float
operation. Decimal places
are truncated.
19%4 3 int / int --> int Remainder for integer
division.
19 / 4 = 4 Rest 3
15 > 2 True (1) int > int --> > always bool
bool
true && false bool && && (and Operator) delivers
false bool --> bool bool
Programming I en Page 52
false bool --> bool bool

What happens when 8/2.0 is computed? 8 is promoted to


double and then the result will be a double

Programming I en Page 53
Usage of the %-Operator

The modulo operator determines the remainder for integer division.

▪ Determination of single digits


▪ Divisibility check

Example:

#include <stdio.h>
int main() {
int x = 123;
//Check if x is dividable by 3
if(x%3 == 0) {
printf("x ist durch 3 teilbar\n");
}else{
printf("x ist nicht durch 3 teilbar\n");
}

// in result the current sum of digits is stored, starting with 0


int result = 0;
// 1st digit
result = x%10;
// 2nd digit
x = x / 10;
result = result + x%10;
//3rd digit
x = x / 10;
result = result + x%10;
printf("The sum of the digits is: %d\n", result);

return 0;
}

Programming I en Page 54
Quiz Operators

Which statements are true?


1. If a double and a float are added, the double value must first be converted to a float
value.
2. 180% 100 equals 20
3. 180 / 100 equals 1.8

Programming I en Page 55
Conditional Statements

#include <stdio.h>
#include <stdbool.h>
int main() {
// could be deliverd by a humidity sensor
bool isRaining = false;
// could be delivered by date check
bool streetCleaning = false; 1 Keyword if
2 Condition must always be resolvable to
// When is the street wet?
true(1) or false(0)
if (isRaining || streetCleaning)
3 The indented block is only executed if
1 2
{ the condition is true
printf("The street is wet\n"); 4 The optional Else part is only executed if
}else the condition is false.
{
printf("The street is dry\n"); 3
}

printf("Please drive carefully\n"); 4


return 0;
}

If the condition is evaluated by the program, a bool is expected.


Numbers are also accepted:
▪ 0 -> false
▪ All other numbers -> true

If statements can be nested:

if(condition1)
{
if(condition2)
{
//instruction
}
}

The example above is the same as this:

if(condition1 && condition2)


{
//instruction
}

Programming I en Page 56
If-else variations

if (condition_1) if (condition_1)
{ {
// Executed if condition_1 is true // Executed if condition_1 is true
} }
else if (condition_2) if (condition_2)
{ {
// Executed if condition_2 is true // Executed if condition_2 is true
} }
else if (condition_3) if (condition_3)
{ {
// Executed if condition_3 is true // Executed if condition_3 is true
} }
else
{
/* Executed if none of the above
conditions are met */
} ▪ Each block can be executed
▪ All conditions are checked, no matter which of them are
true
▪ Only one block is executed
▪ Conditions 2 and 3 do not need to be checked if
condition 1 applies

Programming I en Page 57
Ternary Operator

//Motor switch equals 1 means true -> on,


//else off
if (motor_switch) motor_voltage = motor_switch == 1 ? 24:0;
motor_voltage = 24; Same semantics
else (equal meaning)
motor_voltage = 0;

The ternary operator can also be used with function calls.


The following expressions are possible and useful:

motor_switch ? printf("Switch is on"):printf("Switch is off");

printf("The number is: %s\n", is_even ? "even" : "odd");

By intuition programming beginners like to write

if (motor_switch == true)

instead of

if (motor_switch)

Both are absolutely identical if motor_switch is a boolean / can only have two different cases.

Programming I en Page 58
The Switch Statement

The switch statement can be used instead of long else-if sequences

The following code blocks are different in syntax, but identical in their semantics (meaning)
if (motor_mode == 1) { switch (motor_mode) {
printf("Motor running at 50%...\n"); case 1:
} printf("Motor running at 50%...\n");
else if (motor_mode == 2) { break;
printf("Motor running at 100%...\n"); case 2:
} printf("Motor running at 100%...\n");
else if (motor_mode == 3) { break;
printf("Motor stopped...\n"); case 3:
} printf("Motor stopped...\n");
else { break;
printf("Invalid mode selected.\n"); default:
} printf("Invalid mode selected.\n");
} }

Without a break statement, the subsequent statements are always executed.


The default case is executed if no other case was applicable.

Case conditions may only contain constants (no variables).

int x = 1;
switch (motor_mode) {
case x:
printf("Motor running at 50%...\n");
break;
--> error, x is not a constant

Programming I en Page 59
Quiz conditional statements

Which statements are true?

1. With if-else constructs, either only the if or only the else


part of the code can be executed.
2. An if can also exist without else
3. The ternary operator is just a shorthand for certain if-else
constructs

Programming I en Page 60
Functions

How can I run a calculation, such as the BMI calculation, several times without having to restart the
program?

How can I create a programme with BMI and BAC calculator that is clearer than having both in the
main function?

Programming I en Page 61
What is a function?

Functions Function definition in general:


▪ Serve to structure the programme
▪ Take on clearly defined subtasks return_data_type identifier(parameter_list) {
▪ Can receive input via parameters …
▪ Can return a result (return) return …;
▪ Can change variables from other parts of the programme }
(via pointer/reference)
Example:
int area_of_square(int a){
int area = a*a;
return area;
}

Program state
with variables

y = f(x) = 2x²
Via pointer
(reference)

Copy Copy
Parameter Function body Return value
with instructions

Output

Multiple calls example:

#include <stdio.h>
#include <string.h>
//definition of a function
int area_of_square(int a){
int area = a*a;
return area;
}
int volume_of_cube(int a){
int volume = area_of_square(a) * a;

Programming I en Page 62
int volume = area_of_square(a) * a;
return volume;
}
int main() {
double my_volume = volume_of_cube(5);
//call of a function
printf("Square area: %d", my_volume);
return 0;
}

Programming I en Page 63
Functions with parameters and return values

#include <stdio.h>
1 2
void print_date(){

printf("Today is December 1st 2048\n"); 3


}
4
void print_iso_formatted_date(int day, int month, int year) {
printf("%d-%02d-%02d\n", year, month, day);
} 1 return data type (void = no return value)
2 name or identifier of the function
int return_number_of_days(int day, int month, int year) {
3 Output of the function, outputs can also be made via
int days= day + month*30 + year*365; monitor, loudspeaker, printer, hard disc
return days; 4 Parameter list. Parameters contain data that the
} 5 function requires for execution
5 return a data value that can be used at the call
int main() {
print_date(); point/stored in a variable
print_iso_formatted_date(1,12,2048); 6 Function calls with parameters and usage of the return
value
int number_of_days;
number_of_days = return_number_of_days(1,12,2048); 6
printf("%d", number_of_days);

return 0;
}

Output:
Today is December 1st 2048
2048-12-01
Days: 747881

Programming I en Page 64
Signature, declaration and definition of functions

The signature of
void print_iso_formatted_date(int day, int month, int year) {
printf("%d-%02d-%02d\n", year, month, day);
}
is
print_iso_formatted_date(int, int, int)

Functions must be declared before they are called, the definition may follow later. The
signature serves as declaration:

#include <stdio.h>
// Declaration of the function
void print_iso_formatted_date(int, int, int);

int main() {
// Call of the function
print_iso_formatted_date(01,12,2048);
return 0;
}
// Definition of the function
void print_iso_formatted_date(int day, int month, int year) {
printf("%d-%02d-%02d\n", year, month, day);
}

Programming I en Page 65
Quiz Functions

What applies to functions?


1. A program function can be compared to a mathematical
function f(x)
2. Allowed to work without return
3. Must receive at least one input per parameter

Which of the terms are part of a function definition


A Name
B Data
C Return
D Parameter
E Call
F Function body

Programming I en Page 66
Overloaded functions (C++, not C)

In C++ and other languages several functions can have the same name as long as they have
different signatures (function name and parameter type):

Overloaded functions are helpful, for example, if default values are to be used. The ISO date
function always requires the year to be entered.

The current year is usually used. A second function (not overloaded) is possible in C for this
purpose:

void print_iso_formatted_date_y(int day, int month ) {


printf("%d-%02d-%02d\n", 2024, month, day);
}

To avoid duplicated printf code, the original function should always be reused:

void print_iso_formatted_date_y(int day, int month) {


print_iso_formatted_date(day, month, 2024);
}

In C++ and other languages, functions can be overloaded. An overloaded function has the same
name but a different signature:

void print_iso_formatted_date (int day, int month) {


print_iso_formatted_date(day, month, 2024);
}

Note: This is not a recursive function call, as the function with two parameters could have a
different name. (Recursion is covered later)

Programming I en Page 67
Call-by-reference vs Call-by-value

Call By Value & Call By Reference in C - a video explaining pointers

Call-by-value
Parameters (actual parameters) are transferred as a copy when called. After the function is completed,
the parameters at the call location are unchanged.

Call-by-reference
Parameters (arguments) are passed as a reference (pointer). After the function is completed, the
parameters at the call location may have changed. The references are still a copy, but there is no need to
change them.

Pointer can be used to change variables across functions.

//Variable with value x


int x = 10;

//Variable with pointer on an int, NULL is the recommended default


//int* in a declaration means the data type is pointer (to an int)
int* ptrx = NULL;

//The & operator delivers the address of a normal variable


//The address of x is now stored in ptrx
ptrx = &x

//the * operator delivers the value to which the pointer shows


//20 is now stored in the variable behind ptrx
*ptrx = 20

Address Value Identifier/name


0x0000 0 NULL
&x -> 0x004A Address-operator
0x004A 20 x returns the address of x
0x0052 0x004A ptrx *ptrx -> follows the value of ptrx as an address and returns
0x0056 255 … the value found there (in this case the value of x)

x returns the value of x

#include <stdio.h>
// Function to demonstrate call by value
void callByValue(int x) {
x = 20; // This will modify only the local copy (stack) of 'x'
printf("Inside callByValue: x = %d\n", x);
}
// Function to demonstrate call by reference using pointers
void callByReference(int *x) {
*x = 20; // This will modify the original variable using its address
printf("Inside callByReference: x = %d\n", *x);
}

int main() {
int a = 10;
printf("Before callByValue: a = %d\n", a); // 10
callByValue(a); // 20 - Passing by value, changes won't affect 'a'
printf("After callByValue: a = %d\n\n", a); //10

printf("Before callByReference: a = %d\n", a); //10


callByReference(&a); //20 - Passing by reference, changes will affect 'a'
printf("After callByReference: a = %d\n", a); //20
return 0;
}

What would happen with this line?

Programming I en Page 68
What would happen with this line?
ptrx = 20;

The address 20 would be stored in ptrx. So *ptrx would just try


to get the memory value from this (randomly chosen) address.
This usually ends up in a memory access fault.

Technical note: In C there is technically only call-by-value. The


pointer passed is only copied.

Programming I en Page 69
Return parameter (reference parameter)

One (single) return value is great, but how can I return multiple variables/data types?
-> Parameters can also be used as return parameters if they are pointers.

int create_formatted_dates(char* iso_date, char* local_date, int day, int month, int year) {
sprintf(iso_date, "%d-%02d-%02d\n", year, month, day);
sprintf(local_date, "%02d.%02d.%d\n", day, month, year);
return 0;
}

int main() {
//create two strings to save the results in,
//Note: arrays are pointers with allocated memory
char iso_date[12];
char local_date[12];

//call the function, hand the strings as parameters


create_formatted_dates(&iso_date, &local_date, 01,12,2048);
printf("%s%s", iso_date, local_date);
return 0;
} Heap

Address Value
0x5A20 ‘2‘
0x5A21 ‘0‘
0x5A23 ‘4‘
0x5A22 ‘8‘
0x5A24 ‘-‘
0x5A25 ‘1‘ The stack is available in the debugger
0x5A26 ‘2‘
0x5A27 ‘-‘
0x5A28 ‘0‘
0x5A29 ‘1‘
0x5A2A ‘\0‘
0x5A2B ‘‘
0x5A2C ‘0‘
0x5A2D ‘1‘
0x5A2E ‘.‘
0x5A2F ‘1‘
0x5A30 ‘2‘
0x5A31 ‘.‘
… …

The create_formatted_dates area is deleted after the function is exited (return).

Programming I en Page 70
Global variables (static)

What is going wrong here?


char* return_iso_formatted_date(int day, int month, int year) {
char date[12];
sprintf(date,"%d-%02d-%02d\n", year, month, day);
return date;
}

int main() {
char* my_date;
my_date = return_iso_formatted_date(01,12,2048);
printf(my_date);
return 0;
}

date is created on the stack within the function return_iso_formatted_date and destroyed when the
function is terminated.

Solution A: Return parameter

Solution B: global variable static char date[12]; //outside the main function
Creates the variable on the persistent heap.

static char date[12];


void return_iso_formatted_date(int day, int month, int year) {
sprintf(date,"%d-%02d-%02d\n", year, month, day);
}
int main() {
return_iso_formatted_date(01,12,2048);
printf(date);
return 0;
}

-> Global variables should be avoided if possible, as they tie up main memory during the entire
program sequence.
-> Programs with static variables can become messy, as static variables can be modified in any part
of the source code file

Programming I en Page 71
Quiz Functions 2

Which statements are true


1. C functions are always call by value
2. Call-by-value automatically updates the value of the parameter
when the caller changes it
3. The return is often indicated by a status value in C (0 means
okay)

Global Variables
1. Are declared outside the functions
2. Accessible from any function
3. Each function has its own copy of the variable

Programming I en Page 72
Commenting code

Unannotated code is generally considered incomplete.


Code without documentation is also more difficult to use.

--> Comments are an important quality criterion for code


Minimum of comments:
- Comment for the file/module
- Comment for each function with explanation of parameters and return
- Comments for places that are difficult to read and places with possible pitfalls

Clever annotation can be used to create documentation with tools such as Doxygen.

/**
* @file commented_gcd.c
* @brief Compute the greatest common divisor (GCD) of integers.
*
* @note This minimal version performs no error handling.
*/

#include <stdio.h>
/**
* @brief Compute the greatest common divisor (GCD) of two integers.
*
* Uses the iterative Euclidean algorithm. Inputs may be negative;
* the result is non-negative.
*
* @param a First value.
* @param b Second value.
* @return The non-negative GCD of @p a and @p b.
*/
static int gcd(int a, int b) {
if (a < 0) a = -a;
if (b < 0) b = -b;
/* Euclidean algorithm, a will be the result */
while (b != 0) {
int t = a % b;
a = b;
b = t;
}
return a;
}
/**
* @brief Program entry point.
*
* Expects at least two integers per keyboard input (e.g. 84 30).
* Computes the GCD of them.
*
Programming I en Page 73
*
* @return 0 on completion.
*/
int main() {
printf("Enter first number: ");
int first;
scanf("%d", &first); /* No checks: assumes input is numeric. */

printf("Enter second number: ");


int second;
scanf("%d", &second); /* No checks: assumes input is numeric. */

int result = gcd(first, second);


printf("GCD = %d\n", result);
return 0;
}

This HTML documentation is created by Doxygen for the above code:

Programming I en Page 74
###end of lecture 31.10.25

Programming I en Page 75
Git (Source code management)

"I'm an egotistical bastard, and I name all my projects after myself. First Linux, now Git."

– Linus Torvalds

git - In British English, git is a rather friendly insult - not as strong as idiot, but not particularly
nice either.

Programming I en Page 76
Git Functions

Git is a source code management tool.


Among other things, it enables
▪ Versioned storage (history)
▪ Easy exchange of code
▪ Simultaneous editing and merging

This semester, only absolutely basic functions will be taught -> Use for
assignments and your own programmes
Programming II covers collaboration using git.

Basic git commands

git

Git Command Description


git init Creates a new local Git repository in the current
folder.
git add <file> Adds a file to the staging area
git commit -m "message" Creates a commit with a message
git merge <branch> Merges the specified branch into the current branch
git pull Fetch the latest changes from the remote repository
and merge them
git push Pushes local commits to the remote repository
git fetch Only fetch changes without integrating them
git checkout <branch> Switches to another branch
git clone <url> Clones an existing remote repository (e.g. from
GitHub)

Programming I en Page 77
Git Tutorial für CLion
Mittwoch, 29. Oktober 2025 11:00

Git can be used as a console application or as an integrated GUI


variant in an IDE. This lecture is limited to using the GUI in
Clion.

[Link]/help/clion/[Link]

Live demo:
- Integrate workspace into git
- commit / push
- pull
- git clone

Programming I en Page 78
Loops

Source: [Link]

How to calculate the rice grain number for all fields?

Or how to calculate 1000 BMIs with data from an interface?

Control structures

If/switch Execute alternative paths with conditional statements


Functions Structure code and call it repeatedly - one execution per
function call
Loops Repeat instructions as often as required

Programming I en Page 79
While-loop

int counter = 1;

1 2
while(counter <= 5){
4 printf("%d\n", counter); 3
counter++;
}

1 Keyword while
2 Condition (true/false)
3 Loop body
4 The programme always jumps back to the condition of the
loop and checks it again. As long as the condition is true, the
body is repeated.

In a loop, you must ensure that the condition becomes false at


some point, otherwise an infinite loop is created.

Intended infinite loops:

while (1){
listen(ftp_port);
}

int connected = false;


while(! connected){
// connect returns a boolean
connected = connect(serverip);
}

Programming I en Page 80
Do-while-loop

int number;
do {
printf("Enter a positive number: ");
//Read a number from keyboard
scanf("%d", &number);

if (number <= 0) {
printf("Invalid input, please try again.\n");
}
// Keep asking until number is positive
} while (number <= 0);

▪ In a do/while loop, the loop body is executed at least once


▪ Note that a semicolon is placed after the loop condition

Programming I en Page 81
Break bricht die Schleife komplett und führt den Code nach Ihr
aus.

Continue unterbricht nur den aktuellen Schleifendurchlauf und


geht direkt zur erneuten Prüfung der Bedingung über

Programming I en Page 82
For-loop (Counting-loop)

1 1 2
for (int i = 1; i <= 5; i++)
{ 2 3 4
5
printf("%d\n", i);
} 3

1 for Keyword 5
2 Initialisation of the count variable (i for index)
3 (Termination- or loop-) condition 4
4 Update instruction before checking the condition
again
5 Loop body (block of instructions)

Any loop can be interrupted by the break; command or


forwarded by the continue; command

Programming I en Page 83
Break bricht die Schleife komplett und führt den Code nach Ihr
aus.

Continue unterbricht nur den aktuellen Schleifendurchlauf und


geht direkt zur erneuten Prüfung der Bedingung über

Programming I en Page 84
Results of for loops
// Case A
for (int a = 10; a < 20; a = a + 1) {
printf("Value of a: %d\n", a);
}

// Case B
for (int a = 10; a < 20;) {
printf("Value of a: %d\n", a);
}

Programming I en Page 85
Transform while to for loop

int year = 2023;


while(year <= 2023 + 30) {
printf("Year: %d\n", year);
year++;
}

for (initialisation; condition; update)


{

instructions;
}

for(int i = 2023; i <= 2023 + 30; i++){


printf("Year: %d\n", year);
}

Programming I en Page 86
Comparison of loop types

All 3 types of loops have their own intended use. Often more than one type
of loop can be used for a problem.

Basically:
▪ The While loop is the mother of all loops, it can always be used
▪ The For loop is also called a counting loop. If it is known how many runs are
to take place, the code is easier to read than with the While loop.
▪ The Do-While loop covers the case where the first run should always be
executed. In some cases, slightly less code is required as a result.

Compiler optimisations generally do not result in differences in execution


speed. The loop type should always be selected with readability in mind.

Programming I en Page 87
Nested Loops

Loops can be nested inside each other.

Nested loops are generally used for multidimensional structures -> multidimensional arrays are covered later

A rectangle of points is already a two-dimensional structure. The following function can print a rectangle with any side length:

void print_rectangle(int width, int height) {

// Loop through each row


for (int row = 0; row < height; row++) {

// Loop through each column


for (int column = 0; column < width; column++) {
printf("#");
}
printf("\n"); // New row after each column
}
}

The total number of executions of the inner loop is ?

Programming I en Page 88
Quiz Loops

Which statements are true?


1. A for loop cannot run indefinitely
2. The while loop can replace any for loop
3. The for loop cannot count backwards in increments of two

What is correct?
1. For loops are good when the number of passes is not
exactly predictable.
2. while(1) is an infinite loop
3. For nested for loops, the number of passes adds up
(number of inner + outer passes)

[Link]

###end of lecture 07.11.2025

Programming I en Page 89
(Pseudo) random numbers

The library stdlib.h is provided in C for the use of random numbers

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main() {
// Seed the random number generator with the system time
srand((unsigned int)time(NULL));

// Generate a random number between 0 and RAND_MAX (32767)


int randomNumber = rand();
printf("Random Number: %d\n", randomNumber);

// To create a random number within a specific range, for example, 0 to 99


int randomNumberWithinRange = rand() % 100; // 0 to 99
printf("Random Number within 0 to 99: %d\n", randomNumberWithinRange);

// To create a random number within a different range, for example, 1 to 10


int start = 1;
int end = 10;
int randomInRange = (rand() % (end - start + 1)) + start; // 1 to 10
printf("Random Number within 1 to 10: %d\n", randomInRange);
return 0;
}

▪ Without the seed, the same sequence of pseudo-random numbers is generated each time the programme is
started
○ The same seed can be used to create the same test conditions
▪ If random numbers are frequently used in certain number areas, separate functions should be written (these are
usually available in other languages)

3546757 -> 3, 88, 35 ,

3546757 -> 3, 88, 35 ,

Programming I en Page 90
Modeling algorithms

What is an algorithm?
An algorithm is a clear instruction that leads to the solution of a
type of problem. A recipe, for example, is an (informal)
algorithm. Algorithms can be represented in various forms,
source code is just one of them.

What is modelling?
Models are an abstraction of reality. When modelling,
unimportant details are omitted and only the information of
interest for the case under consideration is shown.

Why do you model algorithms instead of writing them down


directly in code?
The model of an algorithm can have the following useful
properties:
▪ Quicker to understand and change
▪ Can also be understood by non-programmers
▪ Also serves as documentation

Programming I en Page 91
Activity diagrams
Activity diagrams are a widespread way of creating models for
algorithms.

Activity diagrams are part of the UML (Unified Modelling Language).

Known alternatives are:


▪ Structure diagrams (Nassi-Shneidermann diagram)
▪ Programme flow chart (PLC or German PAP)

The following elements of the activity diagram are sufficient to


describe algorithms, but are not all-encompassing (see UML
specification 2.5.1)

Activity diagrams are also used for describing business processes. Here
is an example:

6 1 Starting point / Initial node


2 Control flow / activity edge
1 3 Activity / Action node
3 4 Decision Node (if) creates alternative paths
2 4a Merge Node merges alternative paths
4b Loop by return to previous nodes
5 Fork Node for parallel / concurrent flows, also used
for joining for them
4 6 Swim Lane
7 Final node, end of all activities.

4b

4b
4a

Rules for creating UML activity diagrams


1. only decision nodes may have multiple inputs and outputs
2. alternative paths opened by decision nodes must be merged back into merge
nodes
3. decision/merge nodes have no inner text
4. alternatives are always indicated in square brackets on the arrows
5. all possibilities must be covered for alternative paths/arrows
6. only actions / activities are shown in the boxes with round corners -> no states
7. you can freely choose the level of description depth, from natural language to
instruction level, everything is allowed
8. each diagram has exactly one starting point. Several end points are permitted. If

Programming I en Page 92
8. each diagram has exactly one starting point. Several end points are permitted. If
an end point is reached, the entire diagram is finished.
9. swim lanes divide the activities into areas of responsibility, e.g. a role,
department or IT system.

Tool for UML diagrams: [Link]

Incident
process

Programming I en Page 93
Activity diagram for Lucky Punch

What is expressed by this diagramm? Describe in a linguistic


way.

Is it easier to develop according to the diagram or according to


the linguistic description?

Programming I en Page 94
Desk check

diff = 0
n=2
m=1
Step m n diff
1 1 2 Some embedded systems do not support debugging. The desk
test is used to check an algorithm without a debugger.
2 0
3 1 One line in the table is filled for each assignment.
4 2 Only the value that has been reassigned by the code in the
5 1 latest step is written to the table.
6 1 m n Result
7 1 4 10 2
8 1 2 6 2
9 0 3 5 1
10 1 40 10 10
11 0 1000 250 250
14 35 7
9 6 3
51 34

Programming I en Page 95
Quiz Algorithms

Algorithms
1. Are a description of how certain inputs with certain action
steps lead to a result
2. A recipe is comparable to an algorithm

Which statements are correct?


1. Activity diagrams are used to better understand algorithms
2. Activity diagrams are part of the Universal Markup
Language
3. Activity diagrams can depict processes

[Link]

Programming I en Page 96
Arrays

How can I save a large number of variables?

void prime01() {
int prime1 = 2;
int prime2 = 3;
int prime3 = 5;
int prime4 = 7;
int prime5 = 11;
//... Output
printf("prime1: %d\n", prime1);
printf("prime2: %d\n", prime2);
printf("prime3: %d\n", prime3);
printf("prime4: %d\n", prime4);
printf("prime5: %d\n", prime5);
}

Programming I en Page 97
Properties of arrays

void prime02() {
int prime[8] = {2, 3, 5, 7, 11};
1 Declaration with number and data type of the
1 2
elements, the length must be a constant (static array)
2 Literal for an array
3 3 Loop that increments the index i
for (int i = 0; i < 8; i++) 4 Access to element at position i
printf("prime %d: %d\n",i+1, prime[i]);
}
4

prime //Pointer to first element


array[i] = base_address + (i) * sizeof(element_type)
Address 0x42C9 0x42CD 0x42D1 0x42D5 0x42D9 0x42DD 0x42E1 0x42E5
Index 0 1 2 3 4 5 6 7 Access to prime[3]:
prime[3] -> prime + 3 * sizeof(int)
Value 2 3 5 7 11 0 0 0 prime[3] -> 0x42C9 + 3 * 4
prime[3] -> 0x42D5

Arrays
▪ Collection of data of the same data type
▪ The number of elements is invariable
▪ The array variable itself is a pointer to the first element
▪ The index i allows access to position i of the array,
▪ Index 0 -> first position, n-1 -> last position!
▪ Access in constant time or O(1) (no matter how many elements are in the array, access takes
approximately the same amount of time)
▪ Elementary data types (int, char, ...) and pointers permitted as data types
▪ Multi-dimensional arrays can be managed with an array of pointers to other arrays
▪ Initialisation with int prime[]= {2, 3, 5, 7, 11}; is possible, in this case prime has length
5

Programming I en Page 98
The two biggest problems in programming

1. assign meaningful names for variables, functions, etc.

2. do not use outdated cache data

3. Do not lose count by one

int primes[] = {2, 3, 5, 7, 11};


for (int i = 0; i < 5; i++)
printf("%d ", primes[i]);

###end_of_lecture 21.11.2025

Programming I en Page 99
Traversing Arrays

int primes[] = {2, 3, 5, 7, 11};


Output:
Prime number 1 is: 2
for (int i = 0; i < sizeof(primes) / sizeof(int); i++) Prime number 2 is: 3
{ Prime number 3 is: 5
printf("Prime number %d is: %3d\n",i+1, primes[i]); Prime number 4 is: 7
} Prime number 5 is: 11

sizeof(primes) Returns the number of bytes the variable is consuming


sizeof(int) Returns the number of bytes this datatype consumes on this platform

The number of elements in the array can be determined with


sizeof() if the array was defined in the same function. Outside of the
function, the length of the array must be passed as a variable.

Programming I en Page 100


Quiz Arrays

Which statements about int results[8] = {1,3,5};


are true
1. The array cannot accommodate more than 8 integers
2. The expression results without [] returns an address
3. You can also save a character in the array
4. results[8] is 0

What is true about traversing arrays


1. Traversing is the stepping through (and possibly changing) of all
elements of an array
2. Usually implemented in C with a while loop
3. To determine the number of elements for traversing the array,
sizeof() can be used without any problems

Programming I en Page 101


Handover arrays as a parameter

// adds the articlenumber to an empty stock slot


// parameter stock: the reference to stock array
// len_stock: the length of the stock array
int add_to_stock(int stock[], size_t len_stock, int article_number){ Stock
//find first empty element with 0
for(int i = 0; i < len_stock; i++){
if(stock[i] == 0){
//set article number in this slot and return 12343
stock[i] = article_number;
return 0; 12345
} Why not use sizeof(stock)
} instead of len_stock?
return -1; //no empty slot in stock found 12350
}
int main() {
size_t len_stock = 5; //tracks how many of the 5 places are filled 0
int stock[5] = {0}; //contains article numbers of articles in the stock
0
add_to_stock(stock, len_stock, 12343);
add_to_stock(stock, len_stock, 12345);
add_to_stock(stock, len_stock, 12350);

for (int i = 0; i < sizeof(stock) / sizeof(int); i++)


{
printf("Stock item %d is: %d\n",i+1, stock[i]);
}
return 0;
}

sizeof(array) returns the length of the array in bytes.


sizeof(int) returns the length of the int data type on the system.

sizeof(stock) / sizeof(int) returns the number of elements in the array

The array degenerates into a pointer when it is transferred to the new function.

sizeof(array) can only provide the length of the pointer itself (4/8 Byte).

When using an array as a parameter it can be declared in three ways:

int add_to_stock(int stock[])


int add_to_stock(int stock[10])
int add_to_stock(int *stock)

All are semantically identical. In each case a pointer is handed over.

Programming I en Page 102


Two-dimensional Arrays

Examples of two-dimensional arrays are images and tables with data:

- Seating plan in a cinema


- Energy consumption date listed in a table with year as row and month as column
- Temperature measurement data with timepoint as row and sensor location as column

General layout of 2-dim array:

int a[3][2];
Col 0 Col 1
int a[row][column]
Row 0 a[0][0] a[0][1]
Row 1 a[1][0] a[1][1]
Row 2 a[2][0] a[2][1]

Let's look at a simple picture example:

This image can be saved and output as a 2D array:

#include <stdio.h>
//To use them for the array, these constants must be declared via #define
//the const keyword would not work
#define NUM_ROWS 8
#define NUM_COLS 8
int main () {
//this creates a 2D array with NUM_ROWS * NUM_COLS elements, internally it is 1D
int picture[NUM_ROWS][NUM_COLS] = {
{0, 0, 1, 1, 1, 1, 0, 0},
{0, 1, 0, 0, 0, 0, 1, 0},
{1, 0, 1, 0, 0, 1, 0, 1},
{1, 0, 0, 0, 0, 0, 0, 1},
{1, 0, 1, 0, 0, 1, 0, 1},
{1, 0, 0, 1, 1, 0, 0, 1},
{0, 1, 0, 0, 0, 0, 1, 0},
{0, 0, 1, 1, 1, 1, 0, 0}
};

//for printing one (nested) loop per dimension is used.


//Make sure not to use i and j as loop variable names. Row and col ftw in readability
for (int row = 0; row < NUM_ROWS; row++){
for(int col = 0; col < NUM_COLS; col++){
//The access to array elements also uses the two bracket style
printf("%c ", picture[row][col] == 1?'#':' ');

Programming I en Page 103


printf("%c ", picture[row][col] == 1?'#':' ');
}
printf("\n");
}
}

Arrays can have many dimensions. All are stored in a contiguous memory block:

base_address + (row * number_of_columns + col) * sizeof(element_type)

Programming I en Page 104


Extension of Arrays (Dynamic Memory Management)

How can the size of an array be adjusted during the course of the programme?

//size_t is basically an unsigned integer


size_t len_stock = 5;

//This a constant array (constant size)


int stock[len_stock];

//Memory outside array accessed, but probably no error/crash


stock[8] = 9;

//Memory outside process memory accessed-> segmentation error -> crash


stock[8000] = 9;

Solution: Create (allocate) the storage space of the array with more storage space. --> Dynamic array is
required!

Memory function Explanation


malloc(size_t size) Allocates size bytes of memory. Does not initialize the memory
with zero (faster than calloc).
calloc(size_t Allocates number_of_elements * size_per_element
number_of_elements, size_t Bytes. Initializes every value with 0.
size_per_element)
realloc(void *array, size_t Tries to reallocate the array with size Bytes. If no consecutive
size) memory is available, new memory is allocated and the values are
copied. In this case the pointer array changes. Copying values is
slow.
free(void *array) The memory that has been allocated is freed and could be
reused. The old values remain in the memory.

//stock now has to be defined with the malloc function (memory allocation)
int *stock = malloc(len_stock * sizeof(int));

// Double the size


len_stock *= 2;
//Reallocate the stock array with the new size
int *temp = realloc(stock, len_stock * sizeof(int));

//if a pointer is returned, the memory allocation was successful


if (temp != NULL) {
stock = temp;
//if NULL is returned, the memory was full
} else {
free(stock);

Programming I en Page 105


free(stock);
printf("Memory allocation failed.\n");
return 1;

}
//Do some stuff with stock
//Do not forget to free the memory when not needed anymore -> memory leak
free(stock);

Debugging in Clion:
For dynamic arrays, the length must be specified manually for debugging. The following watch can be created
for the dynamic array stock. It then shows 5 or 10 elements of stock:

stock @ len_stock

Further information on dynamic memory management:


[Link]
c-using-malloc-calloc-free-and-realloc/

Further information on pointers:


[Link]

Programming I en Page 106


Pitfalls of dynamic memory management

malloc() can fail


▪ The implementation of the error case has been omitted for the sake of simplicity.
▪ Fragmentation of the memory due to memory chunks that are too small
▪ no more large contiguous memory available.

Memory leaks
▪ if the memory is not released again with free().
▪ The reason is often that the pointer to the allocated memory area has been lost.

Use of free() problematic


▪ Treacherous: memory content can be retained for a certain time after free() (until it
is allocated elsewhere)
▪ It is also bad to release a malloc() pointer twice (the memory may already be in use
again and will then be released again!)
▪ free() on pointers that were not created by malloc() leads to unpredictable
behaviour.

Programming I en Page 107


Quiz Arrays 2

Why are arrays passed to functions as two parameters?


1. One parameter contains the data type, the other the data
2. It takes the beginning and end of the array as parameters,
because sizeof() doesn't work in the new function
3. The information about the length of the array is lost during
the transfer (call-by-value)

Multidimensional arrays
1. Consist of nested arrays
2. In C, for declaration another pair of {} parentheses is used
per dimension
3. Stored internally as a one-dimensional array

Programming I en Page 108


Optional Info - Problems with scanf - keyboard buffer on second call

Line break in the buffer Output:


void read_chars() {
char a,b;
printf("1. character :");
scanf("%c",&a);
printf("2. character :");
scanf("%c",&b);
printf("\nYou entered : %c %c",a,b);
}

The Enter key is retained as \n in the keyboard buffer and supplied as


the second character.

Solution

void read_chars_win() {
char a,b;
printf("==========read_chars_win=========\n"); fflush() deletes all characters from the keyboard buffer,
printf("1. Char :"); unfortunately only under Windows
scanf("%c",&a);
fflush(stdin);
printf("2. Char :");
scanf("%c",&b);
fflush(stdin);
printf("\nYou entered : %c %c",a,b);
}

void read_chars_linux() {
char a,b;
printf("==========read_chars_linux=========\n"); getchar() != '\n' consumes all chars up to and including
printf("1. Char :"); the \n, then a new scanf()
do {scanf("%c",&a);} while ( getchar() != '\n' );
printf("2. Char :");
do {scanf("%c",&b);} while ( getchar() != '\n' );
printf("\nYou entered : %c %c",a,b);
}

Programming I en Page 109


Optional Info - Problems with scanf - buffer overflow

A string in C has a maximum length. If this is exceeded, an access violation occurs.

void buffer_overflow(){
char string[10];
puts("Enter 9 chars at most:");
//The overflow with more input than 9 chars cannot be prevented
scanf("%s", string);
puts(string);
}

Solution:

fgets() requires the maximum length of the string as a parameter and then truncates it:

void buffer_control(){
char string[10];
puts("Enter 9 chars at most:");
//After 9 chars the input is capped by fgets()
fgets(string, 10, stdin);
puts(string);

//other data types can then be read from the string with sscanf

int number;
sscanf(string, "%d", &number);
}

Programming I en Page 110


Recursion

A recursive function/method calls itself in its definition.

y = f(n):

y = 1*2*3*…*n

Factorial iterative
int factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}

Factorial recursive
natural language recursive definition of the factorial:
- the factorial of a number is the number itself times the factorial of the preceding number
- the factorial of 1 is 1

int factorial_recursive(int n) {
if (n == 1) {
return 1;
}
return n * factorial_recursive(n - 1);
}

calls with f(4)

f(4) = 4*f(3)

f(3) = 3 * f(2)

f(2) = 2 * f(1)

f(1) = 1

Programming I en Page 111


Function frames on the stack

A new function frame is created on the stack for each function call:

--> the call stack can be analyzed in the debugger

###end of lecture 5.12.25

Programming I en Page 112


Structure of a recursive method

Recursive methods usually have the following structure. The data types and number of
parameters are variable:

int recursiveMethod(int param)


if (param == ...){
Termination condition / recursion anchor / base case is the
result = fixed_value;
} end of the recursion call chain and returns a specific value
else {
...
result = … recursiveMethod(smallerparam...) Recursive call of the method
}
return result

Programming I en Page 113


Recursive Fibonacci calculation

f(n) 0 1 1 2 3 5 8 13 21 34 55 89 …
n 0 1 2 3 4 5 6 7 8 9 10 11 …

f(3) = f(1) + f(2)

The first Fibonacci number is zero, the second is 1. Each additional nth Fibonacci number is
defined by the sum of the previous Fibonacci number and the Fibonacci number before the
previous number.

f(0) = 0
f(1) = 1
f(n) = f(n-1)+f(n-2)

Fun Fact: f(n-1) miles are approximately f(n) kilometres

Number of calls for the calculation

j - Levels i - elements in f(5)


of the tree the whole tree
(approx. in full
tree) f(4) f(3)
1 1
2 2 f(3) f(2) f(2) f(1)=1
3 4
4 6 (8) f(2) f(1)=1 f(1)=1 f(0)=0 f(1)=1 f(0)=0
5 2(16)
6 0(32)
f(1)=1 f(0)=0

▪ f(10) can only be terminated when f(9) and f(8) have been calculated
▪ f(10) remains open until all subordinate calls have been completed
▪ The program uses the stack to remember where to jump back to for new calls
▪ If there is no termination condition or if new calls do not lead to it, functions are stored on the stack until it is full.
This is followed by a so-called stack overflow error.

Runtime analysis of the Fibonacci calculation (measured with a Python programme)

Programming I en Page 114


Programming I en Page 115
Summary recursive functions
Pro Contra

Readability Runtime problems


Recursive solutions can be more elegant and easier to In some cases, such as with large recursion depths,
understand than iterative solutions if the code reflects recursive code can be slower than iterative solutions.
the recursive nature of a problem.
Memory consumption
Abstract problem solving Recursion can lead to increased memory consumption,
Recursion makes it possible to approach complex as a new stack frame is created for each recursive
problems in an abstract way. You can focus on solving function.
the current part of the problem without having to If the stack overflows, a so-called stack overflow error
worry about the whole. occurs

Adaptability Complexity
Recursion can be applied to different types of Recursive code can be more difficult to understand than
problems, including mathematical calculations, data iterative solutions. Recursion can lead to subtle errors,
structures (e.g. trees and lists) and graphical such as infinite loops (recursive calls without a recursion
algorithms. It is a versatile concept. anchor).

Less code effort


In some cases, recursion can reduce the amount of
code required compared to using loops, as fewer
control structures are needed.

Solving complex problems


Recursion is often the best choice for solving complex
problems that can be broken down into smaller,
related problems, especially if the problem can be
broken down into sub-problems that are similar to
themselves.

Programming I en Page 116


Optional: Example for a recursive algorithm

Conversion of numbers (any base) into the binary system.


Note: Only integer division is used.

Decimal number n/2 n%2


52 26 0 5210=1101002
26 13 0
recursive definition of the function:
13 6 1 print_binary(n)=
6 3 0 0 if n =
3 1 1 0
1 0 1 print_binary(n/2) concatenated with if n >
print(n % 2) 0

110100

Für Interessierte: Vorgriff auf Algorithmen und Datenstrukturen in Semester 2


Merge sort in 3 minutes

Programming I en Page 117


Quiz Recursion

A recursive programme always has


1. a recursion anchor
2. a loop condition
3. a termination condition
4. a function call to the higher-level function

In contrast to iterative approaches, recursive programmes are


generally
1. better in terms of memory consumption (primarily in the
stack)
2. better suited for tree structures
3. the better performing approach
4. easier to understand

Programming I en Page 118


Modules

Problem
Helper functions for arrays, such as sum and average, are to be used in
various projects. However, the code must not be copied (maintainability).

Solution
Outsourcing to a separate array_utils module and integrating this in all
projects.

A module consists of a header (*.h) and a programme part (*.c)

Realization
Before a function/variable can be called from another module, it must be
declared (signature only).

-> Combine function and variable declarations into header files (here
array_utils.h).
-> Store implementation in array_utils.c

Header files are copied to C source files with the #include instruction of
the pre-processor (#include array_utils.h)

project1.c
array_utils.h
#include "array_utils.h"

Programming I en Page 119


project2.c
array_utils.c
#include "array_utils.h"

Programming I en Page 120


Standard libraries

Documentation: [Link]

Standard libraries are included with <>

#include <stdio.h>

User libraries are included with ""

#include "array_utils.h"

<assert.h> Help functions for troubleshooting


<complex.h> Complex numbers (C99)
<ctype.h> Tests for character classes, e.g. isupper(c), toupper(c)
<errno.h> System error codes
<fenv.h> Control of the floating point number environment (C99)
<float.h> Value ranges for floating point numbers
<inttypes.h> Conversion and formatting functions for integers (C99)
<iso646.h> Alternative operator spellings (e.g. and instead of && )
<limits.h> Restrictions for integers
<locale.h> Local settings (e.g. language, currency)
<math.h> Mathematical functions
<setjmp.h> Global jumps from functions
<signal.h> Signal handling e.g. for interrupts
<stdarg.h> Editing variable argument lists
<stdbool.h> Use of type bool and true (1) and false (0) (C99)
<stddef.h> Type definitions, NULL and errno
<stdint.h> Integer types of specified width (e.g. intNt with N=8, 16, 32, 64) (C99)
<stdio.h> Input/output
<stdlib.h> String conversion, random numbers, memory management, environment functions, search/sort
functions, integer arithmetic
<string.h> String processing
<tgmath.h> Type-generic maths functions (C99)
<time.h> Time and date functions
<wchar.h> stdio.h and string.h functions for extended character set
<wctype.h> ctype.h functions for extended character set (e.g. iswupper(c)) (NA1)

Programming I en Page 121


Custom libraries

euclid.h

#ifndef EUCLID_H
#define EUCLID_H main.c
int euclid(int x, int y);
#endif #include <stdio.h>
#include "euclid.h"
int main (void){
int x;
euclid.c int y;
#include "euclid.h" printf("x is: \n");
int euclid(int x, int y) { scanf ("%d", &x);
while (x != y) { printf("y is: \n");
if (x < y) { scanf ("%d", &y) ;
y = y - x; printf ("euclid for %d and %d is: %d\n", x, y, euclid(x, y)) ;
} else { return 0;
x = x - y; }
}
}
return x;
}

#ifndef EUCLID_H_
#define EUCLID_H_

If a file is accidentally included twice, this can lead to errors.


The pre-processor (#ifndef) therefore checks whether the
header has already been included.

Headers may contain entire functions. For reasons of


separation of code and interface, header files should only
contain:

▪ Function declarations
▪ Variable declarations (external)
▪ Global constants (#define, const)
▪ Own type definitions (typedef, struct, union, enum)

Programming I en Page 122


Complex projects

Project/
├── include/ # Contains header files
├── lib/ # Contains external libraries
├── src/ # Contains source code (e.g., .c files)
├── [Link] # Main CMake file

The same is also possible with the compiler on console level. the following example shows the usage of
the gcc compiler on Windows with the same setting as above:

gcc src/*.c -Iinclude -Llib -lmyLibrary1 -lmyLibrary2 -o [Link]

src/*.c Includes all .c files in the src directory.


-Iinclude Specifies the path to the include directory for header files.
-Llib Specifies the path to the lib directory where external libraries are located.

Programming I en Page 123


-lmyLibrary1 Links the libraries myLibrary1 and myLibrary2. Note that you don’t include lib
-lmyLibrary2 prefix or file extension here; for example, if you have libmyLibrary1.a, just use -
lmyLibrary1.
-o [Link] Names the output executable as [Link].

Programming I en Page 124


Quiz Modules

What is the purpose of using modules?


1. to make the code easier to store on a hard drive with a
directory system
2. better structure the code, i.e. improve its readability and
maintainability
3. to store smaller units of meaning in individual files
4. simpler integration of third-party code into your own code
base using libraries
5. better security against hacking attacks, as modules are
isolated from each other

The header of a module usually contains


1. function definitions
2. function declarations
3. global variables
4. loops and conditional statements
5. Import instructions for modules used

Programming I en Page 125


Storage classes / Scope of Variables

Variables have a range of validity, the so-called scope. These are possible:

local Local variables are valid within a function or block in which


they have been declared.
parameter Formal parameters (parameters in the function definition,
not arguments) are valid within the function. They have
priority over global variables (if they have the same name).
global Global variables are valid within a module
extern so that global variables from another module can be
accessed
static Variables and functions can be static. This means that they
are permanent but only valid within the module or within
a function

Initialisation
Global variables are initialised with 0 or NULL depending on their type.
However, local variables are not; they can contain old values.
#include <stdio.h>

int global_var = 10; // Global variable accessible from any file in the program
static int static_global_var = 20; // Static global variable accessible only in this file
extern int extern_var; // Declares an external variable defined in another file

void function1() {
static int static_local_var = 0; // Static local variable retains its value across calls
static_local_var++;
printf("Value of static_local_var in function1 (retains value across calls): %d\n", static_local_var);
}

void function2() {
int local_var = 30; // Local variable in function2
printf("Value of local_var in function2 (local scope): %d\n", local_var);
}

int main() {
printf("Value of global_var in main (global scope): %d\n", global_var);
printf("Value of static_global_var in main (file scope): %d\n", static_global_var);

// Demonstrating extern usage


extern int extern_var; // This refers to a variable defined outside this file or at a later point
extern_var = 50; // Assigning value to extern_var
printf("Value of extern_var in main (defined elsewhere): %d\n", extern_var);

function1();
function1(); // Calling function1 twice to see static local variable behavior
function2();

// Block scope
{
int block_var = 40; // Block-scoped variable
printf("Value of block_var in block scope: %d\n", block_var);
}
// block_var cannot be accessed here, outside the block

return 0;
}

Programming I en Page 126


Storage class static - Example

#include <stdio.h>
/* function declaration */
void func(void);

static int count = 5; /* global variable */

int main() {
while (count--) {
func();
}
return 0;
}

void func(void) {
static int i = 5; /* local static variable*/
i++;
printf("i ist %d und count ist %d\n", i, count);
}

count i
4 6
3 7
2 8
1 9
0 10

Programming I en Page 127


Storage class extern - Example

#include <stdio.h> #include <stdio.h>


#include "myExtern.c" extern int count;
int count; void write_extern() {
printf("Count ist %d\n", count);
void write_extern(); }
int main() {
count = 5;
write_extern();
count = 10;
write_extern();
return 0;
}

Programming I en Page 128


Storage class register

int monat;
register int monat;

For variables that are not to be saved in the main memory but
in a register. Register memory is not enforced.

The maximum size of the variable may not exceed the size of
the register (16 / 32 / 64 bits) on the platform (processor
architecture).

'&' operator cannot provide an address in the main memory as


this is not used.

Should only be used for variables that require fast access,


otherwise the rest will tend to be slower.

General: The register keyword is a hint to the compiler that the


object should be made accessible as quickly as possible

Programming I en Page 129


Quiz Scope
Which statements are true?
1. static variables are immutable
2. global variables are declared in the main function
3. external variables originate from imported libraries
4. local variables always apply within the surrounding {} pair
5. Local variables also apply in blocks that are in the
surrounding block

###end_of_lecture 12.12.25

Programming I en Page 130


Structs

Problem: Natural objects (such as books) consist of a number of variables. Managing these is impractical

We need to represent one or more data sets (books) consisting of a set of attributes

e.g: Title, author, subject, number of copies sold

General structure of a struct

Specifications in [] are optional

struct [structure Tag]


{
datatype identifier1;
datatype identifier2;
...
datatype identifierN;
} [one or more structure variables];

Struct is a data type similar to pointer or integer

Example for creating structs:

//anonymous struct, requires variable(s) //with name tag, for later use
struct { struct Book{
int books_printed; int books_printed;
char title[80]; char title[80];
char author[80]; char author[80];
}book1, book2 }

//named struct with definition of a variable


struct Book{
int books_printed;
char title[80];
char author[80];
}book3 = {80000000, "The Da Vinci Code",
"Dan Brown"}

-> Name tags (book) and variables after the declaration of the tag are optional, but one of them is always required.

//a new declaration allows the {} initialisation


struct Book book4 = {36000000, "War and Peace", "Leo Tolstoy"};
struct Book book5 ;

//book1 has not been initialized on declaration,


//so members have to be filled separately
book1.books_printed = 30000000;
strcpy([Link], "1984");
strcpy([Link], "George Orwell");

//the next line would go wrong, because book1 is a kind of package with different variables
inside:
//printf("%s\n", book1);

//use the . notation to gain access to the struct members


printf("%s - %s: ca. %d copies\n", [Link], [Link], book1.books_printed);

Programming I en Page 131


printf("%s - %s: ca. %d copies\n", [Link], [Link], book1.books_printed);

Programming I en Page 132


typedef syntax

typedef can be used to assign any names for data types:

typedef float velocity;


typedef float duration;
typedef float distance;

velocity calculate_velocity(distance d, duration t){


velocity v1 = d/t;
return v1;
}
int main(){
duration t1 = 5.4;
distance d1 = 250;
velocity v1 = calculate_velocity(d1, t1);

//confusing the two float parameters now leads to a compile time error
velocity v1 = calculate_velocity(t1, d1);
}

Units are not included; a different data type can be introduced for each unit using typedef so that they cannot
be swapped.

Structs can also be defined with the keyword typedef. The only difference to the standard is that struct no
longer needs to be used later:

typedef struct
{
datatype identifier1;
datatype identifier2;
...
datatype identifierN;
} [structure Tag];

//with typedef
typedef struct {
int books_printed;
char title[80];
char author[80];
}Book;

//if typedef was used, the keyword struct can be omitted


Book book5 = {36000000, "War and Peace", "Leo Tolstoy"};

Programming I en Page 133


booksprinted Title Author
4 Bytes 80 Bytes 80 Bytes
36000000 "War and Peace" "Leo Tolstoy"

Programming I en Page 134


Nested Structs

Structs can be nested as required:

typedef struct {
unsigned int hour; Appointment
unsigned int minute;
unsigned int second; Date
} Time_of_day; ▪ day
typedef struct { ▪ month
unsigned int day; ▪ year
unsigned int month;
int year; Time_of_day
} Date; ▪ hour
typedef struct { ▪ minute
Date d; ▪ second
Time_of_day z;
} Appointment;

When comparing structs, no pointers may be compared:

if([Link] == [Link] &&


[Link] == [Link] &&
...

Programming I en Page 135


Structs as parameters

//call by value
void printBook(Book book1) {
printf("Title: %s\n", [Link]);
printf("Author:%s\n", [Link]);
printf("Copies: %d\n", book1.books_printed);
}

Pro
The parameter list is clearer if a struct is passed instead of n variables.

Contra
A copy of all variables is transferred, even if only one is required. Cannot change the struct of the caller.

-> struct to be used as pointer

//call by reference
void print_book_ptr(Book* book1) {
printf("Title: %s\n", book1->title);
printf("Author:%s\n", book1->author);
printf("Copies: %d\n", book1->books_printed);
}

The operator -> must be used instead of .

Book* return_struct_reference() {
struct Book* ptr_book1; // declare ptr_book1 of type Book pointer
ptr_book1 = malloc(sizeof(struct Book));

ptr_book1->books_printed = 30000000;
strcpy(ptr_book1->title, "1984");
strcpy(ptr_book1->author, "George Orwell");

return ptr_book1;
}

Programming I en Page 136


Structs as return value

By returning a structs, several variables can be returned within the structs. A copy is passed
on. book1 is destroyed after the function is completed.

struct Book return_struct_copy() {


Book book1; // declare book1 of type Book
book1.books_printed = 30000000;
strcpy([Link], "1984");
strcpy([Link], "George Orwell");

return book1;
}

The return can also be made by reference without copying.

struct Book* return_struct_reference() {


// declare ptr_book1 of type Book pointer
Book* ptr_book1;
ptr_book1 = malloc(sizeof(struct Book));
ptr_book1->books_printed = 30000000;
strcpy(ptr_book1->title, "1984");
strcpy(ptr_book1->author, "George Orwell");
return ptr_book1;
}

free() has to be used in the calling function.

Programming I en Page 137


Quiz Structs

What is true about structs?


1. It is a package of variables of different/same data types
2. the order of the internal variables is decisive for access
3. can be passed like a single variable
4. each struct definition represents a separate data type
5. structs can be nested within each other as often as required

Programming I en Page 138


Arrays of structs

typedef struct Book{


int books_printed;
char title[80];
char author[80];
}

Book library[500];

As structs are a data type, they can be used in arrays

Programming I en Page 139


Bit fields

struct robo {
unsigned int sensor1:1; Note on the example
unsigned int sensor2:1; sizeof(robo) should be 1 byte, but is 4 bytes
unsigned int sensor3:1; Reason: 4 bytes is the smallest possible memory block for a bit field.
unsigned int sensor4:1; In this case, only 1 byte (8 bit) is used and 3 bytes are unused
unsigned int output:4;
} Robo1;

Enables efficient storage of data with low hardware resources


(embedded systems)

Memory is only as large as necessary, particularly useful for flags (like


bool, but they consume 1 Byte instead of 1 bit)

Add the number of bits for the attribute after the colon in the struct:

int attribute:1;

Permitted types for bit fields

▪ int
▪ unsigned int

Addition: C in version C23 also allows _BitInt(n), which can be used


alternatively and outside of structs:

_BitInt(1) sensor1;

Programming I en Page 140


###Quiz Structs 2

Programming I en Page 141


Enumerations

#include <stdio.h>
enum Direction {
NORTH, Output:
EAST, North: 0, East: 1, South: 2, West: 3
SOUTH,
WEST
};

int main() {
printf("North: %d, East: %d, South: %d, West: %d\n", NORTH, EAST, SOUTH, WEST);
}

Enumerations are named constants. The numbering is ascending and starts at 0, unless otherwise specified.

#include <stdio.h> #include <stdio.h>


enum Direction { enum Direction {
NORTH =11, //start value 11 NORTH = 0,
EAST, //12 EAST = 90,
SOUTH, //13 SOUTH = 180,
WEST //14 WEST = 270
}; };

An enum can also act as a data type. Some compiler versions support warning messages/errors if no suitable value is
transferred.

void move(enum Direction dir) {


switch (dir) {
case NORTH:
printf("Moving North\n");
break;
case EAST:
printf("Moving East\n");
break;
case SOUTH:
printf("Moving South\n");
break;
case WEST:
printf("Moving West\n");
break;
default:
printf("Invalid Direction\n");
break;
}
}

Programming I en Page 142


C++ Basics

Targets of C++
Providing object-oriented functions in a C-based language without compromising
efficiency

▪ Backward compatibility with C


▪ Better static type checking
▪ Data abstraction
▪ Objects and classes
▪ Prioritize efficiency of compiled code wherever possible

Software written in C++


▪ Game engines: Unreal Engine (Gears of War, Fortnite, ...)
▪ Control units such as those of the Tesla for autonomous driving
▪ Animation software such as Blender and Maya
▪ Databases such as MySQL and MongoDB
▪ Windows and MacOS (partially)
▪ Browsers such as Firefox and Chrome
▪ Libraries for AI/machine learning: TensorFlow (largely C++ )
▪ Financial systems such as Bloomberg Terminal

Programming I en Page 143


Programming I en Page 144
Hello World in C++
1 Namespaces allow the same names to be assigned to
classes and functions in different files as long as they are
different namespaces. Instead of std::cout, only
#include <iostream> 1
cout needs to be written.
using namespace std;
int main() { 2 cout replaces printf. It is a stream that outputs strings
cout << "Hello World!" << endl; to the console
3 The stream can be fed with the << operator
2
3 4 4 endl is a keyword that the stream recognizes. \n in
the string also works.
return 0;

Structure of a C++ file:

Header
[Link]
or .h .hpp

Codefile
[Link]
or .cc

Programming I en Page 145


The most important differences between C und C++

Feature C C++
Paradigm Procedural* Multi-Paradigm (Procedural + Object-
Oriented)
Object-Oriented Not Supported Supported (Classes, Objects, Inheritance,
Features etc.)
Memory malloc(), calloc(), free(), no new, delete, no garbage collection
Management garbage collection
Namespaces Not Supported Supported
Function Not Supported Supported
Overloading
Operator Not Supported Supported
Overloading
Exception Handling Error Codes, setjmp(), longjmp() try, catch, throw
Type Safety** Less Type-Safe More Type-Safe
Boolean Data Type int used as default, to be imported with bool Type (true/false)
stdbool.h
String Data Type char arrays are used as strings native string data type
Generics Not supported Supported
Standard Template Not Available Available - the STL provides data types like
Library Lists, Maps etc.
Input/Output printf(), scanf() cin <<
Operations cout >>
Compatibility Specific to C Mostly Backward-Compatible with C, C
libraries can be imported
Main compiler gcc g++ uses the same argument structure as gcc

*Procedural means that the language uses functions, but it is not functional. Functional
programming is the main paradigm of languages such as Haskell, Erlang, F# and Scala.

**Type safety ensures that variables must always have a predefined data type. This means that
the programmer has more work to do, but the compiler can detect errors that would otherwise
only be noticed later.

Type-safe (C)
int number = 12;
number = {12,2} //Early error warning from the compiler

Not type-safe (Python)


number = 12 //data type is automatically assigned due to assignment
number = {12,2} //number now has the datatype Set instead of int

//range requires an int as parameter, the set will crash the program. The compiler
can and will not warn about it:

Programming I en Page 146


can and will not warn about it:
for i in range(number):

###end of lecture 19.12.2025

Programming I en Page 147


Namespaces

Definition:

namespace customers
{
int number;
int find_by_name(string s)
{
//...
}
}

Usage
int result = customers::find_by_name("Meier");
//or
using namespace customers;
//...
int result = find_by_name("Meier");

Programming I en Page 148


Overloading functions

Overloading functions mainly serves the readability and maintainability of the code.

// Function with year parameter


void print_iso_formatted_date(int day, int month, int year) {
printf("%d-%02d-%02d\n", year, month, day);
}

In C++ and other languages, functions may be overloaded. An overloaded function has the same
name but a different signature:

// Function without year parameter, 2024 used as default


void print_iso_formatted_date(int day, int month) {
print_iso_formatted_date(day, month, 2024);
}

Note: This is not a recursive function.

Calls:
print_iso_formatted_date(01,10,2025);
print_iso_formatted_date(01,10);

Programming I en Page 149


Data streams and string in-/output

System library Variable Description


#include <iostream> cin standard input stream
cout standard output stream
iostream replaces some functions of stdio.h
System libraries are included without the .h file extension cerr standard error stream

Streams
stream: a source/destination for reading/writing bytes in sequence.
other iostreams: fstream, stringstream, etc.

Expression Description
cout << Expression Output extraction operator; writes the value of the expression to the
standard output
cin >> Variable Input extraction operator; reads from the standard input and stores it
in a variable

Data is sent "in the direction of the arrow"


endl sends '\n' and flushes the data stream:

cout << "Schüler #" << i << endl;

Input with cin: (you can also use getline to read the entire line)

int age;
cout << "Geben Sie Ihr Alter ein: ";
cin >> age;

Programming I en Page 150


Strings - the upgrade to char*

#include <iostream>
using namespace std;
int main() {
string message = "Hello World!";
cout << message << endl; Prompt
message[0] = 'h'; Hello World!
cout << message << endl; hello World!
return 0;
}

Changeability (Mutability)
Strings can be modified. Access to a string character through brackets

msg[0] -> "H"

Automatic memory management


Strings in C++ manage the memory automatically. The programmer does not have to worry about
allocating, reallocating or releasing memory.

std::string str = "Hello";


str += ", World!"; // Automatically resizes and manages memory

Usability
New functions and the operators + and == are available for std::strings

Function Description
length() Get the length of the string
substr() Extract a substring
find() Find a substring or character
compare() Compares if the letters in two strings are equal
replace() Replaces found substrings by another given string

Programming I en Page 151


enum class - typesafe enums

enum Color { Red, Green, Blue };


enum Trafficlight { Red, Yellow, Green }; // Name conflict with Color
int main() {
Color c = Blue; // `Blue` is in the global scope, no need to specify `Color::Blue`
Trafficlight t = Green; // Conflict! Which `Green` is this?
}

The previous enum construct can only use each value once. In the example, it is not clear whether Green
comes from Colour or Trafficlight.

enum class Color { Red, Green, Blue };


enum class TrafficLight { Red, Yellow, Green }; // No conflict!
int main() {
Color c = Color::Red; // Must use `Color::Red`
TrafficLight t = TrafficLight::Green; // Must use `TrafficLight::Green`
}

Programming I en Page 152


nullptr - the upgrade to NULL

void increase(int x);


//NULL should be a pointer that points to null, but it is 0.
// Calls increase(int), because NULL is interpreted as 0.
increase(NULL);

// Call is rejected by the compiler, nullptr is not an int.


increase(nullptr);

Programming I en Page 153


References - the upgrade for pointer

With references the programmer can hand over pointer that do not need to be dereferenced. The reference address cannot be
changed (which often happened accidentally).

Syntax
int& my_variable = 50;

Example
#include <iostream>
using namespace std;
void callByReferenceC(int *x) {
*x = 20; // This will modify the original variable using its address
cout << "Inside callByReferenceC: x = " << *x << endl;
}
void callByReferenceCPP(int& y){
y=y+10; // This will modify the original variable but without using *
cout << "Inside callByReferenceCPP: y = " << y <<endl;
}
int main() {
int a = 10;
callByReferenceC(&a); //20 - Passing by reference, changes will affect 'a'
cout << "Inside callByReferenceCPP: a = " << a << endl;
//the variable itself can be used as actual parameter
callByReferenceCPP(a);
cout << "Inside callByReferenceCPP: a = " << a << endl;
return 0;
}

Differences between pointer and reference:


Feature Pointer Reference
may point to nothing yes, may become null/nullptr no, always has a valid value
Initialisation constraint no yes
Address modification allowed yes no

Note: From a technical point of view, there is only call-by-value in C. Passed pointers have been copied.
However, the reference in C++ is also technically a real call-by-reference.

Programming I en Page 154


Data type declaration with auto
Instead of a data type, auto can also be specified in C++. The variable must be initialised immediately, as otherwise
the correct data type cannot be determined. Nevertheless, the data type must not be changed during the
variable's lifetime.

It is often more convenient to specify auto instead of the concrete data type; the compiler then determines the
correct type.

#include <iostream>
#include <map>
using namespace std;
int main() {
map<int, string> students = {{1, "Alice"}, {2, "Bob"}, {3, "Charlie"}};
// Without auto (long type name)
for (map<int, string>::iterator it = [Link](); it != [Link](); ++it) {
cout << it->first << ": " << it->second << endl;
}
// With auto (shorter & cleaner)
for (auto it = [Link](); it != [Link](); ++it) {
cout << it->first << ": " << it->second << endl;
}
}

Programming I en Page 155


Type conversion in C++

In addition to the casting method in C, C++ opens up further new possibilities.


They are more readable and in some cases also safer.

Here is the most common variant compared to C:

double average = 2.4;


int i = 0;
//C-style cast - avoid in C++
i = (int)average;
//C++ static cast for numerical conversions
i = static_cast<int>(average);

However, the static cast does not work if strings are to be converted into
numbers. There are special sto? functions, for example stoi() or stod().

std::string str = "42f";


// Safe string-to-int conversion, throws exceptions on errors
int num = std::stoi(str);

With static_cast<>, error cases must unfortunately be checked themselves


(e.g. double value is too large for integer range).

Exceptions are already thrown with sto? if the string does not fit into the target
format.

Programming I en Page 156


Command line parameter

Command line parameters can be used for C and C++ programs.

Problem
A finished application, such as a self-written encryption program, is
available for use as a compiled .exe. The customer wants to use the
application in a Powershell script or from the cmd terminal. All
entries should be made at the start of the program via the script,
keyboard entries would stop the script.

The mode (encrypt/decrypt), the password and the paths of the


input/output file must be transferred.

Solution:
The main method receives parameters that are read in by the .exe
call.

//int argc - number of parameter strings,


//char* argv [] - array containing separated (by blanks)
strings
int main(int argc, char* argv[]){

The command line call is either made in the cmd or can be set in
the IDE (for testing):

Call in cmd

Clion Run/Debug Configuration

In CLion, the .exe can be found in the cmake-build-debug folder:


Programming I en Page 157
In CLion, the .exe can be found in the cmake-build-debug folder:

This line should be stored in [Link]. This links the required


libraries statically - i.e. the libraries are stored in the .exe.

#This will build executables with the required libraries


included
set(CMAKE_EXE_LINKER_FLAGS"-static")

A possible stub of the encryption programme:


#include <iostream>
#include <string>
using namespace std;
//prints a kind of manual when parameters are wrong
void print_usage();
//int argc - number of parameter strings,
//char* argv [] - array containing separated (by blanks)
strings
int main(int argc, char* argv[]) {
//The program requires exactly 9 parameters. 0 is the
path of the .exe
if (argc != 9) {
cerr << "Error: Invalid number of arguments.\n";
print_usage();
return 1;
}
string mode, password, input_file, output_file;
//strings are pairs of "-?" and the parameter value
for (int i = 1; i < argc; i += 2) {
string arg = argv[i];
if (arg == "-m") {
mode = argv[i + 1];
} else if (arg == "-p") {
password = argv[i + 1];
} else if (arg == "-i") {
input_file = argv[i + 1];
} else if (arg == "-o") {
output_file = argv[i + 1];
} else {
cerr << "Error: Unknown argument " << arg
<< "\n";
print_usage();
return 1;
}
}
cout << "Mode: " << mode << "\n";
cout << "Password: " << password << "\n";
cout << "Input File: " << input_file << "\n";
cout << "Output File: " << output_file << "\n";
// Encryption/Decryption logic would go here
return 0;
}
void print_usage() {

Programming I en Page 158


void print_usage() {
cout << "Usage: [Link] -m <mode> -p
<password> -i <input_file> -o <output_file>\n";
cout << " -m <mode> : Mode
(encrypt/decrypt)\n";
cout << " -p <password> : Password for
encryption/decryption\n";
cout << " -i <input_file> : Path to input file\n";
cout << " -o <output_file> : Path to output file\n";
}

Programming I en Page 159

You might also like