Variadische Funktion

aus Wikipedia, der freien Enzyklopädie
Wechseln zu: Navigation, Suche

Als variadische Funktion bezeichnet man in Programmiersprachen Funktionen, Prozeduren oder Methoden mit unbestimmter Arität, also solche, deren Parameteranzahl nicht bereits in ihrer Deklaration festgelegt ist. In einigen Sprachen wie C, C++ und Java wird dies in der Funktionsdeklaration mit Auslassungspunkten angezeigt, der sogenannten Ellipse. An Stelle der Ellipse können beliebig viele Argumente (oder auch keine) übergeben werden. Nützlich sind variadische Funktionen beispielsweise bei der Verknüpfung mehrerer Zeichenketten oder beim Aufsummieren von Zahlenreihen und generell bei Operationen, die prinzipiell auf eine beliebige Anzahl Operanden angewandt werden können.

Umsetzung in verschiedenen Programmiersprachen[Bearbeiten]

C und C++[Bearbeiten]

Der Zugriff auf variadische Parameter erfolgt hier über spezielle Makros.[1] Einige Bibliotheksfunktionen von C sind mit Ellipse deklariert, da es in C keine Möglichkeit der Funktionsüberladung gibt, Beispiele sind die Bibliotheksfunktionen printf und scanf zur formatierten Aus- beziehungsweise Eingabe.[2] Ein grundlegendes Problem bei diesem Mechanismus ist, dass zur Laufzeit keine Information über Anzahl und Typ der übergebenen Argumente zur Verfügung steht. Der Programmierer muss also durch zusätzliche Maßnahmen (wie etwa mit dem format string bei printf) sicherstellen, dass die Argumente richtig interpretiert werden und nicht mehr Argumente verarbeitet werden, als tatsächlich vorhanden waren. Außerdem muss mindestens ein fester Parameter vor der Ellipse angegeben werden.

In C++ gelten Ellipsen heutzutage als überholt, da C++ elegantere Möglichkeiten zur Funktionsüberladung und das Konzept der Defaultargumente bietet, und als schlechter Stil, da sie keine Typsicherheit bieten.[3] Sie sind jedoch die einzige Möglichkeit, eine nahezu unbegrenzte Anzahl an Argumenten zu übergeben.

C#[Bearbeiten]

In C# wird in der Deklaration das Schlüsselwort "params" verwendet. Auch der Typ wird mitangegeben. Einer solchen Methode kann eine durch Kommas getrennte Liste übergeben werden (diese Liste kann auch leer sein). Nach dem "params" Schlüsselwort sind keine weiteren Parameter mehr zulässig. Zudem darf das "params" Schlüsselwort nur einmal in der Methodendeklaration vorkommen.[4]

public class Summe
{
    public static int sum(params int[] list)
    {
        int result = 0;
 
        for (int i = 0; i < list.Length; i++)
        {
            result += list[i];
        }
 
        return result;
    }
 
    static void Main()
    {
        int a = sum();             // Ergebnis: a = 0
        int b = sum(1);            // Ergebnis: b = 1
        int c = sum(1, 2, 3, 4);   // Ergebnis: c = 10
    }
}

Go[Bearbeiten]

Die Sprache Go erlaubt die Deklaration variadischer Funktionen über den Anhang einer Ellipse ... an den Namen des letzten Parameters.[5] Es können dann beliebig viele Parameter des angegebenen Types übergeben werden, diese sind dann über ein Slice in der aufgerufenen Funktion verfügbar. Ferner ist es möglich durch Anhängen einer Ellipse an den letzten Parameter im Aufruf einer variadischen Funktion, direkt ein Slice an Stelle einzelner Parameter zu übergeben. Es folgt ein Beispiel analog zu obigem C#-Beispiel.

// Deklariere eine Funktion Sum, die mit beliebig viele Parameter vom Typ int aufgerufen
// wird und die Summe ihrer Parameter zurückgibt.
func Sum(x ...int) (n int) {
    for i := range x { // Iteriere über alle Indizes von x
        n += x[i]
    }
 
    return
}
 
// Beispielfunktion zum Aufruf der Funktion Sum()
func ExampleSum() {
    Sum() // leere Summe. Gibt 0 zurück
    Sum(1, 2, 3) // Gibt 6 zurück. x hat den Wert []int{1, 2, 3}
    v := []int{23, 42, 1337}
    Sum(v...) // Wie Sum(23, 42, 1337)
}

Java[Bearbeiten]

Auch in Java verwendet man in der Deklaration die Ellipse. Hier spricht man von Methoden mit variabler Argumentanzahl, oder kurz Varargs.[6] Im Gegensatz zu C und C++ wird aber der Typ mit angegeben. Im Hintergrund wird die Parameterliste in ein Array übersetzt, so dass auch innerhalb des Funktionsrumpfes der Parameter wie ein Array behandelt werden muss.[7]

JavaScript[Bearbeiten]

In JavaScript werden die beliebig vielen Funktionsargumente dem arguments-Objekt übergeben, das ein Array-artiges Objekt mit den zusätzlichen Eigenschaften arguments.length und arguments.callee ist. Mit dem arguments-Objekt können sogar die Funktionsparameter überschrieben werden, wie das nachfolgende Beispiel zeigt.

function meineFunk(x) {
    arguments[0] = 5; // die Variable x wird hier überschrieben!
    ...               // x ist nun 5.
}

PHP[Bearbeiten]

PHP unterstützt erst ab Version 4 variadische Funktionen, frühere Versionen von PHP boten keinen derartigen Mechanismus. Es wird kein besonderes Kennzeichen in der Funktionsdeklaration verwendet. Die Argumente können mit Hilfe spezieller Funktionen ausgewertet werden.[8]

Ruby[Bearbeiten]

In Ruby werden variable Argumentanzahlen durch einen Stern vor dem Parameternamen gekennzeichnet.[9] Auch hier wird dieser Parameter als ein Array behandelt, in dem alle Argumente gesammelt werden, die der vorgegeben Anzahl an Argumenten folgen.

Python[Bearbeiten]

Python bietet dieselbe Funktionalität wie Ruby. Darüber hinaus kann man überzählige Argumente benennen und deren Namen zusammen mit dem Wert in einer Tabelle („Wörterbuch“ im Python-Jargon) speichern, wenn Parameternamen zwei Sterne vorangestellt sind.[10]

Haskell[Bearbeiten]

Haskell erlaubt es nicht direkt, variable Argumentanzahlen zu verwenden, allerdings kann man dies über trickreiche Verwendung von Typklassen nahezu beliebig nachbilden. (So sind mit einer entsprechenden Implementation z.B. auch typsichere variadische Funktionen mit verschiedenen Argumenttypen möglich).[11][12]

Siehe auch[Bearbeiten]

Einzelnachweise[Bearbeiten]

  1. Variable Argumentlisten in C. Abgerufen am 9. September 2010.
  2. Definition von printf. Abgerufen am 9. September 2010 (englisch).
  3. Ellipses (and why to avoid them). Abgerufen am 9. September 2010 (englisch).
  4. Params in C#. Abgerufen am 23. August 2013 (englisch).
  5. Spezifikation der Sprache Go. Abgerufen am 26. März 2014 (englisch).
  6. Varargs in Java. Abgerufen am 26. März 2014.
  7. Varargs in Java im Sprachüberblick auf oracle.com. Abgerufen am 1. September 2011 (englisch).
  8. Variadische Funktionen in PHP. Abgerufen am 9. September 2010.
  9.  David Thomas, Andrew Hunt: Programmieren mit Ruby. Addison-Wesley, München 2002, ISBN 3-8273-1965-X, S. 281 (eingeschränkte Vorschau in der Google-Buchsuche).
  10. Abschnitt Function Definition in der Python-Schnellübersicht. Abgerufen am 9. September 2010 (englisch).
  11. Implementierung in Haskell mit detaillierter Beschreibung. Abgerufen am 12. August 2010 (englisch).
  12. Beschreibung des Vorgehen bei der Haskell-Variante von printf zur Erzeugung einer polyvariadischen Funktion. Abgerufen am 12. August 2010 (englisch).