Slide 1

Slide 1 text

C/C++ - language Jussi Pohjolainen

Slide 2

Slide 2 text

C: Mother of all Languages • Many programming languages are directly derived from C or are heavily influenced by its syntax and design • C++: • Built on C with object-oriented features. • Objective-C: • A C-based language with object-oriented extensions. • Java and C#: • Adopted C-like syntax and many concepts. • JavaScript, Go, Rust, Swift, PHP, ... • Designed in the 70s! • 1978: Kernighan + Ritchie: "The C Programming Language" • From 1989 -> 2018 ANSI C standard. • 2018: C18 (ISO/IEC 9899:2018) language standard • Free doc: https://en.cppreference.com/w/c

Slide 3

Slide 3 text

Use Cases? • Operating Systems: • C is frequently used to develop operating systems due to its low-level capabilities and direct access to system hardware. Examples include UNIX, Linux, Windows, and macOS kernels. • Embedded Systems: • C's ability to directly interact with hardware makes it ideal for programming microcontrollers and embedded systems found in appliances, automotive systems, and consumer electronics. • Compilers and Interpreters: • Many compilers and interpreters for other programming languages are themselves written in C due to its performance and ability to manipulate system resources effectively. • Game Development, Networking, IoT Devices, Libraries...

Slide 4

Slide 4 text

Machine Code • Definition: The lowest-level programming language, consisting of binary code (0s and 1s) that the CPU directly executes. • Human Readability: Not human-readable; it's difficult to interpret and write directly. • Portability: Not portable across different types of CPUs, as different CPUs have different instruction sets. • Usage: Used for critical performance-sensitive applications, but typically generated automatically by compilers.

Slide 5

Slide 5 text

Assembly Code • Definition: A low-level programming language that provides a symbolic representation of machine code instructions. • Human Readability: Slightly human-readable with mnemonics for operations (e.g., MOV, ADD) and labels for memory addresses. • Portability: Hardware-specific and not portable across different CPU architectures. • Usage: Used for system programming, device drivers, and performance-critical code where hardware control is necessary. • First C – compiler was written with assembly

Slide 6

Slide 6 text

Assembly: x86 processor

Slide 7

Slide 7 text

Assembly: ARM64

Slide 8

Slide 8 text

An instruction set • An instruction set architecture (ISA), is a set of commands that a particular processor (CPU) can execute • These instructions are low-level commands that tell the CPU to perform basic operations • add, subtract, .. • AND, OR, XOR • Data movement • Control Flow • Input / Output • Assembly code is basically using these instruction sets • x86, ARM, MIPS, PowerPC

Slide 9

Slide 9 text

Compiling • Assembly code is compiled into machine code using a tool called assembler • NASM (Linux + Windows) • MASM (Microsoft Macro Assembler) • FASM (Flast Assembler) • Translates the assembly instructions into binary machine code that CPU can execute

Slide 10

Slide 10 text

Problems with Assembly • Productivity • Portability • Maintenance • Development tools

Slide 11

Slide 11 text

C - language • High – level language • More focus on programming logic than detailed knowledge of hardware • Portability: same code can be compiled to different architectures • Readability • Maintainability

Slide 12

Slide 12 text

// Preprocessor directive to include the standard input-output header file. // This file contains declarations for the I/O functions like printf and scanf. #include // The main function where program execution begins. // It returns an integer value to the operating system. int main() { // The printf function is used to print the string "Hello, World!" to the console. // The \n is a newline character, which moves the cursor to the next line after printing the string. printf("Hello, World!\n"); // The return statement ends the main function and returns the value 0 to the operating system. // Returning 0 typically indicates that the program finished successfully. return 0; }

Slide 13

Slide 13 text

Compile and Run gcc hello.c -o hello ./hello

Slide 14

Slide 14 text

GCC Compiler • GCC (GNU Compiler Collection) is a compiler system developed by the GNU Project • C, C++, Objective-C, Fortran, Ada, and others • Open source and free

Slide 15

Slide 15 text

Installing • macOS • Install Xcode command line tools • Linux (Debian/Ubuntu) • sudo apt update && sudo apt install gcc • Windows • https://winlibs.com/

Slide 16

Slide 16 text

WinLibs • Win32 vs. Win64: • Choose based on whether you need a 32-bit or 64-bit toolchain. • 64-bit is generally preferred for modern development due to better performance and the ability to handle larger memory. • Posix vs MCF • POSIX Threads • Standard threading model used in Unix-like systems. Code is portable across systems. Widely Supported. #include • MCF Threads • Not standardized, less portable, designed for massive concurrency, efficiently handling very large number of threads.

Slide 17

Slide 17 text

Variables

Slide 18

Slide 18 text

