Wissensspeicher 5

Alt

  • Zeiger (oder das Tor zur Hölle 😈) - int *k = 0x4711;
  • Zeiger sind 

    • selbst Variablen deren GrĂ¶ĂŸe sich nach der Architektur richtet; nicht nach dem Datentyp auf den sie zeigen
    • können beliebige Adressen enthalten und greifen dort auf Speicher zu 🚹
    • verĂ€nderbar: siehe Zeigerarithmetik

Neu

  • Dynamische Speicherverwaltung
    • Zur Laufzeit Speicher beliebiger GrĂ¶ĂŸe anfordern
    • Betriebssystem liefert Zeiger auf den Anfang des Bereichs
    • Wichtig: FĂŒr jede Allokation muss es genau eine Freigabe geben
    • Operationen: new/new[] und delete/delete[]

Live-Demo - Speicherlayout

#include <iostream>
#include <iomanip>
using namespace std;

int main() {
    constexpr int len = 10;
	int statArr[len] = {0};
	int *dynArr = NULL;

	cout << "Stack" << endl;
	cout << "----------" << endl;
	for (int i = len - 1; i >= 0; i--) {
		cout << "&statArr[" << setfill('0') << setw(3) << dec << i << "] = " << hex << &statArr[i] << endl;
	}
	cout << "----------" << endl;

	dynArr = new int[len];
	cout << "Heap" << endl;
	cout << "----------" << endl;
	for (int i = len - 1; i >= 0; i--) {
		cout << " &dynArr[" << setfill('0') << setw(3) << dec << i << "] = " << hex << &dynArr[i] << endl;
	}
	cout << "----------" << endl;
	delete[] dynArr;
}
compiler
gen/memory-layout-stack-heap-crop.svg

Zeiger-Zeiger - Live-Demo

#include <iostream>
#include <iomanip>
using namespace std;

static void gebeArrayAus(int *arr, int n) {
	cout << "----------" << endl;
	for (int i = 0; i < n; i++) {
		cout << "statArr[" << setfill('0') << setw(3) << i << "] = " << setfill(' ') << setw(3) << dec << arr[i];
		cout << ", &statArr[" << setfill('0') << setw(3) << dec << i << "] = " << hex << &arr[i] << endl;
	}
	cout << "----------" << endl;
}

int main(void) {
	constexpr int len = 10;
	int statArr[len] = {0};

	int *pStatArr = NULL;
	int **ppStatArr = NULL;

	gebeArrayAus(statArr, len);

	pStatArr = &statArr[3];
	ppStatArr = &pStatArr;
	**ppStatArr = 21;

	cout << "\n   pStatArr = &statArr[3];" << endl;
	cout << "  ppStatArr = &pStatArr;" << endl;
	cout << "**ppStatArr = 21;" << endl;
	cout << "&pStatArr = " << hex << &pStatArr << ",   pStatArr = " << hex << *ppStatArr << ",   *pStatArr = " << dec << **ppStatArr << endl;
	cout << "ppStatArr = " << hex << ppStatArr << ", *ppStatArr = " << hex << *ppStatArr << ", **ppStatArr = " << dec << **ppStatArr  << endl;
	cout << "\n----------\n" << endl;

	*ppStatArr = *ppStatArr + 4;
	**ppStatArr = 42;
	cout << " *ppStatArr = *ppStatArr + 4;" << endl;
	cout << "**ppStatArr = 42;" << endl;
	cout << "&pStatArr = " << hex << &pStatArr << ",   pStatArr = " << hex << *ppStatArr << ",   *pStatArr = " << dec << **ppStatArr << endl;
	cout << "ppStatArr = " << hex << ppStatArr << ", *ppStatArr = " << hex << *ppStatArr << ", **ppStatArr = " << dec << **ppStatArr << "\n" << endl;
	
	gebeArrayAus(statArr, len);

	return 0;
}
compiler

Zeiger-Zeiger - ErklÀrung

constexpr int len = 10;
int statArr[len] = {0};

int *pStatArr = NULL;
int **ppStatArr = NULL;
gen/memory-layout-pointer-01.svg

Zeiger-Zeiger - ErklÀrung

constexpr int len = 10;
int statArr[len] = {0};

int *pStatArr = NULL;
int **ppStatArr = NULL;

pStatArr = &statArr[3];
gen/memory-layout-pointer-02.svg

Zeiger-Zeiger - ErklÀrung

constexpr int len = 10;
int statArr[len] = {0};

int *pStatArr = NULL;
int **ppStatArr = NULL;

pStatArr = &statArr[3];
ppStatArr = &pStatArr;
gen/memory-layout-pointer-03.svg

Zeiger-Zeiger - ErklÀrung

constexpr int len = 10;
int statArr[len] = {0};

int *pStatArr = NULL;
int **ppStatArr = NULL;

pStatArr = &statArr[3];
ppStatArr = &pStatArr;
**ppStatArr = 21;
gen/memory-layout-pointer-04.svg

Zeiger-Zeiger - ErklÀrung

constexpr int len = 10;
int statArr[len] = {0};

int *pStatArr = NULL;
int **ppStatArr = NULL;

pStatArr = &statArr[3];
ppStatArr = &pStatArr;
**ppStatArr = 21;

*ppStatArr = *ppStatArr + 4;
**ppStatArr = 42;
gen/memory-layout-pointer-04.svg

Zeiger-Zeiger - ErklÀrung

constexpr int len = 10;
int statArr[len] = {0};

int *pStatArr = NULL;
int **ppStatArr = NULL;

pStatArr = &statArr[3];
ppStatArr = &pStatArr;
**ppStatArr = 21;

*ppStatArr = *ppStatArr + 4;
**ppStatArr = 42;
gen/memory-layout-pointer-05.svg

pages/Kapitel05-page-01.svg

pages/Kapitel05-page-02.svg

pages/Kapitel05-page-03.svg

pages/Kapitel05-page-04.svg

pages/Kapitel05-page-05.svg

pages/Kapitel05-page-06.svg

pages/Kapitel05-page-07.svg

pages/Kapitel05-page-08.svg

pages/Kapitel05-page-09.svg

pages/Kapitel05-page-10.svg

pages/Kapitel05-page-11.svg

pages/Kapitel05-page-12.svg

pages/Kapitel05-page-13.svg

pages/Kapitel05-page-14.svg

pages/Kapitel05-page-15.svg

pages/Kapitel05-page-16.svg

pages/Kapitel05-page-17.svg

pages/Kapitel05-page-18.svg

pages/Kapitel05-page-19.svg

pages/Kapitel05-page-20.svg

pages/Kapitel05-page-21.svg

pages/Kapitel05-page-22.svg

pages/Kapitel05-page-23.svg

pages/Kapitel05-page-24.svg

pages/Kapitel05-page-25.svg

pages/Kapitel05-page-26.svg

pages/Kapitel05-page-27.svg

pages/Kapitel05-page-28.svg

pages/Kapitel05-page-29.svg

pages/Kapitel05-page-30.svg

pages/Kapitel05-page-31.svg

pages/Kapitel05-page-32.svg

pages/Kapitel05-page-33.svg

pages/Kapitel05-page-34.svg

pages/Kapitel05-page-35.svg

pages/Kapitel05-page-36.svg

Live-Demo - Funktionen

#include <iostream>

using namespace std;

void zeichne_10_sterne();

int main(void) {
    zeichne_10_sterne();
    zeichne_10_sterne();
    zeichne_10_sterne();

	return 0;
}

void zeichne_10_sterne() {
    int k = 10;
    while (k--){
        cout << '*';
    }
    cout << endl;
}
compiler

pages/Kapitel05-page-37.svg

pages/Kapitel05-page-38.svg

pages/Kapitel05-page-39.svg

pages/Kapitel05-page-40.svg

pages/Kapitel05-page-41.svg

pages/Kapitel05-page-42.svg

pages/Kapitel05-page-43.svg

pages/Kapitel05-page-44.svg

pages/Kapitel05-page-45.svg

pages/Kapitel05-page-46.svg

Live-Demo - Funktionen mit Parameter

#include <iostream>

using namespace std;

void zeichne_sterne(int k) {
    while (k--) std::cout << '*';
    std::cout << std::endl;
}

void zeichne_10_sterne() {
   zeichne_sterne(10); 
}

int main(void) {
    zeichne_sterne(10);
    zeichne_10_sterne();

	return 0;
}
compiler

pages/Kapitel05-page-47.svg

pages/Kapitel05-page-48.svg

pages/Kapitel05-page-49.svg

pages/Kapitel05-page-50.svg

pages/Kapitel05-page-51.svg

pages/Kapitel05-page-52.svg

pages/Kapitel05-page-53.svg

pages/Kapitel05-page-54.svg

pages/Kapitel05-page-55.svg

pages/Kapitel05-page-56.svg

pages/Kapitel05-page-57.svg

pages/Kapitel05-page-58.svg

pages/Kapitel05-page-59.svg

pages/Kapitel05-page-60.svg

pages/Kapitel05-page-61.svg

pages/Kapitel05-page-62.svg

Live-Demo - Funktionen mit mehreren Parametern

#include <iostream>

using namespace std;

void zeichnen(int k, char c){
    // zeichne k mal das Zeichen c
    while (k--) std::cout << c;
    std::cout << std::endl;
}

int main(void) {
    for (int i = 0; i < 26; ++i){
        zeichnen(i+1, 'A'+i);
    }

	return 0;
}
compiler

pages/Kapitel05-page-63.svg

pages/Kapitel05-page-64.svg

pages/Kapitel05-page-65.svg

pages/Kapitel05-page-66.svg

pages/Kapitel05-page-67.svg

pages/Kapitel05-page-68.svg

pages/Kapitel05-page-69.svg

pages/Kapitel05-page-70.svg

pages/Kapitel05-page-71.svg

pages/Kapitel05-page-72.svg

pages/Kapitel05-page-73.svg

pages/Kapitel05-page-74.svg

pages/Kapitel05-page-75.svg

pages/Kapitel05-page-76.svg

pages/Kapitel05-page-77.svg

pages/Kapitel05-page-78.svg

pages/Kapitel05-page-79.svg

pages/Kapitel05-page-80.svg

pages/Kapitel05-page-81.svg

pages/Kapitel05-page-82.svg

pages/Kapitel05-page-83.svg

pages/Kapitel05-page-84.svg

pages/Kapitel05-page-85.svg

pages/Kapitel05-page-86.svg

pages/Kapitel05-page-87.svg

pages/Kapitel05-page-88.svg

pages/Kapitel05-page-89.svg

pages/Kapitel05-page-90.svg

pages/Kapitel05-page-91.svg

pages/Kapitel05-page-92.svg

pages/Kapitel05-page-93.svg

pages/Kapitel05-page-94.svg

pages/Kapitel05-page-95.svg

pages/Kapitel05-page-96.svg

pages/Kapitel05-page-97.svg

pages/Kapitel05-page-98.svg

pages/Kapitel05-page-99.svg

pages/Kapitel05-page-100.svg

pages/Kapitel05-page-101.svg

pages/Kapitel05-page-102.svg

pages/Kapitel05-page-103.svg

pages/Kapitel05-page-104.svg

pages/Kapitel05-page-105.svg

pages/Kapitel05-page-106.svg

pages/Kapitel05-page-107.svg

pages/Kapitel05-page-108.svg

pages/Kapitel05-page-109.svg

pages/Kapitel05-page-110.svg

pages/Kapitel05-page-111.svg

pages/Kapitel05-page-112.svg

pages/Kapitel05-page-113.svg

pages/Kapitel05-page-114.svg

pages/Kapitel05-page-115.svg

pages/Kapitel05-page-116.svg

pages/Kapitel05-page-117.svg

Live-Demo - ParameterĂŒbergabe 1

#include <iostream>

using namespace std;

void tausche_wert(int a, int b) {
    int h = a;
    a = b;
    b = h;
    cout << "Fkt.: " << a << " " << b << endl;
}

int main(void) {
    int a = 3, b = 11;
    cout << "main: " << a << " " << b << endl;
    tausche_wert(a, b);
    cout << "main: " << a << " " << b << endl;

	return 0;
}
compiler

pages/Kapitel05-page-118.svg

pages/Kapitel05-page-119.svg

pages/Kapitel05-page-120.svg

pages/Kapitel05-page-121.svg

pages/Kapitel05-page-122.svg

Live-Demo - ParameterĂŒbergabe als Zeiger

#include <iostream>

using namespace std;

void tausche_wert(int *pa, int *pb) {
    int h = *pa;
    *pa = *pb;
    *pb = h;
    cout << "Fkt.: " << *pa << " " << *pb << endl;
}

int main(void) {
    int a = 3, b = 11;
    cout << "main: " << a << " " << b << endl;
    tausche_wert(&a, &b);
    cout << "main: " << a << " " << b << endl;

	return 0;
}
compiler

pages/Kapitel05-page-123.svg

pages/Kapitel05-page-124.svg

pages/Kapitel05-page-125.svg

