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’
user1508893
quelle
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;
Alok Speichern
quelle
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);
MOHAMED
quelle
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)
    {
    }
};
Chirag Desai
quelle
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.

Donnie
quelle
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"};

Omkant
quelle
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.

David Callanan
quelle
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;
Bogdan Alexandru
quelle
3

Sie können eine Initialisierungsfunktion implementieren:

employee init_employee() {
  empolyee const e = {0,"none"};
  return e;
}
Bitmaske
quelle
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);
}
Adeel Ahmed
quelle
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
2

Sie können die Kombination von C-Präprozessorfunktionen mit Varargs , zusammengesetzten Literalen und festgelegten Initialisierern für maximalen Komfort verwenden:

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

#define EMPLOYEE(...) ((employee) { .id = 0, .name = "none", ##__VA_ARGS__ })

employee john = EMPLOYEE(.name="John");  // no id initialization
employee jane = EMPLOYEE(.id=5);         // no name initialization
Maxim Kulkin
quelle
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.

HaxtraZ
quelle
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
Israel Unterman
quelle
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();
};
Landwirt
quelle
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";
}
Joseph Pena
quelle
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;
CSharpino
quelle
-4

Ich denke, auf folgende Weise können Sie es tun:

typedef struct
{
  int flag : 3;
} MyStruct;
Shibu J.
quelle
Das ist eigentlich ein Bitfeld, kein Standardwert. en.cppreference.com/w/cpp/language/bit_field
Bruno Alexandre Rosa