Ich habe folgenden C-Code:

struct {
    short s;
    int n;
} variableName;

Ich möchte eine Funktion schreiben, um diese Variable so zu erfassen

void func(MyStruct* var){
    //do stuff
}

func(&variableName);

Ich möchte dies tun, ohne eine Definition für die Struktur anzugeben. Gibt es eine Möglichkeit, variableName zu erfassen?

0
JComputerScience 18 Jän. 2019 im 01:29

3 Antworten

Beste Antwort

Nein, Sie können eine "anonyme" Struktur nicht an eine Funktion in C übergeben. Sie können Ihre Funktion natürlich so definieren, dass die Argumente einzeln akzeptiert werden:

void func(short s, int n) { ... }

Oder Sie können die MyStruct -Struktur an einer Stelle definieren, für die sowohl die Funktion als auch der aufrufende Code sichtbar sind. Beachten Sie, dass die gesamte Struktur dabei als Wert (Kopie) übergeben wird. Dies kann das gewünschte Verhalten sein (oder auch nicht).

Möglicherweise suchen Sie eher nach einem "Wörterbuch" - oder "assoziativen Array" - oder "Hash" -Typ, den viele andere Sprachen mit beliebigen Schlüsselwertpaaren bereitstellen. Pure C hat hierfür keine Möglichkeit; Der Compiler möchte das Layout einer Struktur im Voraus wissen.

(Ich bin mir nicht sicher, ob Sie nach einer etwas esoterischeren Idee fragen, die die Zusammensetzung einer Struktur verbirgt und ein "undurchsichtiges Handle" aus und in eine API umgibt. Es gibt Möglichkeiten, dies in C zu strukturieren. aber bitte sag es, wenn du darüber sprichst.)

2
Ben Zotto 17 Jän. 2019 im 22:40

Völlig übersehen "Ich möchte dies tun, ohne eine Definition für die Struktur anzugeben. Gibt es eine Möglichkeit, Variablenname zu erfassen?" im OP, es sei denn, es wurde danach bearbeitet. Die Frage ist jetzt weniger sinnvoll, aber hier ist, wie Sie normalerweise eine Struktur an eine Funktion für zukünftige Leser übergeben können.

#include <stdio.h>

    struct StructName{
        short s;
        int n;
    };

    void func(struct StructName struct_var){
            printf("Param values are: %4X %4X\n", struct_var.s & 0xFFFF, struct_var.n & 0xFFFF);
        }

    int main(){
        struct StructName struct_var;
        struct_var.s = 0xDEAD;
        struct_var.n = 0xBEEF;
        func(struct_var);
    }

// Es sieht so aus, als würden Sie versuchen, die Definition als Variable zu verwenden. Hier lautet die Definition StructName und die Variable struct_var.

Dieser Beispielcode gibt Folgendes aus: Parameterwerte sind: DEAD BEEF

2
Bwebb 17 Jän. 2019 im 22:41

Wenn Sie clang oder gcc verwenden, können Sie möglicherweise typeof verwenden:

struct foo {
    struct {
        int i;
    } anon;
} foo;

void do_something(typeof(foo.anon)* member) {
    member->i = 1;
}

Wenn es keine globale Instanz Ihres Typs gibt, können Sie möglicherweise typeof((struct foo){}.anon) verwenden.

Dies hat viele Nachteile. Die offensichtlichsten sind:

  • es ist nicht standard und bindet dich an clang / gcc
  • Es ist verdammt hässlich
  • es könnte sich sowieso nicht so verhalten, wie Sie es erwarten

Zum Beispiel haben strukturell äquivalente anonyme Typen nicht denselben Typ, also in etwa so:

struct foo {
    struct {
        int i;
    } anon1;
    struct {
        int i;
    } anon2;
} foo;

anon1 und anon2 haben beide einen unterschiedlichen Typ, was bedeutet, dass typeof einer von ihnen nicht verwendet werden kann, um auf beide zu verweisen.

Auf lange Sicht werden Sie mit ziemlicher Sicherheit feststellen, dass es sich lohnt, die Strukturen zu benennen, insbesondere wenn Sie sie als Funktionsargumente verwenden. Wenn Sie beispielsweise Ihre Variable über einen Header verfügbar machen möchten, müssen Sie meiner Meinung nach ziemlich hart arbeiten, um sie anonym zu halten.

Obwohl es nicht besonders hübsch und nicht mit C ++ kompatibel ist, fügt C den Namen verschachtelter Deklarationen in den globalen Namespace ein. Dies ist also portabel und keine große Codeänderung beim Frontload:

struct {
    struct not_anon {
        int i;
    } anon;
} foo;

void do_something(struct not_anon* member) {
    member->i = 1;
}
0
zneak 17 Jän. 2019 im 23:40