pages/Kapitel05-page-126.svg

pages/Kapitel05-page-127.svg

pages/Kapitel05-page-128.svg

pages/Kapitel05-page-129.svg

pages/Kapitel05-page-130.svg

pages/Kapitel05-page-131.svg

pages/Kapitel05-page-132.svg

pages/Kapitel05-page-133.svg

pages/Kapitel05-page-134.svg

pages/Kapitel05-page-135.svg

pages/Kapitel05-page-136.svg

pages/Kapitel05-page-137.svg

pages/Kapitel05-page-138.svg

pages/Kapitel05-page-139.svg

pages/Kapitel05-page-140.svg

pages/Kapitel05-page-141.svg

pages/Kapitel05-page-142.svg

pages/Kapitel05-page-143.svg

pages/Kapitel05-page-144.svg

Feedback erwĂŒnscht

Wissensspeicher 6

  • Funktionen
    • Kapselung von wiederkehrenden AblĂ€ufen
    • Erhöht Lesbarkeit und Wartbarkeit
  • Varianten
    • ohne Parameter(n) und ohne RĂŒckgabewert → ?
    • mit Parameter(n) und ohne RĂŒckgabewert → setprecision(int n)
    • mit Parameter(n) und mit RĂŒckgabewert → double sin(double x)
    • ohne Parameter(n) und mit RĂŒckgabewert → int rand(void)
  • Übergabe von Parametern und RĂŒckgabewerten als Kopie auf dem Stack (→ Call by value)

  • Übergabe von modifizierbaren Parametern mittels Zeigern (→ Call by reference)

    Technisch immer noch Call by value, aber jetzt werden die Adressen kopiert.

pages/Kapitel05-page-145.svg

pages/Kapitel05-page-146.svg

pages/Kapitel05-page-147.svg

pages/Kapitel05-page-148.svg

pages/Kapitel05-page-149.svg

pages/Kapitel05-page-150.svg

pages/Kapitel05-page-151.svg

pages/Kapitel05-page-152.svg

pages/Kapitel05-page-153.svg

pages/Kapitel05-page-154.svg

pages/Kapitel05-page-155.svg

pages/Kapitel05-page-156.svg

pages/Kapitel05-page-157.svg

pages/Kapitel05-page-158.svg

pages/Kapitel05-page-159.svg

pages/Kapitel05-page-160.svg

pages/Kapitel05-page-161.svg

pages/Kapitel05-page-162.svg

pages/Kapitel05-page-163.svg

pages/Kapitel05-page-164.svg

pages/Kapitel05-page-165.svg

pages/Kapitel05-page-166.svg

Live-Demo - ParameterĂŒbergabe als Referenzen

#include <iostream>

using namespace std;

void tausche_wert(int &a, int &b) {
    int h = a;
    a = b;
    b = h;
    cout << "Fkt.: " << a << " " << b << endl;
}

int main(void) {
    int a = 3, b = 11;
    cout << "main: " << a << " " << b << endl;
    tausche_wert(a, b);
    cout << "main: " << a << " " << b << endl;

	return 0;
}
compiler

pages/Kapitel05-page-167.svg

pages/Kapitel05-page-168.svg

pages/Kapitel05-page-169.svg

pages/Kapitel05-page-170.svg

pages/Kapitel05-page-171.svg

pages/Kapitel05-page-172.svg

pages/Kapitel05-page-173.svg

pages/Kapitel05-page-174.svg

pages/Kapitel05-page-175.svg

pages/Kapitel05-page-176.svg

pages/Kapitel05-page-177.svg

pages/Kapitel05-page-178.svg

pages/Kapitel05-page-179.svg

pages/Kapitel05-page-180.svg

pages/Kapitel05-page-181.svg

pages/Kapitel05-page-182.svg

pages/Kapitel05-page-183.svg

pages/Kapitel05-page-184.svg

pages/Kapitel05-page-185.svg

pages/Kapitel05-page-186.svg

pages/Kapitel05-page-187.svg

pages/Kapitel05-page-188.svg

pages/Kapitel05-page-189.svg

pages/Kapitel05-page-190.svg

pages/Kapitel05-page-191.svg

pages/Kapitel05-page-192.svg

pages/Kapitel05-page-193.svg

pages/Kapitel05-page-194.svg

pages/Kapitel05-page-195.svg

pages/Kapitel05-page-196.svg

pages/Kapitel05-page-197.svg

pages/Kapitel05-page-198.svg

pages/Kapitel05-page-199.svg

pages/Kapitel05-page-200.svg

pages/Kapitel05-page-201.svg

pages/Kapitel05-page-202.svg

pages/Kapitel05-page-203.svg

pages/Kapitel05-page-204.svg

pages/Kapitel05-page-205.svg

pages/Kapitel05-page-206.svg

pages/Kapitel05-page-207.svg

pages/Kapitel05-page-208.svg

pages/Kapitel05-page-209.svg

pages/Kapitel05-page-210.svg

pages/Kapitel05-page-211.svg

pages/Kapitel05-page-212.svg

pages/Kapitel05-page-213.svg

pages/Kapitel05-page-214.svg

pages/Kapitel05-page-215.svg

pages/Kapitel05-page-216.svg

pages/Kapitel05-page-217.svg

pages/Kapitel05-page-218.svg

pages/Kapitel05-page-219.svg

pages/Kapitel05-page-220.svg

pages/Kapitel05-page-221.svg

pages/Kapitel05-page-222.svg

pages/Kapitel05-page-223.svg

pages/Kapitel05-page-224.svg

pages/Kapitel05-page-225.svg

pages/Kapitel05-page-226.svg

pages/Kapitel05-page-227.svg

Live-Demo - Übergabe von Arrays

#include <iostream>

using namespace std;

void inkrement(int b[5]) {
    for (int k = 0; k < 5; k++) {
        b[k]++;
    }
    cout << "sizeof(b): " << sizeof(b) << endl;
}

int main(void) {
    int i, a[5] = {2, 4, 6, 8, 10};
    cout << "sizeof(a): " << sizeof(a) << endl;
    inkrement(a);
    for (int k = 0; k < 5; k++) {
        cout << a[k] << " ";
    }
    cout << endl;

	return 0;
}
compiler

pages/Kapitel05-page-228.svg

pages/Kapitel05-page-229.svg

pages/Kapitel05-page-230.svg

pages/Kapitel05-page-231.svg

Live-Demo - Übergabe von Arrays mit Bereichsgrenzen

#include <iostream>

using namespace std;

void inkrement(int b[], int const n) {
    for (int k = 0; k < n; k++) {
        b[k]++;
    }
}

int main(void) {
    int constexpr n = 5;
    int i, a[n] = {2, 4, 6, 8, 10};

    inkrement(a, n);
    for (int k = 0; k < n; k++) {
        cout << a[k] << " ";
    }
    cout << endl;

	return 0;
}
compiler

pages/Kapitel05-page-232.svg

pages/Kapitel05-page-233.svg

pages/Kapitel05-page-234.svg

pages/Kapitel05-page-235.svg

pages/Kapitel05-page-236.svg

pages/Kapitel05-page-237.svg

pages/Kapitel05-page-238.svg

pages/Kapitel05-page-239.svg

pages/Kapitel05-page-240.svg

pages/Kapitel05-page-241.svg

pages/Kapitel05-page-242.svg

pages/Kapitel05-page-243.svg

pages/Kapitel05-page-244.svg

pages/Kapitel05-page-245.svg

pages/Kapitel05-page-246.svg

pages/Kapitel05-page-247.svg

pages/Kapitel05-page-248.svg

pages/Kapitel05-page-249.svg

pages/Kapitel05-page-250.svg

pages/Kapitel05-page-251.svg

pages/Kapitel05-page-252.svg

pages/Kapitel05-page-253.svg

pages/Kapitel05-page-254.svg

pages/Kapitel05-page-255.svg

pages/Kapitel05-page-256.svg

pages/Kapitel05-page-257.svg

pages/Kapitel05-page-258.svg

pages/Kapitel05-page-259.svg

pages/Kapitel05-page-260.svg

pages/Kapitel05-page-261.svg

pages/Kapitel05-page-262.svg

pages/Kapitel05-page-263.svg

Live-Demo - Übergabe eines Vektors

#include <iostream>
#include <vector>

using namespace std;

void plusEinsAusgabe(vector<int> v) {
    for (int i = 0; i < v.size(); i++) {
        v[i]++;
        cout << v[i] << " ";
    }
    cout << endl;
}

int main(void) {
    vector<int> vec = {1,2,3,4,5};
    plusEinsAusgabe(vec);
    for (int i: vec) {
        cout << i << " ";
    }
    cout << endl;

	return 0;
}
compiler

pages/Kapitel05-page-264.svg

pages/Kapitel05-page-265.svg

pages/Kapitel05-page-266.svg

pages/Kapitel05-page-267.svg

pages/Kapitel05-page-268.svg

pages/Kapitel05-page-269.svg

pages/Kapitel05-page-270.svg

pages/Kapitel05-page-271.svg

pages/Kapitel05-page-272.svg

pages/Kapitel05-page-273.svg

pages/Kapitel05-page-274.svg

pages/Kapitel05-page-275.svg

pages/Kapitel05-page-276.svg

pages/Kapitel05-page-277.svg

pages/Kapitel05-page-278.svg

pages/Kapitel05-page-279.svg

pages/Kapitel05-page-280.svg

pages/Kapitel05-page-281.svg

pages/Kapitel05-page-282.svg

pages/Kapitel05-page-283.svg

pages/Kapitel05-page-284.svg

pages/Kapitel05-page-285.svg

pages/Kapitel05-page-286.svg

pages/Kapitel05-page-287.svg

pages/Kapitel05-page-288.svg

pages/Kapitel05-page-289.svg

pages/Kapitel05-page-290.svg

pages/Kapitel05-page-291.svg

Live-Demo - Funktionen mit Schablonen

#include <iostream>

using namespace std;

template <typename T>
T arrayMin(int const n, T a[]) {
    if (n == 0)
        return -1;
    T min = a[0];
    for (int i = 1; i < n; ++i) {
        if (a[i] < min) {
            min = a[i];
        }
    }
    return min;
}

int main() {
    double feld[] = {10.1, 9.9, 9.3, 10.5, 11.3, 12.0};
    short feld2[] = {10, 9, 3, 5, 11, 12};

    double min = arrayMin<double>(6, feld);
    short min2 = arrayMin<short>(6, feld2);

    cout << "double minimum: " << min << endl;
    cout << "short minimum: " << min2 << endl;
    return 0;
}
compiler

pages/Kapitel05-page-292.svg

pages/Kapitel05-page-293.svg

pages/Kapitel05-page-294.svg

pages/Kapitel05-page-295.svg

pages/Kapitel05-page-296.svg

pages/Kapitel05-page-297.svg

pages/Kapitel05-page-298.svg

pages/Kapitel05-page-299.svg

pages/Kapitel05-page-300.svg

pages/Kapitel05-page-301.svg

pages/Kapitel05-page-302.svg

pages/Kapitel05-page-303.svg

pages/Kapitel05-page-304.svg

pages/Kapitel05-page-305.svg

pages/Kapitel05-page-306.svg

pages/Kapitel05-page-307.svg

pages/Kapitel05-page-308.svg

Live-Demo - Schablonentyp automatisch ableiten

#include <iostream>

using namespace std;

template<typename T> T func(T a) {
    T result = a * 2;
    return result;
}

int main() {
    short s = func<short>(1024);
    float f = func<float>(1024);
    int   i = func<int>(1024);

    cout << "s = " << s << endl;
    cout << "f = " << f << endl;
    cout << "i = " << i << endl;

    return 0;
}
compiler

Wissensspeicher 7

  • Bisher: Zeiger verweisen auf beliebige Adressen
  • Jetzt: Referenzen
    • Ist wie ein Alias auf eine Variable zu sehen
    • Erlaubt Zugriff auf denselben Speicher wie bei einer Variablen
    • Kann den Inhalt verĂ€ndern
    • Alias wird bei der Initialisierung einmal festgelegt
  • Funktionsschablonen (function templates)
    • Deklaration mit template <typename T> T foo(T in);
    • Funktion einmal implementieren
    • Codegenerierung fĂŒr verschiedene Datentypen

pages/Kapitel05-page-309.svg

pages/Kapitel05-page-310.svg

pages/Kapitel05-page-311.svg

pages/Kapitel05-page-312.svg

pages/Kapitel05-page-313.svg

pages/Kapitel05-page-314.svg

pages/Kapitel05-page-315.svg

pages/Kapitel05-page-316.svg

pages/Kapitel05-page-317.svg

pages/Kapitel05-page-318.svg

pages/Kapitel05-page-319.svg

pages/Kapitel05-page-320.svg

Live-Demo - zweidimensoniale Arrays im Speicher

#include <iostream>

using namespace std;

int main(void) {
    constexpr int rows = 3, columns = 4;
    int arr[rows][columns] = {0};

    cout << "GrĂ¶ĂŸe einer Zeile: " << sizeof(arr[0]) << endl;
    cout << "Abstand zw. Zeile 1 und 2: ";
    cout << (reinterpret_cast<intptr_t>(&arr[2]) - reinterpret_cast<intptr_t>(&arr[1])) << endl;

	return 0;
}
compiler

pages/Kapitel05-page-321.svg

pages/Kapitel05-page-322.svg

pages/Kapitel05-page-323.svg

pages/Kapitel05-page-324.svg

pages/Kapitel05-page-325.svg

pages/Kapitel05-page-326.svg

pages/Kapitel05-page-327.svg

pages/Kapitel05-page-328.svg

pages/Kapitel05-page-329.svg

pages/Kapitel05-page-330.svg

pages/Kapitel05-page-331.svg

pages/Kapitel05-page-332.svg

pages/Kapitel05-page-333.svg

pages/Kapitel05-page-334.svg

pages/Kapitel05-page-335.svg

pages/Kapitel05-page-336.svg

pages/Kapitel05-page-337.svg

pages/Kapitel05-page-338.svg

pages/Kapitel05-page-339.svg

pages/Kapitel05-page-340.svg

pages/Kapitel05-page-341.svg

pages/Kapitel05-page-342.svg

pages/Kapitel05-page-343.svg

pages/Kapitel05-page-344.svg

pages/Kapitel05-page-345.svg

pages/Kapitel05-page-346.svg

pages/Kapitel05-page-347.svg

pages/Kapitel05-page-348.svg

pages/Kapitel05-page-349.svg

pages/Kapitel05-page-350.svg

pages/Kapitel05-page-351.svg

pages/Kapitel05-page-352.svg

pages/Kapitel05-page-353.svg

pages/Kapitel05-page-354.svg

pages/Kapitel05-page-355.svg

pages/Kapitel05-page-356.svg

pages/Kapitel05-page-357.svg

pages/Kapitel05-page-358.svg

pages/Kapitel05-page-359.svg

pages/Kapitel05-page-360.svg

pages/Kapitel05-page-361.svg

pages/Kapitel05-page-362.svg

pages/Kapitel05-page-363.svg

pages/Kapitel05-page-364.svg

pages/Kapitel05-page-365.svg

pages/Kapitel05-page-366.svg

pages/Kapitel05-page-367.svg

pages/Kapitel05-page-368.svg

pages/Kapitel05-page-369.svg

pages/Kapitel05-page-370.svg

pages/Kapitel05-page-371.svg

pages/Kapitel05-page-372.svg

pages/Kapitel05-page-373.svg

pages/Kapitel05-page-374.svg

pages/Kapitel05-page-375.svg

pages/Kapitel05-page-376.svg

pages/Kapitel05-page-377.svg

pages/Kapitel05-page-378.svg

pages/Kapitel05-page-379.svg

pages/Kapitel05-page-380.svg

pages/Kapitel05-page-381.svg

pages/Kapitel05-page-382.svg

Live-Demo - Uhrzeit

#include <iostream>
#include <ctime>

using namespace std;

int main(void) {
    time_t jetzt = time(nullptr);
    cout << jetzt << endl;

    struct tm *jetzt_lokal = localtime(&jetzt);
    char *uhrzeit = asctime(jetzt_lokal);
    cout << uhrzeit << endl;

	return 0;
}
compiler

pages/Kapitel05-page-383.svg

pages/Kapitel05-page-384.svg

pages/Kapitel05-page-385.svg

pages/Kapitel05-page-386.svg

pages/Kapitel05-page-387.svg

pages/Kapitel05-page-388.svg

pages/Kapitel05-page-389.svg

Live-Demo - Zeitmessung

#include <iostream>
#include <chrono>

using namespace std;
using namespace std::chrono;

int main(void) {
    time_point<steady_clock> jetzt = steady_clock::now();
    for (int i = 0; i < 10000000; i++) {}
    time_point<steady_clock> spaeter = steady_clock::now();

    duration<double> zeit = spaeter - jetzt;
    cout << "Zeit: " << zeit.count() << " sec." << endl;

	return 0;
}
compiler

pages/Kapitel05-page-390.svg

pages/Kapitel05-page-391.svg

pages/Kapitel05-page-392.svg

pages/Kapitel05-page-393.svg

pages/Kapitel05-page-394.svg

pages/Kapitel05-page-395.svg

pages/Kapitel05-page-396.svg

pages/Kapitel05-page-397.svg

pages/Kapitel05-page-398.svg

pages/Kapitel05-page-399.svg

pages/Kapitel05-page-400.svg

pages/Kapitel05-page-401.svg

pages/Kapitel05-page-402.svg

pages/Kapitel05-page-403.svg

pages/Kapitel05-page-404.svg

pages/Kapitel05-page-405.svg

pages/Kapitel05-page-406.svg

pages/Kapitel05-page-407.svg

pages/Kapitel05-page-408.svg

pages/Kapitel05-page-409.svg

pages/Kapitel05-page-410.svg

pages/Kapitel05-page-411.svg

pages/Kapitel05-page-412.svg

pages/Kapitel05-page-413.svg

pages/Kapitel05-page-414.svg

pages/Kapitel05-page-415.svg

pages/Kapitel05-page-416.svg

pages/Kapitel05-page-417.svg

pages/Kapitel05-page-418.svg

pages/Kapitel05-page-419.svg

pages/Kapitel05-page-420.svg

pages/Kapitel05-page-421.svg

pages/Kapitel05-page-422.svg

pages/Kapitel05-page-423.svg

pages/Kapitel05-page-424.svg

pages/Kapitel05-page-425.svg

pages/Kapitel05-page-426.svg

pages/Kapitel05-page-427.svg

pages/Kapitel05-page-428.svg

pages/Kapitel05-page-429.svg

pages/Kapitel05-page-430.svg

pages/Kapitel05-page-431.svg

pages/Kapitel05-page-432.svg

pages/Kapitel05-page-433.svg

pages/Kapitel05-page-434.svg

pages/Kapitel05-page-435.svg

Live-Demo - Makros

#include <iostream>

using namespace std;

#define SQUARE(x) ((x) * (x))
#define PFERD 2

int hallo(void) {
    cout << "hallo" << endl;
    return 1;
}

int main(void) {
    int x = 2;
    cout << SQUARE(++x) << endl;
    x = 2;
    cout << SQUARE(x++) << endl;

    SQUARE(hallo());

#ifdef PFERD
    cout << "PFERD!" << endl;
#endif
#if PFERD == 1
    cout << "Ein Pferd" << endl;
#endif

	return 0;
}
compiler

Wissensspeicher 8

  • Standardbibliotheken
    • Stellen hĂ€ufig genutzte Funktionen bereit → sin() oder time()
    • Alte C-Bibliotheken nutzbar ĂŒber vorangestelltes c: #include <cmath>
  • inline-Funktionen
    • Bsp.: inline int foo(void);
    • Ersetzt jeden Aufruf durch die Anweisung in der Funktion
    • Nur ein Hinweis an den Compiler
  • Makros
    • Werden durch den C++-PrĂ€prozessor ausgewertet („reine Textersetzung, außer bei Strings“)
    • Wird in C oft fĂŒr die Dimensionierung von Arrays genutzt: #define MAX_ARR_SIZE 100
    • Achtung: Markos können versteckte Seiteneffekte haben

Beispiel - Makros 1

// ...
#define SQUARE(x) ((x) * (x))

int main(void) {
    int x = 2;
    cout << SQUARE(++x) << endl;

    return 0;
}
  • Erwartete Ausgabe: 12
  • Festgestellte Ausgabe: 16
  • Auswertungsreihenfolge der Erhöhung ist undefiniert
  • Nur die Auswertungsreihenfolge der Multiplikation ist definiert

Quelle: cppreference.com, Abschnitt „Evaluation Order“

Beispiel - Makros 2

#include <cstdio>
 
int a() { return std::puts("a"); }
int b() { return std::puts("b"); }
int c() { return std::puts("c"); }
 
void z(int, int, int) {}
 
int main()
{
    z(a(), b(), c());       // all 6 permutations of output are allowed
    return a() + b() + c(); // all 6 permutations of output are allowed
}
Undefined behavior

1) If a side effect on a memory location is unsequenced relative to another side effect on the same memory location, the behavior is undefined. 
i = ++i + 2;       // well-defined
i = i++ + 2;       // undefined behavior until C++17

Quelle des Beispiels und des Ausschnitts: cppreference.com, Abschnitt „Evaluation Order“ (CC-BY-SA)

pages/Kapitel05-page-436.svg

pages/Kapitel05-page-437.svg

pages/Kapitel05-page-438.svg

pages/Kapitel05-page-439.svg

pages/Kapitel05-page-440.svg