2015-05-26 8 views
5

Ich habe einen unordentlichen Code-Block wieHat C eine Kurzform, um eine Struktur mit malloc zu initialisieren und seine Felder zu setzen?

result = (node*)malloc(sizeof(node)); 
result->fx = (char*)malloc(sizeof(char) * 2); 
result->fx[0]='x'; result->fx[1]='\0'; 
result->gx = NULL; result->op = NULL; result->hx = NULL; 

, wo ich ein Element vom Typ

typedef struct node 
{ 
    char * fx; // function 
    struct node * gx; // left-hand side 
    char * op; // operator 
    struct node * hx; // right-hand side 
} node; 

Gibt es eine Kurzform zu tun, dass initialisieren? Mit anderen Worten, gibt es einen Weg zu tun, wie ich es in C++ tun würde?

result = new node { new char [] {'x','\0'}, NULL, NULL, NULL }; 
+1

Leider nicht. Wenn Sie alle Felder mit 0 initialisieren möchten, können Sie 'calloc' verwenden. Und tippen Sie nicht das Ergebnis von "malloc". –

+1

Wenn 'fx' immer mit der gleichen Größe malloc'd ist, dann könnten Sie es zu einem Array machen –

+1

Können Sie klären, ob '' x'' hardcoded sein soll, oder ob es Pseudocode ist und Sie initialisieren wollen ' fx' mit Daten, die beispielsweise vom Benutzer eingegeben wurden? –

Antwort

7

Sie können Ihre eigenen Wrapper-Funktion schreiben:

static node *getNewNode(char *fx) { 
    node *p = calloc(1, sizeof *p); 
    if(p && fx) { 
    p->fx = malloc(strlen(fx) + 1); 
    if(!p->fx) { 
     free(p); 
     p = null; 
    } else { 
     strcpy(p->fx, fx); 
    } 
    } 
    return p; 
} 

Später Sie dies als anrufen:

node *result = getNewNode("x"); 
if(result) ... 

Welche besser lesbar und weniger cluttery ist.

5

Sie können nicht zwei verschachtelte mallocs haben und alles auf einmal initialisieren. Allerdings würde ich folgendes Design vorschlagen:

typedef struct node 
{ 
    char fx[2], op[2]; // first byte being null indicates not-present 
    struct node *gx, *hx; 
} node; 

und dann können Sie einfacher schreiben:

node *result = malloc(sizeof *result); 

if (!result) 
    errorhandling...... 

// C89 
node temp = { "x" }; 
*result = temp; 

// C99 
*result = (node){ .fx = "x" }; 

Das C99 Beispiel verwendet Verbindung Literale und bezeichnet initializers, die in C, aber nicht C++ . Weitere Informationen finden Sie unter How to initialize a struct in ANSI C.

Sie müssen nicht den angegebenen Initialisierer verwenden, es verringert jedoch die Fehlermöglichkeit. Alle nicht explizit initialisierten Strukturelemente werden wie von 0 initialisiert.

In beiden Fällen wird das theoretische temporäre Objekt wegoptimiert, so dass diese Lösung nicht als ineffizient betrachtet werden sollte.

+0

Es könnte erwähnenswert sein, dass "x" ein String-Literal ist und daher der Endwert von "result-> fx", auf den verwiesen wird, nicht änderbar ist. Dies ist eine Einschränkung des Ansatzes des OP. – alk

+1

Das bedeutet, dass Sie ein zusätzliches temporäres Objekt auf dem Stapel erstellen. Eine bessere Lösung wäre vielleicht, einen statischen statischen Knoten zu erstellen, bei dem bereits alles vorhanden ist. – Lundin

+0

@Lundin Ich kompilierte mit '-O1' und es gibt kein temporäres Objekt auf dem Stapel erstellt. Die Assembler-Anweisung 'movq' wird benutzt, um '' x'' direkt in den Malloc'd-Platz zu platzieren. Können Sie den Code für Ihren Vorschlag anzeigen? (Bedenkt man, dass OP wahrscheinlich beabsichtigt, dass "x" ein zur Laufzeit erhaltener Wert ist) –

Verwandte Themen