Funktionen

Eine Funktion in der Informatik ist wie ein kleines Programm innerhalb eines größeren Programms. Sie enthält einen Block von Code, der eine bestimmte Aufgabe ausführt. Funktionen werden verwendet, um den Code in kleinere, wiederverwendbare Teile zu zerlegen und so den Programmieraufwand zu verringern und die Lesbarkeit und Wartbarkeit von Programmen zu verbessern.

Eine Funktion kann Parameter (Eingabewerte) akzeptieren und/oder Rückgabewerte liefern. Die Parameter ermöglichen es der Funktion, unterschiedliche Eingabedaten zu verarbeiten und das Ergebnis als Rückgabewert an den Aufrufer zurückzugeben.

In C++ wird eine Funktion mit einem Rückgabetypen, einem Funktionsnamen, einer Parameterliste und einem Anweisungsblock definiert, der den Code enthält, der ausgeführt werden soll, wenn die Funktion aufgerufen wird. Um eine Funktion aufzurufen, werden der Name der Funktion und gegebenenfalls die erforderlichen Parameter übergeben.

Du hast bereits die Funktionen „setup()“ und „loop()“ mit Leben gefüllt oder Funktionen wie delay() oder drawPixel() verwendet, hier lernst du aber deine eigenen Funktionen zu schreiben.

Funktionen ohne Parameter und Rückgabewert

Einige Funktionen benötigen weder Parameter noch Rückgabewert. Diese Begriffe werden die später noch begegnen. Das folgende Beispiel zeigt dir, wie du eine Funktion, hier zum Zeichnen eines Rasters, schreiben und verwenden kannst. Werden innerhalb einer Funktion Variablen deklariert, so sind sie nur darin gültig. Das dem Funktionsnamen vorangestellte „void“ zeigt, dass es sich hier um eine Funktion ohne Rückgabewert handelt.

Beispiel

#include <U8g2lib.h>
#include <SPI.h>

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10, 8, 9);

void drawGrid() {
  for (int i = 1; i < 16; i++) {
    u8g2.drawLine(i * 8, 8, i * 8, 56);
  }
  for (int i = 1; i < 8; i++) {
    u8g2.drawLine(8, i * 8, 120, i * 8);
  }
}

void setup(void) {
  u8g2.begin();
  u8g2.clearBuffer();
  drawGrid();
  u8g2.sendBuffer();
}

void loop() {}

Funktionen mit Parametern

Die Funktion drawPiece(int xPos, int yPos) zeichnet einen „Spielstein“ bei einer übergebenen Position. Der Funktionsaufruf drawPiece(1,2) führt beispielsweise dazu, dass die Parameter bzw. die Variablen xPos und yPos bei Ausführung innerhalb der Funktion die Werte 1 bzw. 2 annehmen . Ebenso ist das Übergeben von Variablen möglich, wie im Beispiel dargestellt.

Beispiel

#include <U8g2lib.h>
#include <SPI.h>

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10, 8, 9);

void drawGrid() {
  for (int i = 1; i < 16; i++) {
    u8g2.drawLine(i * 8, 8, i * 8, 56);
  }
  for (int i = 1; i < 8; i++) {
    u8g2.drawLine(8, i * 8, 120, i * 8);
  }
}

void drawPiece(int xPos, int yPos){
  u8g2.drawCircle(xPos*8+4,yPos*8+4,3);
}

void setup(void) {
  u8g2.begin();
  u8g2.clearBuffer();
  drawGrid();
  drawPiece(1,1);
  drawPiece(1,2);
  int xP = 3;
  int yP = 3;
  drawPiece(xP,yP);
  u8g2.sendBuffer();
}
void loop() {}

Funktionen mit Parametern und Rückgabewert

Funktionen, wie du sie aus der Mathematik kennst liefern meist einen Wert zurück. Hast du beispielsweise eine Funktion f(x) = 5  + x, bekommst du bei einem „Funktionsaufruf“ f(3) den Wert 8 zurück. Durch Funktionen mit einem oder mehreren Parametern und Rückgabewert ist dies auch in der Programmierung möglich.

Beispiel

Hinweis: Das Beispiel gibt lediglich Daten über die Serielle Schnittstelle aus. Benutze dazu also den seriellen Monitor aus der Arduino-Software.

void setup() {
  Serial.begin(9600);
}

int quadrat(int x){
  int q = x*x;
  return q;
}

void loop() {
  for(int i = 0; i < 100; i++){
    Serial.print("Das Quadrat von ");
    Serial.print(i);
    Serial.print(" ist ");
    Serial.println(quadrat(i));
    }
}

Funktionen mit Rückgabewert

Manchmal ist es auch sinnvoll, Funktionen zu schreiben, die ohne Parameter einen Rückgabewert liefern, der z.B. auf den Belegungen globaler Variablen basiert, wie im Beispiel zu sehen.

Beispiel

#include <U8g2lib.h>
#include <SPI.h>

#define KEY_RIGHT 2
#define KEY_DOWN 3
#define KEY_LEFT 4
#define KEY_UP 1
#define KEY_CENTER 0

U8G2_SH1106_128X64_NONAME_F_4W_HW_SPI u8g2(U8G2_R0, 10, 8, 9);

int xPos;
int yPos;

void setup(void) {
  u8g2.begin();
  u8g2.clearBuffer();
  u8g2.sendBuffer();
  u8g2.setFont(u8g2_font_glasstown_nbp_tf);

  pinMode(KEY_RIGHT, INPUT_PULLUP);
  pinMode(KEY_DOWN, INPUT_PULLUP);
  pinMode(KEY_LEFT, INPUT_PULLUP);
  pinMode(KEY_UP, INPUT_PULLUP);
  pinMode(KEY_CENTER, INPUT_PULLUP);

  xPos = 64;
  yPos = 32;
}

boolean outsideSquare() {
  boolean out = false;
  if (xPos < 20) { out = true; } if (xPos > 107) {
    out = true;
  }
  if (yPos < 10) { out = true; } if (yPos > 53) {
    out = true;
  }
  return out;
}

void loop() {
  if (digitalRead(KEY_UP) == LOW) {
    yPos = yPos - 1;
  }
  if (digitalRead(KEY_DOWN) == LOW) {
    yPos = yPos + 1;
  }
  if (digitalRead(KEY_LEFT) == LOW) {
    xPos = xPos - 1;
  }
  if (digitalRead(KEY_RIGHT) == LOW) {
    xPos = xPos + 1;
  }
  if (digitalRead(KEY_CENTER) == LOW) {
    u8g2.clearBuffer();
    xPos = 64;
    yPos = 32;
  }

  delay(50);
  u8g2.clearBuffer();
  u8g2.drawFrame(20, 10, 87, 43);
  u8g2.drawPixel(xPos, yPos);
  if (outsideSquare()) {
    u8g2.drawStr(36, 34, "Come back in!");
  }
  u8g2.sendBuffer();
}