Standardwert für Strukturelement in C.


82

Ist es möglich, Standardwerte für ein Strukturelement festzulegen? Ich habe Folgendes versucht, aber es würde einen Syntaxfehler verursachen:

typedef struct
{
  int flag = 3;
} MyStruct;

Fehler:

$ gcc -o testIt test.c 
test.c:7: error: expected ‘:’, ‘,’, ‘;’, ‘}’ or ‘__attribute__’ before ‘=’ token
test.c: In function ‘main’:
test.c:17: error: ‘struct <anonymous>’ has no member named ‘flag’

Sie können eine Initialisierungsfunktion für die Struktur erstellen.
Sgarizvi

4
Nicht in C. Sie können eine Funktion erstellen, die eine Struktur mit den gewünschten Werten zurückgibt.
Vaughn Cato

Wenn Sie es erstellen, können Sie die Werte wie folgt
Fantastic Mr Fox

Für C ++ - Strukturen können Sie Standarddaten im Konstruktor
Zac

Antworten:


122

Struktur ist ein Datentyp . Sie geben einem Datentyp keine Werte. Sie geben Instanzen / Objekten von Datentypen Werte.
Also nein, das ist in C nicht möglich.

Stattdessen können Sie eine Funktion schreiben, die die Initialisierung für die Strukturinstanz ausführt.

Alternativ können Sie Folgendes tun:

struct MyStruct_s 
{
    int id;
} MyStruct_default = {3};

typedef struct MyStruct_s MyStruct;

Und initialisieren Sie Ihre neuen Instanzen dann immer wie folgt:

MyStruct mInstance = MyStruct_default;

