Tutoriumsinhalt

  • Plagiatscheck!
  • Besprechung Assignments 1 & 2
  • Funktionen
  • Call-by-Reference
  • Arrays
  • Pointer
  • Strings

Plagiatscheck

Allgemein:

  • Aufgaben sind alleine zu lösen!
  • Abgaben werden automatisch auf Plagiate geprüft

Bei Verstoß:

  • Alle Verdächtigen werden von der LV disqualifiziert

Besprechung Assignments 1 & 2

Wichtig - upstream adden und aktuell halten!

Assignment 1
  • git remote add upstream git@gitlab.tugraz.at:ep-2019/assignment_1_a.git
  • git pull upstream master
Assignment 2
  • git remote add upstream git@gitlab.tugraz.at:esp-2019/assignment_a2.git
  • git pull upstream master

Aktualisieren mit (nur lokal!):

git pull upstream master

Wichtig - Namen!

  • Dateiname: ass-a1.c
  • Tag: submission
  • Deadline A1: 31.10.2019 12:00 Uhr

Coding Standard!

Funktionen

 <Rueckgabewert-Typ> Funktion-Name (<Parameter1>, <Parameter2>...)
 {
   // Code
   return <Rueckgabewert>
 }

 int main()
 {
   // Aufruf:
   <Rueckgabewert-Typ> Ergebnis;
   Ergebnis = Funktion-Name(<Parameter1>, <Parameter2>...);
 } 

Rückgabewert der main-Funktion anzeigen

 > echo $?
 0
 

Funktionen - Beispiel

 int correctCode(int studentID)
 {
   ... code ...
   return points;
 }

 int main()
 {
   int num_studis = 85;
   int i = 0;
   for(i = 0; i < num_studis; i++)
   {
      printf("Student #%d received %d points!", i, correctCode(i));
   }
 } 

Funktionen - Void als Returnwert

 void printHello()
 {
   while(1)
   {
     int studentID = 0;
     printf("Please enter your studentID: ");
     scanf("%d", &studentID);

     if(studentID == 0)
     {
       return;
     }
     printf("Hello %d!\n", studentID);
   }
 }

 int main()
 {
   printHello();
 } 

Rekursive Funktionen

 int fibonacci(int num, int a, int b)
 {
   if(num == 0)
   {
     return a;
   }
   else
   {
     return fibonacci(num - 1; b, a + b);
   }
 }

 int main()
 {
   int num = 15;
   int fib = fibonacci(num, 0, 1);
   printf("%dth fibonacci number = %d", num, fib);

 } 

Arrays

  • Hintereinander liegende Daten vom gleichen Typ
  • Größe kann nicht mehr verändert werden, muss bei Deklaration bekannt sein
  • Zugriff über [ ]
  • Deklaration:
    <typ> name[<size>];
  • Initialisiertes Array:
    <typ> name[] = {<value1>, <value2>, ...};
  • Zugriff:
    name[<index>] = <value>;

Beispiel

1int main() { 2 int fibo[5]; 3 fibo[0] = 1; 4 fibo[1] = 1; 5 fibo[2] = fibo[1] + fibo[0]; 6 fibo[3] = fibo[2] + fibo[1]; 7 fibo[4] = fibo[3] + fibo[2]; return 0; }
0x1000
0x1004
0x1008
0x100C
0x1010
0x1014
fibo   0x1000
0x1004
0x1008
0x100C
0x1010
0x1014
fibo   0x10001
0x1004
0x1008
0x100C
0x1010
0x1014
fibo   0x10001
0x10041
0x1008
0x100C
0x1010
0x1014
fibo   0x10001
0x10041
0x10082
0x100C
0x1010
0x1014
fibo   0x10001
0x10041
0x10082
0x100C3
0x1010
0x1014
fibo   0x10001
0x10041
0x10082
0x100C3
0x10105
0x1014

Variable-length-Arrays

  • GCC akzeptiert Arrays mit variabler Länge (C99 Standard)
  • Beispiel
    int size = numberOfHornsOnAUnicorn();
    int array[size];
    
  • Gefährlich zu verwenden, da diese Arrays am Stack liegen → normal 8MB maximale Größe, kann jedoch auch nur 64kB sein!
  • Ist das Array zu groß, stürzt das Programm ohne erkennbare Ursache ab
  • Have fun debugging!
  • Array als Funktionsparameter

    • Soll ein Array an eine Funktion als Parameter übergeben werden gibt es 3 Wege
    1. Array variabler Größe
      void foo(int bar[]) {
       [..]
      }
    2. Array fixer Größe
      void foo(int bar[8]) {
       [..]
      }
    3. Als Pointer
      void foo(int* bar) {
       [..]
      }

    Spezielle Arrays: Mehrdimensionale Arrays

    • Arrays können mehrere Dimensionen haben
    • 2-dimensionale Arrays:
      <typ> name[<rows>][<columns>];
    • Zugriff über Zeilen- und Spaltenindex:
      name[<row>][<column>] = <value>;
    • Beispiel Initialisierung:
      char matrix[3][3] = { {'A', 'B', 'C'}, {'D', 'E', 'F'},
            {'G', 'H', 'I'} };

    Mehr als 2 Dimensionen?

    • Ja, in C beliebig viele (so lange wir Speicher haben)
    • Schwer vorstellbar ab 4 Dimensionen, deshalb als Array von Arrays denken
    int cube[3][3][3];
    int hypercube[3][3][3][3];
    

    Beispiel: 4 Dimensionen

     int hypercube[3][3][3][3];
    

    Möglichkeit 1: 4D-Würfel

    Möglichkeit 2: Array von 3D Würfeln

    Mehrdimensionale Arrays als Parameter

    #include <stdio.h>
    
    void printMatrix3(char matrix[][3])
    {
      int y;
      for(y = 0; y < 3; y++)
      {
        printf("%c %c %c\n", matrix[y][0], matrix[y][1], matrix[y][2]);
      }
    }
    
    int main()
    {
      char matrix[3][3] = { {'A', 'B', 'C'}, {'D', 'E', 'F'},
          {'G', 'H', 'I'} };
      printMatrix3(matrix);
    }
    
    Achtung: Nicht mehr möglich als Pointer zu übergeben!

    Pointer

    • Pointer »zeigen« auf Variablen
    • Pointer enthält die Adresse einer Variable
    • Deklaration mit "*"
      <datentyp>* name;
    • Zugriff auf die Variable durch Dereferenzieren ebenfalls mit "*"
      *name = <value>;
    • Zuweisen einer Adresse durch den Adressoperator "&"
      name = &<variable>;

    Pointer und Pointee

    Pointer - Praxisbeispiel

    1int main() { 2 int a = 3; 3 int x = 2; 4 int* ptr = &a; 5 *ptr = 4; 6 ptr = &x; 7 *ptr = 8; return 0; }
    0x1000
    0x1004
    0x1008
    0x100C
    0x1010
    a   0x10003
    0x1004
    0x1008
    0x100C
    0x1010
    a   0x10003
    x   0x10042
    0x1008
    0x100C
    0x1010
    a   0x10003
    x   0x10042
    0x1008
    ptr   0x100C0x1000
    0x1010
    a   0x10004
    x   0x10042
    0x1008
    ptr   0x100C0x1000
    0x1010
    a   0x10004
    x   0x10042
    0x1008
    ptr   0x100C0x1004
    0x1010
    a   0x10004
    x   0x10048
    0x1008
    ptr   0x100C0x1004
    0x1010

    Call-by-Reference

    • Bei Funktionsaufruf nicht Variable, sondern Adresse übergeben
    • mehrere Rückgabewerte möglich
    • z.B. nützlich damit eine Funktion einen Wert sowie einen Fehlercode liefern kann

    Beispiel

    void getHourMinutes(int minutes, int* h, int* m)
    {
      *h = minutes / 60;
      *m = minutes % 60;
    }
    
    int main()
    {
      int hour = 0, minutes = 0;
      getHourMinutes(320, &hour, &minutes);
      printf("%d:%d\n", hour, minutes);
      return 0;
    }
    

    Strings - auch nur Arrays

    • String = Zeichenkette, »Text«
    • String ist nur ein Array von char (Zeichen)
    • Strings enden mit einem 0-Byte ('\0', nicht dem Zeichen 0!)
    • Deklaration (am häufigsten):
      char* text = "Hallo!";
    • Andere Varianten:
      char text[] = "Hallo!";
      char text[] = {'H', 'a', 'l', 'l', 'o', '!', '\0'};

    Strings: Vergleich

    • Funktion strcmp aus string.h verwenden
    • == funktioniert nicht, vergleicht nur die Speicheradressen
    •  char* str1 = "Hello";
       char* str2 = "World";
       if(strcmp(str1, str2) == 0)
       {
         // strings sind gleich
       }
       else
       {
         // strings sind ungleich
       }
      

    Strings: Zugriff auf einzelne Buchstaben

    • Zugriff durch Array-Schreibweise ([])
    • Erstes Zeichen hat Index 0!
    • Letztes Zeichen ist 0-Byte ('\0')
    •  char* str1 = "Hello";
       char c1 = str1[0]; // c1 = 'H'
       char c2 = str1[4]; // c2 = 'o'
       char c3 = str1[5]; // c3 = '\0'
      

    Strings: Funktionen

    • Weitere Funktionen die mit Strings arbeiten in string.h
    • http://www.cplusplus.com/reference/cstring/
    • Einbinden mit
      #include <string.h>
    • Nützliche Funktionen:
      strlen
      Länge des Strings (ohne 0-Byte!)
      strcpy
      String in einen anderen kopieren
      strcat
      Strings aneinanderhängen
      sprintf
      Wie printf, aber Ausgabe wird in String gespeichert

    Viel Erfolg bei den
    Assignments!