1 Theorie | |
→ | 1.1 Die Programmiersprache C |
Überblick |
Prototyp |
Definition |
Speicherklassen von Funktionen |
Nutzung der Funktion |
Beispiel 1: Verwendung einer Funktion |
Beispiel 2: Lokale Variablen |
Coding Standards |
Empfehlungen |
Aufgaben |
Funktionen in C entsprechen Unterprogrammen oder Subroutinen anderer Programmiersprachen. Die Zerlegung des Quelltextes in Funktionen macht den Quelltext übersichtlicher. Eine Funktion erhält beim Aufruf Argumente, die verarbeitetet werden. Im Normallfall gibt eine Funktion einen Wert als Ergebnis zurück.
Bevor eine Funktion verwendet wird, sollte der Prototyp deklariert werden. Der Prototyp hat die Form
Speicherklasse Rückgabetyp Name(Argumenttyp Argumentname,...);
Die Speicherklasse ist dabei optional, Informationen zu Speicherklassen finden Sie weiter unten.
Ein Beispiel für einen Prototypen ist
double quadermasse(double laenge, double breite, double hoehe, double dichte);
als Deklaration einer Funktion zum Berechnen der Masse eines
Quaders aus Länge, Breite, Höhe und Dichte. Das erste double
besagt, dass die Funktion einen Wert vom Typ double liefert. Das
Ergebnis der Funktion kann also beispielsweise einer
double-Variable zugewiesen werden oder in weiteren Berechnungen mit
double-Werten genutzt werden.
Die Funktionsargumente sind ebenfalls alle vom Typ double.
Während der Prototyp lediglich die Typen der Funktionsargumente und den Ergebnistyp festlegt, bestimmt die Definition, was die Funktion tut.
Speicherklasse Rückgabetyp Name(Argumenttyp Argumentname,...) { Lokale Variablen Anweisungsblock return Ergebnis; }
Der Funktionskopf entspricht dem Prototypen, auch hier ist die
Speicherklasse optional.
Im Anweisungsblock können return-Anweisungen auftreten. Diese
führen zur Rückkehr aus der Funktion zum aufrufenden Code und legen
den Wert für das Ergebnis des Funktionsaufrufes fest.
Beispiel:
double
quadermasse(double laenge, double breite, double hoehe, double dichte)
{
double masse = 0.0;
double volumen = 0.0;
volumen = laenge * breite * hoehe;
masse = volumen * dichte;
return masse;
}
Ort | Speicherklasse | Auswirkung |
---|---|---|
Prototyp / Deklaration | keine Angabe | Modulintern oder extern Die Funktion kann entweder modulintern sein oder sich in einem anderen Modul befinden. |
Prototyp / Deklaration | static | Moduleinterne Funktion Diese Funktion kann nur von Funktionen aus demselben Modul aufgerufen werden. |
Prototyp / Deklaration | extern | Funktion aus anderem Modul Eine Funktion aus einem anderen Modul soll benutzt werden. |
Definition | extern keine Angabe |
Globale Funktion Die Funktion kann sowohl von anderen Funktionen aus demselben Modul als auch von anderen Modulen aus aufgerufen werden. |
Definition | static | Modulinterne Funktion Die Funktion kann nur von anderen Funktionen aus demselben Modul aufgerufen werden. |
Wir können nun die Funktion nutzen, z.B.:
double m1; /* Masse des ersten Quaders */
double m2; /* Masse des zweiten Quaders */
double anfang; /* x-Koordinate, an der zweiter Quader beginnt */
double ende; /* x-Koordinate, an der zweiter Quader endet */
anfang = ...
ende = ...
m1 = quadermasse(3.0, 4.0, 2.0, 10.0);
m2 = quadermasse((ende - anfang), 5.0, 3.0, 15.0);
/* Testprogram zur Demonstration einer Funktion */
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
/** Flaechenberechnung fuer Quadrat.
@param a Seitenlaenge des Quadrates.
@return Flaecheninhalt des Quadrates bei Erfolg, -1.0 bei Fehler
(negative Seitenlaenge).
*/
double
quadratflaeche(double a);
/** Hauptprogramm.
@return 0 bei Erfolg, 1 bei Fehler.
*/
int
main(void)
{
int exitcode = 1; /* Exit-Code, 0 bei Erfolg, 1 bei Fehler */
double slaenge; /* Seitenlaenge */
printf("Bitte Seitenlaenge fuer Quadrat angeben: ");
scanf("%lg", &slaenge);
if (0.0 <= slaenge) {
printf("Flaecheninhalt: %lg\n", quadratflaeche(slaenge));
exitcode = 0;
}
else {
printf("FEHLER: Seitenlaenge darf nicht negativ sein!\n");
}
return exitcode;
}
double
quadratflaeche(double a)
{
double ergebnis = -1.0;
if (0.0 <= a) {
ergebnis = a * a;
}
return ergebnis;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Das Beispiel ex019.c verdeutlicht die folgenden Tatsachen:
Hinweis: Wenn Sie das Programm vom unveränderten
Quelltext erstellen, sehen Sie eine Warnung, dass die Variable
summe verwendet wird, ohne dass zuvor ein Wert zugewiesen
wurde. Beim Ausführen erscheint eine entsprechende Warnung
erneut.
Initialisieren Sie die Variable summe, um die Warnung zu
beseitigen.
/* Beispiel zur Verdeutlichung von lokalen Variablen */
/* Copyright (C) 2014-2017 - HS Schmalkalden. All rights reserved. */
#include <stdio.h>
/** Addition von zwei Werten.
@param w1 Linker Operand.
@param w2 Rechter Operand.
@return Summe der beiden Operanden.
*/
int
add(int w1, int w2);
/** Hauptprogramm.
@return 0 bei Erfolg, alle anderen Werte bedeuten Fehler.
*/
int
main(void)
{
int s1 = 10;
int s2 = 20;
int w1 = 50;
int w2 = 60;
int summe = 0;
printf("Vor Verwendung von add(): s1 = %d\n", s1);
printf("Vor Verwendung von add(): s2 = %d\n", s2);
printf("Vor Verwendung von add(): w1 = %d\n", w1);
printf("Vor Verwendung von add(): w2 = %d\n", w2);
printf("Vor Verwendung von add(): summe = %d\n", summe);
summe = add(s1, s2);
printf("Nach Verwendung von add(): s1 = %d\n", s1);
printf("Nach Verwendung von add(): s2 = %d\n", s2);
printf("Nach Verwendung von add(): w1 = %d\n", w1);
printf("Nach Verwendung von add(): w2 = %d\n", w2);
printf("Nach Verwendung von add(): summe = %d\n", summe);
return 0;
}
int
add(int w1, int w2)
{
int s1;
printf("Start von add(): w1 = %d\n", w1);
printf("Start von add(): w2 = %d\n", w2);
w1 = w1 + w2;
s1 = 3;
printf("Ende von add(): w1 = %d\n", w1);
return w1;
}
/* vim: set ai sw=4 ts=4 expandtab : */
Quelle: CERT C Coding Standard 〈1〉
int getchar(void);Wird eine Funktion nur als Subroutine aufgerufen, liefert also kein Ergebnis, ist der Rückgabetyp "void".
errno_t enhanced_strtoul(unsigned long *resptr, const char *str);die bei erfolgreicher Abarbeitung 0 zurückgibt und das Ergebnis in der Variable speichert, auf die resptr zeigt. Im Fehlerfall würde ein Fehlercode zurückgegeben werden.
Quelle: GNU Coding Standards 〈2〉
int berechne_alter(int gt, int gm, int gj, int ht, int hm, int hj) { ... }Damit kann eine Funktionsdefinition schnell gefunden werden, indem nach Vorkommen des Funktionsnamens unmittelbar am Zeilenanfang gesucht wird.
double quadermasse(double laenge, double breite, double hoehe, double dichte);erschließt sich die Verwendung der Funktion bereits beim Lesen des Prototypes, bei einer ansonsten gleichen Funktion
double qm(double l, double b, double h, double d);ist dies nicht der Fall.
1 | http://www.securecoding.cert.org |
2 | http://www.gnu.org/prep/standards/standards.html |