3
Wenn ich ein globales Array habe: 'MyStruct arr [MAX_SIXE];', wie kann die Funktion verwendet werden? (HINWEIS: Ich kann keine init () -Funktion haben, die das gesamte Mitglied
durchläuft

10
MyStruct_default sollte als const deklariert werden.
Lundin

1
Danke für deine Antwort. Ich habe eine Code-Sandbox erstellt, um sie online zu testen. Zuerst hatte
ich

52

Sie können es nicht auf diese Weise tun

Verwenden Sie stattdessen Folgendes

typedef struct
{
   int id;
   char* name;
}employee;

employee emp = {
.id = 0, 
.name = "none"
};

Sie können Makro verwenden, um Ihre Instanzen zu definieren und zu initialisieren . Dies erleichtert Ihnen jedes Mal, wenn Sie eine neue Instanz definieren und initialisieren möchten.

typedef struct
{
   int id;
   char* name;
}employee;

#define INIT_EMPLOYEE(X) employee X = {.id = 0, .name ="none"}

Wenn Sie in Ihrem Code eine neue Instanz mit Mitarbeitertyp definieren müssen, rufen Sie dieses Makro einfach wie folgt auf:

INIT_EMPLOYEE(emp);

1
Nicht gut, wenn Sie möchten, dass die Übergabe an den Parameter die Anforderungen nicht erfüllt.

18

Ich stimme Als zu, dass Sie zum Zeitpunkt der Definition der Struktur in C nicht initialisieren können. Sie können die Struktur jedoch zum Zeitpunkt der Erstellung der unten gezeigten Instanz initialisieren.

In C,

 struct s {
        int i;
        int j;
    };

    struct s s_instance = { 10 ,20 };

In C ++ ist es möglich, einen direkten Wert für die Definition der unten angegebenen Struktur anzugeben

struct s {
    int i;

    s(): i(10)
    {
    }
};

13

Du kannst tun:

struct employee_s {
  int id;
  char* name;
} employee_default = {0, "none"};

typedef struct employee_s employee;

Und dann müssen Sie nur noch daran denken, die Standardinitialisierung durchzuführen, wenn Sie eine neue Mitarbeitervariable deklarieren:

employee foo = employee_default;

Alternativ können Sie Ihre Mitarbeiterstruktur einfach immer über eine Factory-Funktion erstellen.


8

Wenn Sie verwenden gcc, können Sie designated initializersbei der Objekterstellung geben .

typedef struct
{
   int id=0;
   char* name="none";
}employee;

employee e = 
{
 .id = 0;
 .name = "none";
};

Oder verwenden Sie einfach die Array-Initialisierung.

employee e = {0 , "none"};


1
Ich habe gesehen, dass einige Codes auch Doppelpunkte für bestimmte Initialisierer verwenden, mehr in dieser Frage: stackoverflow.com/questions/1601201/…
sdaau

7

Erstellen Sie eine Standardstruktur, wie in den anderen Antworten erwähnt:

struct MyStruct
{
    int flag;
}

MyStruct_default = {3};

Der obige Code funktioniert jedoch nicht in einer Header-Datei - Sie erhalten folgende Fehlermeldung : multiple definition of 'MyStruct_default'. Verwenden Sie externstattdessen in der Header-Datei Folgendes, um dieses Problem zu lösen :

struct MyStruct
{
    int flag;
};

extern const struct MyStruct MyStruct_default;

Und in der cDatei:

const struct MyStruct MyStruct_default = {3};

Ich hoffe, dies hilft allen, die Probleme mit der Header-Datei haben.


Ein Kommentar ein paar Jahre später: Es ist wahrscheinlich sinnvoller, wenn Sie dies direkt in der Header-Datei tun könnten.
David Callanan

5

Um die vorhandenen Antworten zu ergänzen, können Sie ein Makro verwenden, das einen Strukturinitialisierer verbirgt:

#define DEFAULT_EMPLOYEE { 0, "none" }

Dann in Ihrem Code:

employee john = DEFAULT_EMPLOYEE;

3

Sie können eine Initialisierungsfunktion implementieren:

employee init_employee() {
  empolyee const e = {0,"none"};
  return e;
}

Es wird darauf hingewiesen, dass das C-Strukturvariablenobjekt e (const oder nicht) verschwindet, wenn der Block, in dem es definiert ist, beendet wird. Wenn es sich um einen Zeiger handelt, tritt das Problem mit dem baumelnden Zeiger auf. Es ist also keine gute Lösung, wenn der Rückgabetyp ein Zeiger ist. Der beste Weg ist, ein statisches globales Strukturvariablenobjekt mit Standardwerten unter Verwendung von C-Strukturinitialisierern zu haben und die Set- und Get-Funktionen für die Variable zu verwenden, um ihre Werte während der Programmlaufzeit zu ändern. Oder übergeben Sie ein lokales Strukturvariablenobjekt als Parameter an eine Set-Funktion und ändern Sie deren Eigenschaftswerte innerhalb der Set-Funktion.
Ecle

2
Sorry, aber das ist einfach falsch @ecle. Der Rückgabewert ist eine nackte Struktur, kein Zeiger. Es wird kopiert und nicht als Referenz zurückgegeben. Ehrlich gesagt wird der Compiler wahrscheinlich das Beste daraus machen.
Bitmaske

@bismask Versteh mich nicht falsch. Ich habe erwähnt, ob die Funktion einen Zeiger zurückgibt, wenn es sich um einen Zeiger handelt . Vielleicht haben Sie meinen vorherigen Kommentar vor meiner letzten Bearbeitung kommentiert.
Ecle

2

Sie können eine Funktion verwenden, um struct wie folgt zu initialisieren:

typedef struct
{
    int flag;
} MyStruct;

MyStruct GetMyStruct(int value)
{
    MyStruct My = {0};
    My.flag = value;
    return My;
}

void main (void)
{
    MyStruct temp;
    temp = GetMyStruct(3);
    printf("%d\n", temp.flag);
}

BEARBEITEN:

typedef struct
{
    int flag;
} MyStruct;

MyStruct MyData[20];

MyStruct GetMyStruct(int value)
{
    MyStruct My = {0};
    My.flag = value;
    return My;
}

void main (void)
{
    int i;
    for (i = 0; i < 20; i ++)
        MyData[i] = GetMyStruct(3);

    for (i = 0; i < 20; i ++)
        printf("%d\n", MyData[i].flag);
}

2
Was ist, wenn ich ein globales Array von Strukturen haben möchte, wie schlagen Sie vor, GetMyStruct () aufzurufen?
user1508893

Sollte GetMyStruct nicht malloc verwenden?
Dmitry


1

Wenn Sie diese Struktur nur einmal verwenden , dh eine globale / statische Variable erstellen, können Sie typedefdiese Variable sofort entfernen und initialisieren:

struct {
    int id;
    char *name;
} employee = {
    .id = 0,
    .name = "none"
};

Danach können Sie employeein Ihrem Code verwenden.


0

Eine Initialisierungsfunktion für eine Struktur ist eine gute Möglichkeit, ihr Standardwerte zuzuweisen:

Mystruct s;
Mystruct_init(&s);

Oder noch kürzer:

Mystruct s = Mystruct_init();  // this time init returns a struct

Wenn ich ein globales Array habe: 'MyStruct arr [MAX_SIXE];', wie kann die Funktion verwendet werden? (HINWEIS: Ich kann keine init () -Funktion haben, die das gesamte Mitglied
durchläuft

0

Ein weiterer Ansatz für Standardwerte. Erstellen Sie eine Initialisierungsfunktion mit demselben Typ wie die Struktur. Dieser Ansatz ist sehr nützlich, wenn Sie großen Code in separate Dateien aufteilen.

struct structType{
  int flag;
};

struct structType InitializeMyStruct(){
    struct structType structInitialized;
    structInitialized.flag = 3;
    return(structInitialized); 
};


int main(){
    struct structType MyStruct = InitializeMyStruct();
};

0

Sie können eine Funktion dafür erstellen:

typedef struct {
    int id;
    char name;
} employee;

void set_iv(employee *em);

int main(){
    employee em0; set_iv(&em0);
}

void set_iv(employee *em){
    (*em).id = 0;
    (*em).name = "none";
}

0

Ein anderer Ansatz, wenn die Struktur dies zulässt, besteht darin, ein #define mit den darin enthaltenen Standardwerten zu verwenden:

#define MYSTRUCT_INIT { 0, 0, true }

typedef struct
{
    int id;
    int flag;
    bool foo;
} MyStruct;

Verwenden:

MyStruct val = MYSTRUCT_INIT;

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.