Basic Types • int (32 bits, 4 bytes)* • Stores integers (whole numbers), both positive and negative. • float (32 bits, 4 bytes)* • Stores single precision floating point numbers (numbers with a fractional part). • double (64 bits, 8 bytes)* • Stores double precision floating point numbers, providing more precision than float. • char (8 bits, 1 byte)* • Stores individual characters or small integers (usually 1 byte). • * Usually, can vary depending on OS and compiler

Slide 19

Slide 19 text

Bits, Byte? bit: 0 or 1 byte (8 bits): 01011010 // Example, character 'a' byte (8 bits): 01100001 => integer 97 => 'a'

Slide 20

Slide 20 text

32 bits, 4 bytes 32 bits / 4 bytes: 00000000 0000000 0000000 01100001

Slide 21

Slide 21 text

Basic Types int age = 30; // An integer variable int temperature = -5; // Can store negative values float weight = 65.5; // A floating-point number float height = 175.0f; // Suffix 'f' denotes a float literal double distance = 123.456; // A double precision floating point number char initial = 'A'; // Stores a single character char escape = '\n'; // Escape character for new line

Slide 22

Slide 22 text

Modifier types • signed • Allows storage of both positive and negative numbers. • unsigned • Only allows positive values and zero, effectively doubling the maximum value of a data type. • short • Used with int to specify a shorter integer. • long • Used with int to specify a longer integer.

Slide 23

Slide 23 text

Derived types • Arrays • A fixed-size sequence of elements of a single type, e.g., int arr[10];. • Pointers • Variables that store memory addresses of another variable, e.g., int *ptr;. • Structures • A user-defined data type that allows the combination of data items of different kinds, e.g., struct { int age; char *name; } person;. • Union • Similar to structures, but the members that share the same memory location, allowing different types of data in the same location at different times. • Function Pointers • Variables that point to functions.

Slide 24

Slide 24 text

Modifier Types unsigned int followers = 5000; // Only positive numbers short int distance = 32000; // Short integer, typically 2 bytes long int population = 1000000; // Long integer, typically 4 or 8 bytes unsigned long int stars = 4294967295; // Large range positive numbers signed short temperature = -32768; // Allows for negative numbers in a small range

Slide 25

Slide 25 text

Modifier Types #include #include int main() { unsigned long x = 18446744073709551615UL; printf("%lu", x); return 0; }

Slide 26

Slide 26 text

Casting • Casting in C is a way to convert a variable from one data type to another. • This can be done explicitly using casting operators or implicitly by the compiler

Slide 27

Slide 27 text

Explicit Casting • Casting in C is a way to convert a variable from one data type to another. • This can be done explicitly using casting operators or implicitly by the compiler • Example int i = 10; float f = (float) i; double d = 9.5; int x = (int) d; float temp = 65.99; char ch = (char) temp;

Slide 28

Slide 28 text

Implicit Casting • Implicit casting is automatically performed by the compiler when passing values between different types without explicit cast • However, care must be taken as implicit casting can sometimes lead to unexpected results or data loss: • Example int i = 42; float f = i; // We do not lose information

Slide 29

Slide 29 text

Output and Input

Slide 30

Slide 30 text

Output • The printf function in C is a standard output function that is used extensively for formatting and printing data to the console • int printf(const char *format, ...); • format: A format string that includes text to be printed, placeholders for variables (format specifiers), and formatting instructions. • ...: Represents a variable number of arguments that replace the format specifiers in the format string.

Slide 31

Slide 31 text

Format Specifiers Format Specifier Description Example Value Printed Output %d or %i Integer in decimal base 42 42 %u Unsigned decimal integer 150 150 %f Floating-point number 3.14159 3.141590 %lf Double precision floating point (used interchangeably with %f in printf) 3.1415926535 3.141593 %e or %E Scientific notation (lowercase or uppercase) 123456.789 1.234568e+05 %g or %G Shortest representation of %f or %e (lowercase or uppercase) 0.00012345 1.2345e-04 %x or %X Unsigned hexadecimal integer (lowercase or uppercase) 255 ff or FF %o Unsigned octal integer 10 12 %c Character 65 A %s String "Hello" Hello %p Pointer address Address of x 0x7ffeefbff8d8 %% Percent sign N/A %

Slide 32

Slide 32 text

Escape Sequences • \n: New line • \t: Horizontal tab • \a: Alert (bell) character • \\: Backslash • \": Double quote

Slide 33

Slide 33 text

Examples printf("Hello, world!\n"); printf("Temperature: %.2f degrees\n", 23.456); printf("Character: %c\n", 'A'); printf("Hexadecimal: %#x\n", 255);

Slide 34

Slide 34 text

Input • The scanf function in C is used to read formatted input from the standard input, typically the keyboard. • It is one of the most common input functions in C and serves as a counterpart to printf, which is used for formatted output. • int scanf(const char *format, ...); • format: A format string that contains one or more format specifiers, which specify the type and format of the data to be read. This string also can contain literals and whitespace characters, which are used to match the input. • ...: The additional arguments must be pointers to variables where the read values are stored.

Slide 35

Slide 35 text

Format specifiers • %d - Reads an integer. • %f - Reads a float. • %lf - Reads a double. • %c - Reads a single character. • %s - Reads a string until a whitespace is encountered. • %[...] - Reads a string that matches a set of characters specified within the brackets.

Slide 36

Slide 36 text

Examples int number; printf("Enter an integer: "); scanf("%d", &number); printf("You entered: %d\n", number);

Slide 37

Slide 37 text

Examples float pi; printf("Enter a floating point number: "); scanf("%f", &pi); printf("You entered: %f\n", pi);

Slide 38

Slide 38 text

Examples char ch; printf("Enter a character: "); scanf("%c", &ch); printf("You entered: %c\n", ch);

Slide 39

Slide 39 text

Examples int day, month, year; printf("Enter day, month, and year: "); scanf("%d %d %d", &day, &month, &year); printf("Entered date is: %02d/%02d/%d\n", day, month, year);

Slide 40

Slide 40 text

Control Flow

Slide 41

Slide 41 text

If else int number = 10; if (number > 0) { printf("The number is positive.\n"); } else if (number < 0) { printf("The number is negative.\n"); } else { printf("The number is zero.\n"); }

Slide 42

Slide 42 text

switch char grade = 'B'; switch (grade) { case 'A': printf("Excellent!\n"); break; case 'B': case 'C': printf("Well done\n"); break; case 'D': printf("You passed\n"); break; case 'F': printf("Better try again\n"); break; default: printf("Invalid grade\n"); }

Slide 43

Slide 43 text

while int count = 5; while (count > 0) { printf("Count = %d\n", count); count--; }

Slide 44

Slide 44 text

for for (int i = 0; i < 5; i++) { printf("i = %d\n", i); }

Slide 45

Slide 45 text

do while int a = 5; do { printf("a = %d\n", a); a--; } while (a > 0);

Slide 46

Slide 46 text

Conditions • Conditions within if statements are evaluated as Boolean expressions where the integer zero (0) represents FALSE • Any non-zero value is treated as TRUE. • if(1) { .. }

Slide 47

Slide 47 text

Quick Start to Memory

Slide 48

Slide 48 text

RAM Type Storage Location Initialization Lifetime Scope Typical Use Cases Local Stack Not automatic Duration of function call Limited to the block where declared Temporary data within functions Global Data Segment (.data or .bss) Automatic (zero if uninitialized) Entire program duration Accessible from any part of the program Data needed across multiple functions or modules Static (within functions) Data Segment (.data or .bss) Automatic (zero if uninitialized) Entire program duration Limited to the function/block declared Preserving state between function calls Static (global) Data Segment (.data or .bss) Automatic (zero if uninitialized) Entire program duration Limited to the file where declared Module-wide private data Dynamic Heap Not automatic Controlled by programmer Controlled by pointers Flexible size data or when amount is unknown at compile time

Slide 49

Slide 49 text

Stack • Stack allocation is faster than heap allocation • Memory on the stack is automatically created when a function starts and cleaned up when the function exits • Best used for small data that will not need to be resized and for data whose lifetime is well-known and coincides with the scope of the block in which it is declared

Slide 50

Slide 50 text

Heap • The heap is a more loosely managed pool of memory where blocks of memory are dynamically allocated and freed, often in an arbitrary order. • The heap can grow dynamically and is generally limited by the size of the virtual memory in the operating system. • Heap allocation involves more complex management, which can include searching for a block of free memory of adequate size, which makes it slower compared to stack allocation • The lifetime of heap variables is controlled by the programmer

Slide 51

Slide 51 text

Stack #include void function() { int stackVar = 10; // Local variable allocated on the stack printf("Stack variable value: %d\n", stackVar); } int main() { function(); return 0; }

Slide 52

Slide 52 text

Pointers and references #include #include int main() { int a = 5; printf("Address of a is %p\n", &a); int *memoryAddressOfA = &a; printf("Address is a is %p\n", memoryAddressOfA); // let's change a *memoryAddressOfA = 6; printf("Value of a is %d\n", a); return 0; }

Slide 53

Slide 53 text

Heap #include #include int main() { int *heapVar = malloc(sizeof(int)); // Allocate memory on the heap printf("Address is %p\n", heapVar); printf("Value is %d\n", *heapVar); *heapVar = 20; // Assign value to allocated memory printf("Heap variable value: %d\n", *heapVar); free(heapVar); // Free the allocated memory heapVar = NULL; // Good practice to set pointer to NULL after freeing return 0; }

Slide 54

Slide 54 text

