Funktionen in der C-Programmierung mit Beispielen: Rekursiv und Inline

⚡ Intelligente Zusammenfassung

Funktionen in der Programmiersprache C sind wiederverwendbare Codeblöcke, die ein großes Programm in kleinere Teilprogramme unterteilen und so das Verständnis, Testen und Ändern erleichtern. Jede Funktion besteht aus einer Deklaration, einer Definition und einem Funktionsaufruf.

  • 🧩 Was Funktionen bewirken: Eine Funktion gruppiert wiederverwendbare Anweisungen, sodass ein großes Programm in kleinere, überschaubare Unterprogramme zerlegt wird, die einfacher zu debuggen sind.
  • 📚 Zwei Arten: Bibliotheksfunktionen wie printf und scanf sind vorgefertigt, während benutzerdefinierte Funktionen vom Programmierer geschrieben werden.
  • 📝 Drei Teile: Die Verwendung einer Funktion umfasst ihre Deklaration oder ihren Prototyp, ihre Definition oder ihren Funktionskörper und den Aufruf, der sie ausführt.
  • 🎯 Argumente: Werte werden positionsbezogen und standardmäßig auch wertbezogen übergeben, sodass die ursprüngliche Variable innerhalb der aufgerufenen Funktion unverändert bleibt.
  • 🌐 Umfang: Lokale Variablen existieren nur innerhalb ihrer Funktion, während globale und statische Variablen ihre Werte im gesamten Programm oder zwischen Funktionsaufrufen beibehalten.
  • 🤖 KI-Unterstützung: GitHub Copilot und KI-Assistenten erstellen C-Funktionen, schlagen Rückgabetypen vor und kennzeichnen fehlende Rückgabewerte oder nicht übereinstimmende Argumente.

Funktionen in der C-Programmierung

Was ist eine Funktion in C?

Funktion in der C-Programmierung Eine Funktion ist ein wiederverwendbarer Codeblock, der ein Programm verständlicher und testbarer macht und sich leicht modifizieren lässt, ohne das aufrufende Programm zu verändern. Funktionen unterteilen den Code und modularisieren das Programm für bessere und effektivere Ergebnisse. Kurz gesagt: Ein größeres Programm wird in verschiedene Unterprogramme, sogenannte Funktionen, unterteilt.

Was ist eine Funktion in C?

Wenn Sie ein großes Programm in verschiedene Funktionen unterteilen, ist es einfach, jede Funktion einzeln zu verwalten. Wenn im Programm ein Fehler auftritt, können Sie fehlerhafte Funktionen einfach untersuchen und nur diese Fehler beheben. Sie können Funktionen ganz einfach aufrufen und nutzen, wann immer sie benötigt werden, was automatisch zu einer Zeit- und Platzersparnis führt.

Bibliothek vs. Benutzerdefinierte Funktionen

Jedes „C“-Programm hat mindestens eine Funktion, die die Hauptfunktion ist, aber ein Programm kann beliebig viele Funktionen haben. Die Funktion main() in C ist ein Ausgangspunkt eines Programms.

Bei der C-Programmierung werden Funktionen in zwei Typen unterteilt:

  1. Bibliotheksfunktionen
  2. Benutzerdefinierte Funktionen

Der Unterschied zwischen der Bibliothek und benutzerdefinierten Funktionen in C besteht darin, dass wir keinen Code für eine Bibliotheksfunktion schreiben müssen. Es ist bereits in der Header-Datei vorhanden, die wir immer am Anfang eines Programms einfügen. Sie müssen lediglich den Namen einer Funktion eingeben und ihn zusammen mit der richtigen Syntax verwenden. Printf, scanf sind Beispiele für eine Bibliotheksfunktion.

Eine benutzerdefinierte Funktion hingegen ist ein Funktionstyp, bei dem wir den Hauptteil einer Funktion schreiben und die Funktion immer dann aufrufen müssen, wenn die Funktion eine Operation in unserem Programm ausführen soll.

Eine benutzerdefinierte Funktion in C wird immer vom Benutzer geschrieben, kann aber später Teil einer C-Bibliothek sein. Dies ist ein großer Vorteil der C-Programmierung.

C-Programmierfunktionen sind in drei Aktivitäten unterteilt, wie zum Beispiel:

  1. Funktionsdeklaration
  2. Funktionsdefinition
  3. Funktionsaufruf

Funktionserklärung

Die Funktionsdeklaration bedeutet, einem Programm einen Namen zu geben. Sie ist zwingend erforderlich, um Funktionen im Code verwenden zu können. In einer Funktionsdeklaration legen wir einfach den Namen einer Funktion fest, die wir in unserem Programm verwenden möchten, ähnlich wie bei einer Variablendeklaration. Eine Funktion kann nur verwendet werden, wenn sie im Programm deklariert ist. Eine Funktionsdeklaration wird auch als „Funktionsprototyp“ bezeichnet.

Die Funktionsdeklarationen (Prototyp genannt) erfolgen normalerweise über der Funktion main() und haben die allgemeine Form:

return_data_type function_name (data_type arguments);
  • Der return_data_type: ist der Datentyp der Wertfunktion, die an die aufrufende Anweisung zurückgegeben wird.
  • Dem Funktionsnamen folgen Klammern.
  • Argumentnamen mit ihren Datentypdeklarationen werden optional in Klammern gesetzt.

Wir betrachten das folgende Programm, das zeigt, wie man eine Kubusfunktion deklariert, um den Kubuswert einer ganzzahligen Variable zu berechnen

#include <stdio.h>
/*Function declaration*/
int add(int a,b);
/*End of Function declaration*/
int main() {

Beachten Sie, dass eine Funktion nicht unbedingt einen Wert zurückgibt. In diesem Fall wird das Schlüsselwort void verwendet.

Die Funktionsdeklaration „output_message“ gibt beispielsweise an, dass die Funktion keinen Wert zurückgibt: void output_message();

Funktionsdefinition

Unter Funktionsdefinition versteht man lediglich das Schreiben des Hauptteils einer Funktion. Ein Funktionskörper besteht aus Anweisungen, die eine bestimmte Aufgabe ausführen. Ein Funktionskörper besteht aus einer einzelnen Anweisung oder einem Block von Anweisungen. Es ist auch ein obligatorischer Bestandteil einer Funktion.

int add(int a,int b)	//function body	
{
	int c;
	c=a+b;
	return c;
}

Funktionsaufruf

Ein Funktionsaufruf bedeutet, eine Funktion aufzurufen, wann immer dies in einem Programm erforderlich ist. Wann immer wir eine Funktion aufrufen, führt sie eine Operation aus, für die sie entwickelt wurde. Ein Funktionsaufruf ist ein optionaler Teil eines Programms.

  result = add(4,5);

Hier ist der vollständige Code:

#include <stdio.h>
int add(int a, int b);	//function declaration
int main()
{
	int a=10,b=20;
	int c=add(10,20); 	//function call
	printf("Addition:%d\n",c);
	getch();
}
int add(int a,int b)	//function body
{
	int c;
	c=a+b;
	return c;
}

Ausgang:

Addition:30

Funktionsargumente

Die Argumente einer Funktion werden verwendet, um beim Funktionsaufruf die notwendigen Werte zu erhalten. Sie sind nach Position abgeglichen; Das erste Argument wird an den ersten Parameter übergeben, das zweite an den zweiten Parameter und so weiter.

Standardmäßig werden die Argumente als Werte übergeben, wobei der aufgerufenen Funktion eine Kopie der Daten zur Verfügung gestellt wird. Die tatsächlich übergebene Variable ändert sich nicht.

Wir betrachten das folgende Programm, das die Parameterübergabe als Wert demonstriert:

int add (int x, int y); 
int main() {
  int a, b, result;
  a = 5;
  b = 10;
  result = add(a, b);
  printf("%d + %d\ = %d\n", a, b, result);
return 0;}
int add (int x, int y) { 
x += y;
  return(x);}

Die Programmausgabe ist:

5 + 10 = 15

Beachten Sie, dass die Werte von a und b, die an die Add-Funktion übergeben wurden, nicht geändert wurden, da nur ihr Wert an den Parameter x übergeben wurde.

Variablenbereich

Unter Variablenbereich versteht man die Sichtbarkeit von Variablen innerhalb eines Codes des Programms.

In C sind Variablen, die innerhalb einer Funktion deklariert werden, lokal und nur innerhalb dieses Codeblocks zugänglich. Variablen, die außerhalb aller Funktionen deklariert werden, sind hingegen global und vom gesamten Programm aus erreichbar. Konstanten, die mit `#define` am Anfang eines Programms deklariert werden, sind ebenfalls vom gesamten Programm aus zugänglich. Betrachten wir das folgende Programm, das den Wert einer globalen Variable sowohl aus der `main`-Funktion als auch aus einer benutzerdefinierten Funktion ausgibt:

#include <stdio.h>
int global = 1348;
void test();
int main() {
  printf("from the main function : global =%d \n", global);
  test () ;
return 0;}

void test (){
printf("from user defined function : global =%d \n", global);}

Ergebnis:

from the main function : global =1348
from user defined function : global =1348

Wir besprechen die Programmdetails:

Variablenbereich

  1. Wir deklarieren eine ganzzahlige globale Variable mit 1348 als Anfangswert.
  2. Wir deklarieren und definieren eine test()-Funktion, die weder Argumente entgegennimmt noch einen Wert zurückgibt. Diese Funktion gibt nur den Wert der globalen Variablen aus, um zu zeigen, dass überall im Programm auf die globalen Variablen zugegriffen werden kann.
  3. Wir drucken die globale Variable innerhalb der Hauptfunktion.
  4. Wir rufen die Testfunktion auf, um den globalen Variablenwert auszugeben.

Wenn in C Argumente an Funktionsparameter übergeben werden, fungieren die Parameter als lokale Variablen, die beim Verlassen der Funktion zerstört werden.

Wenn Sie verwenden, globale Variablen, verwenden Sie sie mit Vorsicht, da sie zu Fehlern führen können und sie sich überall im Programm ändern können. Sie sollten vor der Verwendung initialisiert werden.

Statische Variablen

Die statischen Variablen haben einen lokalen Gültigkeitsbereich. Sie werden jedoch beim Verlassen der Funktion nicht zerstört. Daher behält eine statische Variable ihren Wert für immer und kann beim erneuten Aufrufen der Funktion abgerufen werden. Eine statische Variable wird bei der Deklaration initialisiert und benötigt das Präfix static.

Das folgende Programm verwendet eine statische Variable:

#include <stdio.h>
void say_hi();
int main() {    
  int i;
  for (i = 0; i < 5; i++) { say_hi();}
   return 0;}
void say_hi() {
  static int calls_number = 1;
  printf("Hi number %d\n", calls_number);
  calls_number ++; }

Das Programm zeigt:

Hi number 1
Hi number 2
Hi number 3
Hi number 4
Hi number 5

Rekursive Funktionen

Betrachten wir die Fakultät einer Zahl, die wie folgt berechnet wird: 6! = 6 * 5 * 4 * 3 * 2 * 1.

Diese Berechnung erfolgt durch wiederholtes Berechnen von Fakt * (Fakt -1), bis Fakt gleich 1 ist.

Eine rekursive Funktion ist eine Funktion, die sich selbst aufruft und eine Beendigungsbedingung enthält, um die rekursiven Aufrufe abzuschließen. Im Fall der Fakultätszahlberechnung ist die Ausgangsbedingung gleich 1. Bei der Rekursion werden Aufrufe „gestapelt“, bis die Ausgangsbedingung wahr ist.

Beispielsweise:

#include <stdio.h>
int factorial(int number);
int main() {    
  int x = 6;
  printf("The factorial of %d is %d\n", x, factorial(x)); 
  return 0;}
int factorial(int number) {
 if (number == 1)    return (1); /* exiting condition */
  else
    return (number * factorial(number - 1));
}

Das Programm zeigt:

 The factorial of 6 is 720

Hier besprechen wir Programmdetails:

Rekursive Funktionen

  1. Wir deklarieren unsere rekursive Fakultätsfunktion, die einen ganzzahligen Parameter annimmt und die Fakultät dieses Parameters zurückgibt. Diese Funktion ruft sich selbst auf und verringert die Zahl, bis die Ausgangs- oder Grundbedingung erreicht ist. Wenn die Bedingung wahr ist, werden die zuvor generierten Werte miteinander multipliziert und der endgültige Fakultätswert zurückgegeben.
  2. Wir deklarieren und initialisieren eine Ganzzahlvariable mit dem Wert „6“ und geben dann ihren Fakultätswert aus, indem wir unsere Fakultätsfunktion aufrufen.

Das folgende Diagramm veranschaulicht den rekursiven Mechanismus, der darin besteht, die Funktion so lange selbst aufzurufen, bis der Basisfall eintritt oder der Abbruch erreicht ist.ping Die Bedingung ist erfüllt, und danach werden die vorherigen Werte erfasst:

Rekursive Funktionen

Inline-Funktionen

Eine Funktion wird in der C-Programmierung zum Speichern der am häufigsten verwendeten Anweisungen verwendet. Es dient der Modularisierung des Programms.

Bei jedem Aufruf einer Funktion springt der Anweisungszeiger zur Funktionsdefinition. Nach der Ausführung einer Funktion fällt der Anweisungszeiger auf die Anweisung zurück, von der aus er zur Funktionsdefinition gesprungen ist.

Immer wenn wir Funktionen verwenden, benötigen wir ein Extra Zeiger head, um zur Funktionsdefinition zu springen und zur Anweisung zurückzukehren. Um solche Zeigerköpfe überflüssig zu machen, verwenden wir Inline-Funktionen.

Bei einer Inline-Funktion wird ein Funktionsaufruf direkt durch tatsächlichen Programmcode ersetzt. Es wird nicht zu einem Block gesprungen, da alle Operationen innerhalb der Inline-Funktion ausgeführt werden.

Inline-Funktionen werden meist für kleine Berechnungen verwendet. Sie sind nicht geeignet, wenn große Rechenkapazitäten erforderlich sind.

Eine Inline-Funktion ähnelt einer normalen Funktion, außer dass das Schlüsselwort inline vor dem Funktionsnamen steht. Inline-Funktionen werden mit der folgenden Syntax erstellt:

inline function_name ()
{
    //function definition
}

Schreiben wir ein Programm zur Implementierung einer Inline-Funktion.

inline int add(int a, int b)		//inline function declaration
{
	return(a+b);
}
int main()
{
	int c=add(10,20);
	printf("Addition:%d\n",c);
	getch();
}

Ausgang:

Addition: 30

Das obige Programm demonstriert die Verwendung einer Inline-Funktion zur Addition zweier Zahlen. Wie wir sehen, haben wir die Addition zweier Zahlen nur innerhalb der Inline-Funktion zurückgegeben, ohne zusätzliche Zeilen zu schreiben. Während des Funktionsaufrufs haben wir nur Werte übergeben, für die wir die Addition durchführen müssen.

Häufig gestellte Fragen

Bei der Wertübergabe wird das Argument in die Funktion kopiert, sodass Änderungen lokal bleiben und die ursprüngliche Variable unverändert bleibt. Bei der Referenzübergabe wird die Variablenadresse über einen Zeiger übergeben, wodurch die Funktion die ursprünglichen Daten des Aufrufers direkt verändern kann.

Der tatsächliche Parameter ist der reale Wert oder die Variable, die der Aufrufer beim Funktionsaufruf übergibt. Der formale Parameter ist der in der Funktionsdefinition angegebene Platzhalter, der ihn empfängt. Sie werden positionsbezogen zugeordnet, erster Parameter mit erstem, zweiter mit zweitem.

Die AC-Funktion gibt direkt nur einen Wert zurück. Um mehrere Ergebnisse zurückzugeben, müssen diese in eine Struktur eingebettet, ein Array gefüllt oder Zeiger als Argumente übergeben werden, sodass die Funktion jedes Ergebnis in die Variablen des Aufrufers schreibt.

Funktionen ermöglichen die Wiederverwendbarkeit, sodass ein Codeblock mehrfach ausgeführt werden kann, und die Modularität, die ein großes Programm in kleinere Teile zerlegt. Sie verbessern außerdem die Lesbarkeit, vereinfachen das Testen und Debuggen und verbergen komplexe Details hinter einem einzigen Namen, was Entwicklungszeit spart.

Die `main()`-Funktion ist der Einstiegspunkt, an dem jedes C-Programm seine Ausführung beginnt. Das Betriebssystem ruft sie zuerst auf, und ihr Rückgabewert, üblicherweise 0, signalisiert Erfolg. Sie kann die Parameter `argc` und `argv` verwenden, um Kommandozeilenargumente entgegenzunehmen.

Rekursion eignet sich für Probleme mit einer natürlich wiederkehrenden Struktur, wie etwa Baumdurchläufe oder Fakultätsberechnungen, und führt zu kürzerem, übersichtlicherem Code. Iteration ist in der Regel schneller und speicherschonender, da sie wiederholte Aufrufe vermeidet. Wählen Sie Rekursion für mehr Übersichtlichkeit und Iteration für eine bessere Performance bei großen Eingaben.

Ja. Ein KI-Programmierassistent kann anhand einer Eingabe in einfacher Sprache eine C-Funktion schreiben, Parameter und Rückgabetypen vorschlagen und Fehler wie fehlende Rückgabewerte oder nicht übereinstimmende Argumente erkennen. Kompilieren und testen Sie die generierte Funktion immer, bevor Sie sich darauf verlassen.

GitHub-Copilot Schreibt C-Funktionen, indem der Funktionskörper anhand des Funktionsnamens oder eines kurzen Kommentars vervollständigt und Deklarationen, Schleifen und rekursive Aufrufe vorgeschlagen werden. Oft wird oberhalb von `main()` ein passendes Prototyp-Element hinzugefügt; dennoch sollten Sie die Logik überprüfen.

Fassen Sie diesen Beitrag mit folgenden Worten zusammen: