Funktionen in der Struktur

Lesezeit: 6 Minuten

Benutzer-Avatar
Schweta

Können Strukturen Funktionen enthalten?

  • Sie können, aber es gibt keinen inhärenten Vorteil in der üblichen C-Programmierung. In C befinden sich alle Funktionen ohnehin im globalen Raum, sodass Sie keine Informationen verbergen, indem Sie sie in eine Funktion stecken. Das Beispiel von paxdiablo ist eine Möglichkeit, Funktionen in einer Struktur zu organisieren, aber Sie müssen sehen, dass sowieso jede einzelne dereferenziert werden muss, um sie zu verwenden. Die Standardorganisationsstruktur von C ist die Datei, mit den Schnittstellen im Header und den Implementierungen in der Quelle. So wird libc gemacht und so werden fast alle C-Bibliotheken gemacht.

    – Chris Reid

    22. Juni 2017 um 21:13 Uhr

Benutzer-Avatar
paxdiablo

Nein, aber sie können Funktionen enthalten Zeiger.

Wenn Sie beabsichtigen, eine Form von Polymorphismus in C durchzuführen, dann ist dies möglich:

typedef struct {
    int (*open)(void *self, char *fspec);
    int (*close)(void *self);
    int (*read)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
    int (*write)(void *self, void *buff, size_t max_sz, size_t *p_act_sz);
    // And data goes here.
} tCommClass;

Das typedef oben war für eine Struktur, die ich für eine Allzweck-Kommunikationsbibliothek erstellt habe. Um die Variable zu initialisieren, würden Sie:

tCommClass *makeCommTcp (void) {
    tCommClass *comm = malloc (sizeof (tCommClass));
    if (comm != NULL) {
        comm->open  = &tcpOpen;
        comm->close = &tcpOpen;
        comm->read  = &tcpOpen;
        comm->write = &tcpWrite;
    }
    return comm;
}

tCommClass *makeCommSna (void) {
    tCommClass *comm = malloc (sizeof (tCommClass));
    if (comm != NULL) {
        comm->open  = &snaOpen;
        comm->close = &snaOpen;
        comm->read  = &snaOpen;
        comm->write = &snaWrite;
    }
    return comm;
}

tCommClass *commTcp = makeCommTcp();
tCommClass *commSna = makeCommSna();

Dann, um die Funktionen aufzurufen, so etwas wie:

// Pass commTcp as first params so we have a self/this variable
//   for accessing other functions and data area of object.
int stat = (commTcp->open)(commTcp, "bigiron.box.com:5000");

Auf diese Weise könnte ein einziger Typ für TCP, SNA, RS232 oder sogar Brieftauben verwendet werden, mit genau der gleichen Schnittstelle.

  • Ist dies also auch einer der Unterschiede zwischen s/w-Struktur und Klassen? Denn soweit ich weiß, ist der einzige Unterschied, dass die Struktur standardmäßig öffentlich und die Klasse standardmäßig privat ist

    – JoshMachine

    19. November 2010 um 7:41 Uhr

  • @Josh, ich denke, Sie haben tatsächlich Recht damit, dass öffentlich/privat der einzige Unterschied zwischen struct/union in C++ ist. Diese Frage bezog sich auf C. Ich vermute Funktionen sind erlaubt in C++ seit struct xyz { int fn(void); } a; funktionierte gut in g++.

    – paxdiablo

    19. November 2010 um 7:48 Uhr


  • Die runden Klammern commTcp.open sind unnötig.

    – Café

    19. November 2010 um 9:57 Uhr

  • Sie können tatsächlich Beispiele für Funktionen in Strukturen im Linux-Kernel-Code sehen. Sehen Sie sich den Linux-Kernel an: Documentation/vfs.txt

    – prap19

    19. November 2010 um 17:01 Uhr

Benutzer-Avatar
wkl

Bearbeiten Mehrdeutigkeiten durch die Verwendung von “Datentypen” beseitigt

Nicht in C. struct Typen können nur Daten enthalten.

Aus Abschnitt 6.7.2.1 des ISO C99-Standards.

Eine Struktur oder Vereinigung darf kein Element mit unvollständigem oder Funktionstyp enthalten (Daher darf eine Struktur keine Instanz von sich selbst enthalten, kann aber einen Zeiger auf eine Instanz von sich selbst enthalten), außer dass das letzte Mitglied einer Struktur mit mehr als einem benannten Mitglied einen unvollständigen Array-Typ haben kann; Eine solche Struktur (und jede Vereinigung, die möglicherweise rekursiv ein Mitglied enthält, das eine solche Struktur ist) darf kein Mitglied einer Struktur oder ein Element eines Arrays sein.

  • “Datentypen enthalten” ist gefährlich zweideutig (zumindest für einen C++-Benutzer, wo er Typen deklarieren kann) – “Daten enthalten” scheint genauer zu sein. Alles klar im Standard aber… :-).

    – Toni Delroy

    19. November 2010 um 8:38 Uhr

