void func(int); für was ist der Parameter gut?



  • Hallo,

    ich lerne mir grad C++ (mit C/C++ Die Referenz von Markt & Technik)...
    meine Frage wäre:

    Welchen Sinn hat es bei einer Funktionsdeklaration einen Parameter ohne Bezeichner (nur der Typ) einzuführen?

    Beispiel:

    void func(int);
    

    Ich kann ja auf den Parameter nicht zugreifen, ohne dem Bezeichner 😕



  • In der Deklaration willst Du doch auch gar nicht darauf zugreifen. Hauptsache, in der Definition steht er.



  • Funktionsdeklaration ist doch zB. die Codezeile ( void func(int); ) die ich geschrieben habe?
    und Funktionsdefinition ist doch der Anweisungsteil?, dachte ich...

    jedenfalls: was nützt mir der Parameter ohne Bezeichner, wenn ich im Anweisungsteil nicht drauf zugreifen kann?



  • jakob190590 schrieb:

    jedenfalls: was nützt mir der Parameter ohne Bezeichner, wenn ich im Anweisungsteil nicht drauf zugreifen kann?

    void x(int, int); // Deklaration
    //..
    void x(int a, int b)
    {
     // ...
    }
    

    ..



  • func.hpp:

    #ifndef FUNC_HPP
    #define FUNC_HPP
    
    void func(int);
    
    #endif
    

    func.cpp:

    #include "func.hpp"
    
    void func(int bla)
    {
       bla / 0;
    }
    

    Jetzt klarer?



  • Das ist (nur) nützlich, wenn du die Funktion z.B. in einer Header-Datei deklarierst und in einer *.cpp Datei implementierst, um das Interface von der Implementierung zu trennen.

    Beispiel:

    Test.h

    #ifndef __TEST_H__
    #define __TEST_H__
    
    void func(int); //Deklaration der Funktion (ohne Definition)
    
    #endif
    

    Test.cpp

    #include <iostream>
    #include "Test.h"
    
    using namespace std;
    
    void func(int a) //Definition der Funktion (kein Semikolon hinter dieser Zeile + Implementierungsblock)
    {
        cout << a << endl;
    }
    

    main.cpp

    #include "Test.h"
    
    int main(void)
    {
        func(5);
        return 0;
    }
    

    Außerdem gibt es das gleiche in Grün wenn du in einer Klassendefinition die Implementierungen der Methoden nicht direkt angibst, sondern in einer seperaten Datei.

    Felix

    EDIT: Zu spät, das kommt davon, wenn man soviel erklärt 😃



  • void func(int);
    

    ist nur eine deklaration, auch signatur einer funktion genannt. die implementierung wird an irgendeiner anderen stelle stehen.

    void func(int);
    
    int main()
    {
      func(12);
    }
    
    void func(int i)
    {
      // mach was mit i
    }
    


  • aha, jetzt versteh ichs glaub ich!

    es ist also nur eine Vereinfachung, dass man nicht alle Parameter-Bezeichner in der Deklaration angeben muss. Das KANN man aber auch machen, oder?

    aha, beim forwarden kann man das auch machen...

    Danke an alle, jakob.



  • Kann dir auch vorkommen wenn du bsw. ein Basisklasse anlegst. Da hast du jetzt eine Funktion mit sagen wir mal 2 Parametern. In der abgeleiteten Klasse brauchst du die jetzt aber garnicht (also die Parameter) ... dann lässt man die Variablenbezeichner ebenfalls weg. (vgl. MS C++ 2005 W4 - Warning = Error)



  • Du meinst sicherlich eine virtuelle Funktion…



  • jakob190590 schrieb:

    es ist also nur eine Vereinfachung, dass man nicht alle Parameter-Bezeichner in der Deklaration angeben muss. Das KANN man aber auch machen, oder?

    Ich meine sogar man sollte es immer machen (Ausnahme: (D)Evils Szenario mit der virtuellen Funktion), denn so sieht man an der Deklaration meist sofort, was die Funktion erwartet und vor allem in welcher Reihenfolge (Voraussetzung: Sinnvolle Bezeichner).



  • was ist jetzt, bei folgendem Beispiel:

    Möglichkeit1:

    void func(int); //Vorwärts-Deklaration (forward)
    
    void func(int i) {}; //Definition
    

    Möglichkeit2:

    void func(int i); //Vorwärts-Deklaration (forward)
    
    void func(int i) {}; //Definition
    

    Möglichkeit3?

    void func(int j); //Vorwärts-Deklaration (forward) 
    //mit anderem Parameter-Bezeichner!
    
    void func(int i) {}; //Definition
    

    hier kommt kein compilerfehler...??



  • Warum sollte bei V3 ein Compiler-Fehler auftreten? Dem ist ziemlich egal wie du die Variablen bennenst(solange du sie nicht nutzt 😉 ). Darum ist auch V1 die beste.



  • Die Namen der Prototyp-Parameter gelten nur innerhalb des Funktionsprototyps - darum ist es letztlich egal, wie du sie dort nennst - oder ob du sie weglässt. Das ist z.B. ganz praktisch für Dokumentationszwecke:

    void print(int value_to_print);
    
    void print(int v)
    {
      ...
    }
    

    (übrigens kannst du auch bei der Funktionsdefinition den Parameternamen weglassen, aber dann kannst du den Parameter in der Funktion nicht ansprechen (brauchbar für unused-Parameter))



  • (D)Evil schrieb:

    Darum ist auch V1 die beste.

    Einspruch, s.o. und CStoll 😉

    Einfaches Beispiel: Du hast eine Funktion substr, die zwei Parameter offset und count erwartet, nur leider ist Dir die Reihenfolge entfallen. Nun schreibst Du mystr.substr und lässt Dich von Deiner IDE in den Header von string schicken. Dort steht jetzt die hilfreiche Angabe substr(size_t, size_t). Sehr aussagekräftig, nicht?



  • (D)Evil schrieb:

    Warum sollte bei V3 ein Compiler-Fehler auftreten? Dem ist ziemlich egal wie du die Variablen bennenst(solange du sie nicht nutzt 😉 ). Darum ist auch V1 die beste.

    Ebenso Einspruch.

    Man sollte immer vermeiden das man Definitionsdetail einblicken muss, es heißt ja auch das man gegen die Schnittstelle, nicht die Implementierung programmieren sollte.

    Aus diesem Grund muss eigentlich der Header einer fremden Klasse für das Programmieren voll und ganz ausreichen (Wer erst in die cpp-Datei schauen muss, unterliegt schneller der Versuchung Implementierungsdetails zu verwenden).

    Und nichts ist besser als sprechende Namen zu finden wenn man programmiert... Wie heißt es so schön, man sollte Programme in erster Linie lesbar für Menschen gestalten, und erst in zweiter für die Maschine.

    cu André



  • Nur der Vollständigkeit halber, unbenannte Parameter sind auch für Funktionen nützlich, die als Funktionszeiger an andere funktionen übergeben werden müssen.

    Z.B. verlangt EnumWindows eine Funktion der Form bool name(HWND hWnd, long l). Wenn man nun den long-Wert gar nicht benötigt, braucht man ihm auch keinen Namen zu geben.


Anmelden zum Antworten