Memory Leak #include #include int main() { if(1) { int *heapVar = malloc(sizeof(int)); // Allocate memory on the heap printf("Address is %p\n", heapVar); printf("Value is %d\n", *heapVar); *heapVar = 20; // Assign value to allocated memory printf("Heap variable value: %d\n", *heapVar); } // free(heapVar); // Free the allocated memory // heapVar = NULL; // Good practice to set pointer to NULL after freeing return 0; }

Slide 55

Slide 55 text

Fix #include #include int main() { int *heapVar = NULL; // Declare heapVar outside the if block if(1) { heapVar = malloc(sizeof(int)); // Allocate memory on the heap printf("Address is %p\n", heapVar); *heapVar = 20; // Assign value to allocated memory printf("Value is %d\n", *heapVar); printf("Heap variable value: %d\n", *heapVar); } // Free the allocated memory outside the if block if (heapVar != NULL) { free(heapVar); heapVar = NULL; // Good practice to set pointer to NULL after freeing } return 0; }

Slide 56

Slide 56 text

Arrays

Slide 57

Slide 57 text

Arrays • Arrays in C are fundamental data structures that consist of elements of the same data type placed contiguously in memory

Slide 58

Slide 58 text

Array in Stack #include int main() { int arr[5] = {1, 2, 3, 4, 5}; // Array declared on the stack int i; // Loop variable also on the stack printf("Array elements are: "); for (i = 0; i < 5; i++) { printf("%d ", arr[i]); } printf("\n"); return 0; }

Slide 59

Slide 59 text

Array in Heap #include #include // Include for malloc and free functions int main() { int size = 5; int *arr = malloc(size * sizeof(int)); // Dynamically allocate memory for the array on the heap // Initialize array elements for (int i = 0; i < size; i++) { arr[i] = i + 1; // Assign values to the array } printf("Array elements are: "); for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); free(arr); // Free the allocated memory arr = NULL; // Set pointer to NULL to avoid dangling pointer return 0; }

Slide 60

Slide 60 text

Dynamic array in heap #include #include // Include for malloc and free functions int main() { int size; // Ask user for the size of the array printf("Enter the size of the array: "); scanf("%d", &size); int *arr = malloc(size * sizeof(int)); // Dynamically allocate memory for the array on the heap // Initialize array elements for (int i = 0; i < size; i++) { arr[i] = i + 1; // Assign values to the array } printf("Array elements are: "); for (int i = 0; i < size; i++) { printf("%d ", arr[i]); } printf("\n"); free(arr); // Free the allocated memory arr = NULL; // Set pointer to NULL to avoid dangling pointer return 0; }

Slide 61

Slide 61 text

Pointers with Arrays #include #include int main() { // Allocate memory for three integers int *numbers = malloc(3 * sizeof(int)); // Initialize the integers using pointer arithmetic *numbers = 1; // Equivalent to numbers[0] = 1 *(numbers + 1) = 2; // Equivalent to numbers[1] = 2 *(numbers + 2) = 3; // Equivalent to numbers[2] = 3 // Print the integers using pointer arithmetic printf("First integer: %d\n", *numbers); // Outputs 1 printf("Second integer: %d\n", *(numbers + 1)); // Outputs 2 printf("Third integer: %d\n", *(numbers + 2)); // Outputs 3 // Free the allocated memory free(numbers); numbers = NULL; // Good practice to set pointer to NULL after freeing return 0; }

Slide 62

Slide 62 text

Char Array

Slide 63

Slide 63 text

Char arrays • String: char array that ends with '\0' • Declaration • char str1[6] = "hello"; // Array size is 6, including the null terminator • Accessing • char firstChar = str1[0]; • Output • printf("%s\n", str1); // Output the string • Input • scanf("%s", str2); // Read a string into str2 (unsafe, prefer fgets)

Slide 64

Slide 64 text

Avoid scanf • Using scanf to read strings into character arrays can be problematic due to its potential to cause buffer overflow • Buffer overflow occurs when the data written to a buffer exceeds its storage capacity, which can lead to undefined behavior, program crashes, or security vulnerabilities. • Example • char name[10]; • printf("Enter your name: "); • scanf("%s", name); // Unsafe: does not limit input size

Slide 65

Slide 65 text

fgets #include int main() { char name[10]; printf("Enter your name: "); fgets(name, sizeof(name), stdin); // Safe: input size is limited // Remove potential newline character name[strcspn(name, "\n")] = 0; printf("Hello, %s!\n", name); return 0; }

Slide 66

Slide 66 text

strcspn, strlen, strcat #include #include int main() { char str[20]; printf("Enter a string: "); fgets(str, sizeof(str), stdin); // Read string with space handling // Replace \n with \0. \0 marks the end of the string int index = strcspn(str, "\n"); str[index] = '\0'; printf("You entered: %s\n", str); // String manipulation int len = strlen(str); printf("String length: %d\n", len); strcat(str, " World"); printf("String after concatenation: %s\n", str); return 0; }

Slide 67

Slide 67 text

Dynamic Char Array #include #include int main() { int size = 256; // Define the maximum size of the input char *str = malloc(size); // Dynamically allocate memory for the string printf("Enter a string: "); fgets(str, size, stdin) // Remove the newline character if present str[strcspn(str, "\n")] = '\0'; printf("You entered: %s\n", str); free(str); // Free the allocated memory return 0; }

Slide 68

Slide 68 text

Functions

Slide 69

Slide 69 text

Functions • Functions are blocks of code that perform a specific task • Help you organize your programs by dividing them into smaller, manageable, and reusable parts • Using functions can make your code more modular, easier to maintain, and more readable.

Slide 70

Slide 70 text

Basic Structure • Return Type: • Specifies what type of data the function will return. It can be any data type such as int, char, void, etc. A void return type means the function does not return a value. • Function Name: • The identifier by which the function can be called in other parts of the program. • Parameters (Optional): • Variables that accept values passed into the function. These parameters act as local variables within the function. • Function Body: • The block of code that defines what the function does. It includes a series of statements enclosed in curly braces {}. • Return Statement (Conditional): • This statement is used to return a value from the function. It is required if the function declares a return type other than void.

Slide 71

Slide 71 text

Example #include // Function declaration int multiply(int x, int y); int main() { int result = multiply(10, 5); printf("Result: %d\n", result); return 0; } // Function definition int multiply(int x, int y) { return x * y; // Return the product of x and y }

Slide 72

Slide 72 text

#include #include void output(char character, int amount) { for(int i=0; i

Slide 73

Slide 73 text

#include #include #define WALL_CHAR 'x' #define SPACE_CHAR ' ' void output(char character, int amount) { for (int i = 0; i < amount; i++) { putchar(character); } } void printRow(int width, int isBorder) { if (isBorder) { output(WALL_CHAR, width); } else { output(WALL_CHAR, 1); output(SPACE_CHAR, width - 2); output(WALL_CHAR, 1); } putchar('\n'); } int main() { int height; printf("Enter height: "); if (scanf("%d", &height) != 1 || height <= 0) { printf("Invalid input. Please enter a positive integer.\n"); return 1; } for (int row = 0; row < height; row++) { printRow(height, row == 0 || row == height - 1); } return 0; } Preprocessor commands for creating constant values putchar is easier function for outputting only one char

Slide 74

Slide 74 text

Structs

Slide 75

Slide 75 text

Structs • Structs in C programming are composite data types that allow you to encapsulate multiple data items of potentially different types into a single cohesive unit. • Composite Type: • A struct (short for "structure") is a user-defined data type in C that groups together different data items (called members) under a single name. • Encapsulation: • Structs help in encapsulating related data items, making it easier to manage and organize data in complex programs.

Slide 76

Slide 76 text

Example struct Person { char name[50]; int age; float height; }; struct Person person1 = {"John Doe", 30, 5.75};

Slide 77

Slide 77 text

Example struct Person person1; strcpy(person1.name, "Alice"); person1.age = 28; struct Person *ptr = &person1; printf("Name: %s, Age: %d", ptr->name, ptr- >age);

Slide 78

Slide 78 text

Example struct Person { char name[50]; int age; float height; }; struct Person person1 = {"John Doe", 30, 5.75};

Slide 79

Slide 79 text

Example struct Person *p = malloc(sizeof(struct Person)); if (p != NULL) { strcpy(p->name, "Bob"); p->age = 40; }

Slide 80

Slide 80 text

C++

Slide 81

Slide 81 text

Origin and History • Developed by Bjarne Stroustrup in 1979 • Extension of C with object-oriented features • Standardized by ISO in 1998 (C++98) with several updates (C++03, C++11, C++14, C++17, C++20)

Slide 82

Slide 82 text

Key Features • Object-oriented programming • Standard Template Library (STL) • Function overloading and templates

Slide 83

Slide 83 text

Syntax and Structure • Similarities with C • Basic syntax: statements, expressions, control structures (if, for, while) • Primitive data types: int, char, float, double • Functions and pointers • Differences from C • Classes and objects • Access specifiers: public, private, protected • Constructors and destructors • Inline functions

Slide 84

Slide 84 text

Hello World: hello.cpp #include int main() { std::cout << "Hello, World!" << std::endl; return 0; }

Slide 85

Slide 85 text

Compile and Run use g++ instead of gcc

Slide 86

Slide 86 text

Datatypes

Slide 87

Slide 87 text

Fundamental Data Types • int: Integer type • char: Character type • float: Single precision floating-point type • double: Double precision floating-point type • bool: Boolean type (true/false)

Slide 88

Slide 88 text

Derived Datatypes • Arrays • Pointers • References

Slide 89

Slide 89 text

User-defined Datatypes • Structures (struct) • Enumerations (enum) • Classes (class)

Slide 90

Slide 90 text

Namespaces

Slide 91

Slide 91 text

Namespaces • Avoid name collisions • Organize code into logical groups

Slide 92

Slide 92 text

Header files • Declarations: • Header files are used to declare the interfaces to your code, including functions, classes, constants, and macros. • Inclusions: • They are included in other files using the #include directive to share declarations across multiple source files without redefining them.

Slide 93

Slide 93 text

mymath.h #ifndef MYMATH_H #define MYMATH_H namespace mymath { int max(int a, int b); } #endif rPevents multiple inclusions of the same header file using

Slide 94

Slide 94 text

Source files: .cpp • Provides the body of the functions declared in the header files. • Class Method Definitions: Implements the methods of the classes declared in the header files. • Local Functions: Defines any additional functions that are not exposed to other parts of the program.

Slide 95

Slide 95 text

mymath.cpp #include "mymath.h" namespace mymath { int max(int a, int b) { return a > b ? a : b; } } Ensure that header file is consistant with cpp file

Slide 96

Slide 96 text

main.cpp #include #include "mymath.h" int main() { std::cout << "Hello, World!" << std::endl; std::cout << mymath::max(5, 5) << std::endl; return 0; }

Slide 97

Slide 97 text

Namespaces #include #include "mymath1.h" #include "mymath2.h" int main() { std::cout << mymath1::max(5, 5) << std::endl; std::cout << mymath2::max(5, 5) << std::endl; return 0; } Possible to have max – method in two different namespaces, no name collisions

Slide 98

Slide 98 text

Basic Input and Output

Slide 99

Slide 99 text

IOStream • Including the iostream Library • Output with cout • std::cout << "Hello, World!" << std::endl; • Input with cin • int age; • std::cout << "Enter your age: "; • std::cin >> age;

Slide 100

Slide 100 text

Functions in C++

Slide 101

Slide 101 text

Function in C++ • A function is a block of code that performs a specific task. • Functions help in code reusability and modularity. • Function • int add(int a, int b) { • return a + b; • }

Slide 102

Slide 102 text

Function Overloading • Function overloading allows multiple functions to have the same name with different parameters. • It helps improve code readability and usability. • Functions must differ in the type or number of parameters. • Return type alone is not sufficient to overload a function.

Slide 103

Slide 103 text

Example int add(int a, int b) { return a + b; } double add(double a, double b) { return a + b; }

Slide 104

Slide 104 text

Default parameters void display(int a, int b = 10) { std::cout << "a: " << a << ", b: " << b << std::endl; } display(5); // Output: a: 5, b: 10 display(5, 20); // Output: a: 5, b: 20

Slide 105

Slide 105 text

Example void greet(std::string name = "Guest") { std::cout << "Hello, " << name << "!" << std::endl; } void greet(std::string name, std::string title) { std::cout << "Hello, " << title << " " << name << "!" << std::endl; } greet(); // Output: Hello, Guest! greet("Alice"); // Output: Hello, Alice! greet("Alice", "Dr."); // Output: Hello, Dr. Alice!

Slide 106

Slide 106 text

C++ OO

Slide 107

Slide 107 text

Key Concepts of OOP • Classes and Objects • Encapsulation • Inheritance • Polymorphism

Slide 108

Slide 108 text

Classes and Objects // Class definition class Animal { public: void eat() { std::cout << "I can eat!" << std::endl; } }; // Creating an object int main() { Animal animal1; animal1.eat(); // Output: I can eat! return 0; }

Slide 109

Slide 109 text

class Student { private: std::string name; int age; public: // Setter for name void setName(std::string n) { name = n; } // Getter for name std::string getName() { return name; } // Setter for age void setAge(int a) { age = a; } // Getter for age int getAge() { return age; } }; int main() { Student student1; student1.setName("Alice"); student1.setAge(20); std::cout << "Name: " << student1.getName() << std::endl; std::cout << "Age: " << student1.getAge() << std::endl; return 0; }

Slide 110

Slide 110 text

Inheritance // Base class class Animal { public: void eat() { std::cout << "I can eat!" << std::endl; } }; // Derived class class Dog : public Animal { public: void bark() { std::cout << "I can bark!" << std::endl; } }; int main() { Dog dog1; dog1.eat(); // Output: I can eat! dog1.bark(); // Output: I can bark! return 0; }

Slide 111

Slide 111 text

Polymorphism // Base class class Shape { public: virtual void draw() { std::cout << "Drawing Shape" << std::endl; } }; // Derived class class Circle : public Shape { public: void draw() override { std::cout << "Drawing Circle" << std::endl; } }; int main() { Shape* shape1 = new Shape(); Shape* shape2 = new Circle(); shape1->draw(); // Output: Drawing Shape shape2->draw(); // Output: Drawing Circle delete shape1; delete shape2; return 0; }

Slide 112

Slide 112 text

Abstract class // Base class class Shape { public: virtual void draw() = 0; }; // Derived class class Circle : public Shape { public: void draw() override { std::cout << "Drawing Circle" << std::endl; } }; int main() { Shape* shape1 = new Shape(); Shape* shape2 = new Circle(); shape1->draw(); // Output: Drawing Shape shape2->draw(); // Output: Drawing Circle delete shape1; delete shape2; return 0; }

Slide 113

Slide 113 text

Dynamic Memory Handling

Slide 114

Slide 114 text

Using heap with int #include int main() { // Step 1: Allocate memory on the heap int* ptr = new int; // Step 2: Assign a value to the allocated memory *ptr = 42; // Step 3: Use the allocated memory std::cout << "Value: " << *ptr << std::endl; // Step 4: Deallocate the memory delete ptr; ptr = nullptr; // Avoid dangling pointer return 0; }

Slide 115

Slide 115 text

Memory leak #include int main() { // Step 1: Allocate memory on the heap int* ptr = nullptr; if (true) { // The condition is always true, but it could be any condition ptr = new int; // Step 2: Assign a value to the allocated memory *ptr = 42; // Step 3: Use the allocated memory std::cout << "Value: " << *ptr << std::endl; // Memory leak here: No delete statement to deallocate the memory // The allocated memory is never freed } // Outside the if block, there is no delete statement // ptr still points to the allocated memory but it's not deallocated return 0; }

Slide 116

Slide 116 text

Templates

Slide 117

Slide 117 text

Templates • Templates in C++ are a powerful feature that allows for generic programming. • Enable functions and classes to operate with any data type without being rewritten for each type • There are two basic main types of templates • function templates • class templates

Slide 118

Slide 118 text

Function Template #include // Function template template T add(T a, T b) { return a + b; } int main() { int intResult = add(3, 4); // T is int double doubleResult = add(2.5, 3.1); // T is double std::cout << "intResult: " << intResult << std::endl; // Outputs: intResult: 7 std::cout << "doubleResult: " << doubleResult << std::endl; // Outputs: doubleResult: 5.6 return 0; }

Slide 119

Slide 119 text

Class Template #include // Class template template class Container { private: T value; public: Container(T val) : value(val) {} void setValue(T val) { value = val; } T getValue() { return value; } }; int main() { Container intContainer(42); // T is int Container doubleContainer(3.14); // T is double std::cout << "intContainer: " << intContainer.getValue() << std::endl; // Outputs: intContainer: 42 std::cout << "doubleContainer: " << doubleContainer.getValue() << std::endl; // Outputs: doubleContainer: 3.14 return 0; }

Slide 120

Slide 120 text

#include #include int main() { // Create a list of integers on the heap std::list* myList = new std::list; // Insert elements into the list myList->push_back(10); // Add 10 to the end myList->push_back(20); // Add 20 to the end myList->push_back(30); // Add 30 to the end // Print the list elements std::cout << "List elements: "; for (int value : *myList) { std::cout << value << " "; } std::cout << std::endl; // Insert at the front myList->push_front(5); // Add 5 to the front // Print the list elements again std::cout << "List elements after push_front: "; for (int value : *myList) { std::cout << value << " "; } std::cout << std::endl; // Delete an element by value myList->remove(20); // Remove 20 from the list // Print the list elements again std::cout << "List elements after removal: "; for (int value : *myList) { std::cout << value << " "; } std::cout << std::endl; // Access the first and last elements std::cout << "First element: " << myList->front() << std::endl; std::cout << "Last element: " << myList->back() << std::endl; // Free the memory allocated for the list delete myList; return 0; } // g++ -std=c++11 *.cpp -o myapp

Slide 121

Slide 121 text

Modern Features

Slide 122

Slide 122 text

auto type #include #include int main() { auto x = 5; // int auto y = 3.14; // double auto str = "Hello"; // const char* std::vector vec = {1, 2, 3, 4, 5}; for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; return 0; }

Slide 123

Slide 123 text

range #include #include int main() { std::vector vec = {1, 2, 3, 4, 5}; for (int value : vec) { std::cout << value << " "; } std::cout << std::endl; return 0; }

Slide 124

Slide 124 text

Smart Pointers • unique_ptr represents unique ownership of a resource. • Only one unique_ptr can own a resource at a time • When the unique_ptr goes out of scope, it automatically deletes the resource. • shared_ptr allows multiple pointers to share ownership of a resource. • The resource is deleted when the last shared_ptr owning it is destroyed.

Slide 125

Slide 125 text

Problem #include int main() { if (true) { int* ptr = new int(10); // Allocate memory on the heap std::cout << "Value: " << *ptr << std::endl; // Forgetting to delete the allocated memory } // Memory allocated inside the if block is not freed, causing a memory leak return 0; }

Slide 126

Slide 126 text

Fix: g++ -std=c++14 *.cpp -o myapp #include #include int main() { if (true) { std::unique_ptr ptr = std::make_unique(10); // Allocate memory on the heap using unique_ptr std::cout << "Value: " << *ptr << std::endl; // No need to manually delete, unique_ptr automatically deletes the memory when it goes out of scope } // Memory allocated inside the if block is automatically freed when the unique_ptr goes out of scope return 0; }

Slide 127

Slide 127 text

shared_ptr #include #include // For shared_ptr class MyClass { public: MyClass(int value) : value(value) { std::cout << "MyClass constructor called with value: " << value << std::endl; } ~MyClass() { std::cout << "MyClass destructor called for value: " << value << std::endl; } int getValue() const { return value; } private: int value; }; int main() { std::shared_ptr ptr1 = std::make_shared(42); if(true) { std::shared_ptr ptr2 = ptr1; std::cout << "Value through ptr2: " << ptr2->getValue() << std::endl; std::cout << "Reference count: " << ptr1.use_count() << std::endl; } std::cout << "Value through ptr1: " << ptr1->getValue() << std::endl; std::cout << "Reference count: " << ptr1.use_count() << std::endl; return 0; }

Slide 128

Slide 128 text

Lambdas • An anonymous function that can capture variables from its surrounding scope. • Basic Syntax: • [ capture ] ( params ) -> ret { body } • Capture Clause ([]): Specifies which variables from the surrounding scope are captured and how. • Parameter List (( params )): Defines the parameters the lambda takes. • Return Type (-> ret) (optional): Specifies the return type. If omitted, the compiler deduces it. • Body ({ body }): Contains the code to be executed when the lambda is called.

Slide 129

Slide 129 text

Example #include #include int main() { // Define the lambda function with std::function std::function add = [](int a, int b) -> int { return a + b; }; // Use the lambda function to add two numbers int sum = add(5, 3); // Print the result std::cout << "The sum of 5 and 3 is: " << sum << std::endl; return 0; }

Slide 130

Slide 130 text

Using auto #include int main() { // Define the lambda function auto add = [](int a, int b) -> int { return a + b; }; // Use the lambda function to add two numbers int sum = add(5, 3); // Print the result std::cout << "The sum of 5 and 3 is: " << sum << std::endl; return 0; }

Slide 131

Slide 131 text

Using callbacks #include #include // Function that takes two integers and a callback function void performOperation(int a, int b, const std::function& callback) { // Call the callback function with the provided integers int result = callback(a, b); // Print the result std::cout << "The result of the operation is: " << result << std::endl; } int main() { // Define the lambda function for summing two numbers auto sum = [](int a, int b) -> int { return a + b; }; // Define the lambda function for subtracting two numbers auto extract = [](int a, int b) -> int { return a - b; }; // Use the lambda function for summing as a callback performOperation(5, 3, sum); // Should print "The result of the operation is: 8" // Use the lambda function for extracting as a callback performOperation(5, 3, extract); // Should print "The result of the operation is: 2" return 0; }

Slide 132

Slide 132 text

Using callbacks with anonymous lambdas #include #include // Function that takes two integers and a callback function void performOperation(int a, int b, const std::function& callback) { // Call the callback function with the provided integers int result = callback(a, b); // Print the result std::cout << "The result of the operation is: " << result << std::endl; } int main() { // Use an anonymous lambda function for summing as a callback performOperation(5, 3, [](int a, int b) -> int { return a + b; }); // Should print "The result of the operation is: 8" // Use an anonymous lambda function for subtracting as a callback performOperation(5, 3, [](int a, int b) -> int { return a - b; }); // Should print "The result of the operation is: 2" return 0; }

Slide 133

Slide 133 text

#include #include #include #include #include // Function that reads a file in a different thread and invokes the callback with the file content void fileRead(const std::string& filePath, std::function callback) { // Create a thread to read the file std::thread([filePath, callback]() { std::ifstream inputFile(filePath); if (!inputFile) { std::cerr << "Unable to open file: " << filePath << std::endl; return; } std::string content; std::string line; while (std::getline(inputFile, line)) { content += line + '\n'; } inputFile.close(); // Invoke the callback with the file content callback(content); }).detach(); } int main() { // Example usage of fileRead function fileRead("path/to/foo.txt", [](const std::string& content) { std::cout << "File content:\n" << content << std::endl; }); // Prevent main from exiting immediately std::this_thread::sleep_for(std::chrono::seconds(2)); // Adjust time as needed for file reading to complete return 0; } allows the thread to run independently from the std::thread object that originally represented it. After calling detach, the thread becomes a daemon thread