Benutzer-Avatar
Mohit Dabas

Nein, du kannst nicht. Eine Struktur kann keine Deklaration einer Funktion enthalten, aber sie kann eine Definition einer Funktion enthalten. Eine Struktur kann nur Datentypen, Zeiger, Zeiger auf verschiedene Funktionen enthalten. Sie können einen Zeiger auf eine Funktion erstellen und dann von der Struktur aus darauf zugreifen.

#include<iostream>
#include<cstring>
using namespace std;

struct full_name
{
  char *fname;
  char *lname;
  void (*show)(char *,char*);
};

void show(char *a1,char * a2)
{
  cout<<a1<<"-"<<a2<<endl;
}

int main()
{  
  struct full_name loki;
  loki.fname="Mohit";
  loki.lname="Dabas";
  loki.show=show;
  loki.show(loki.fname,loki.lname);

  return 0;     
}

Benutzer-Avatar
Benutzer513112

In C dürfen Strukturen nur Datenwerte enthalten und nicht die Funktionszeiger. In C nicht erlaubt, aber das Folgende funktioniert buchstäblich gut, wenn es mit gcc überprüft wird.

enter code here

#include <stdio.h>

struct st_func_ptr{
        int data;
        int (*callback) ();
};

int cb(){
        printf(" Inside the call back \n");
        return 0;
}

int main() {
        struct st_func_ptr sfp = {10, cb};

        printf("return value = %d \n",sfp.callback());

        printf(" Inside main\n");
        return 0;
}

Bin also verwirrt…

Benutzer-Avatar
Toni

Es ist alles in Ordnung. Im Linux-Kernel-Code finden Sie viele Strukturen, die Funktionen enthalten. wie zum Beispiel:

/*


* The type of device, "struct device" is embedded in. A class
 * or bus can contain devices of different types
 * like "partitions" and "disks", "mouse" and "event".
 * This identifies the device type and carries type-specific
 * information, equivalent to the kobj_type of a kobject.
 * If "name" is specified, the uevent will contain it in
 * the DEVTYPE variable.
 */
struct device_type {
        const char *name;
        struct attribute_group **groups;
        int (*uevent)(struct device *dev, struct kobj_uevent_env *env);
        void (*release)(struct device *dev);
        int (*suspend)(struct device * dev, pm_message_t state);
        int (*resume)(struct device * dev);
};

  • Nun, sie sind Zeiger auf Funktionen – ganz ähnlich, außer dass es einige Mühe kostet, sie zu initialisieren, es besteht die Gefahr, dass sie versucht werden, sie zu verwenden, wenn sie NULL oder anderweitig ungültig sind, und sie können zur Laufzeit geändert werden … .

    – Toni Delroy

    19. November 2010 um 8:39 Uhr

Benutzer-Avatar
Benutzer513391

Ja, es ist möglich, eine Funktion zu deklarieren, und die Funktionsdefinition ist nicht zulässig, und das sollte der Funktionszeiger sein.

Es basiert auf der C99-getaggten Struktur.

Lokesh V

  • Nun, sie sind Zeiger auf Funktionen – ganz ähnlich, außer dass es einige Mühe kostet, sie zu initialisieren, es besteht die Gefahr, dass sie versucht werden, sie zu verwenden, wenn sie NULL oder anderweitig ungültig sind, und sie können zur Laufzeit geändert werden … .

    – Toni Delroy

    19. November 2010 um 8:39 Uhr

Benutzer-Avatar
Chris Reid

Sie können, aber es gibt keinen inhärenten Vorteil in der üblichen C-Programmierung.

In C befinden sich alle Funktionen ohnehin im globalen Raum, sodass Sie keine Informationen verbergen, indem Sie sie in eine Funktion stecken. Das Beispiel von paxdiablo ist eine Möglichkeit, Funktionen in einer Struktur zu organisieren, aber Sie müssen sehen, dass sowieso jede einzelne dereferenziert werden muss, um sie zu verwenden.

Die Standardorganisationsstruktur von C ist die Datei, mit den Schnittstellen im Header und den Implementierungen in der Quelle.

So wird libc gemacht und so werden fast alle C-Bibliotheken gemacht.

Mit modernen C-Compilern können Sie Funktionen in derselben Quelldatei definieren und implementieren und sogar statische Funktionen in Header-Dateien implementieren. Dies führt leider zu einiger Verwirrung darüber, was wohin gehört, und Sie können ungewöhnliche Lösungen erhalten, wie z. B. Funktionen in Strukturen stopfen, reine Quellprogramme ohne Header usw. Auf diese Weise verlieren Sie den Vorteil, die Schnittstelle von der Implementierung zu trennen.

1373880cookie-checkFunktionen in der Struktur

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy