2015-05-26 19 views
5

Ho un blocco disordinato di codice comeC ha un modo stenografico per inizializzare una struct con malloc e impostare i suoi campi?

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; 

dove ho inizializzare un elemento di tipo

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

C'è un modo veloce di fare questo? In altre parole, c'è un modo per fare come farei in C++?

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

Purtroppo no. Se vuoi inizializzare tutti i campi con 0, puoi usare 'calloc'. E non digitare il risultato di 'malloc'. –

+1

Se 'fx' sarà sempre malloc'd con le stesse dimensioni, potreste renderlo un array –

+1

Potete chiarire se' 'x'' deve essere hardcoded, o se questo è pseudocodice e volete inizializzarlo ' fx' con dati che sono stati inseriti dall'utente, ad esempio? –

risposta

7

È possibile scrivere la propria funzione avvolgitore:

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; 
} 

In seguito è possibile chiamare questo come:

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

Che è più leggibile e meno cluttery.

5

Non è possibile avere due mallocs nidificati e inizializzare tutto in una volta. Tuttavia vorrei suggerire il seguente disegno:

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

e poi si può più semplicemente scrivere:

node *result = malloc(sizeof *result); 

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

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

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

L'esempio C99 utilizza letterali composti e inizializzatori designati che sono in C, ma non C++ . Per ulteriori discussioni vedi How to initialize a struct in ANSI C.

Non è necessario utilizzare l'inizializzatore designato ma riduce la possibilità di errore. Qualsiasi membro della struct non inizializzato in modo esplicito verrà inizializzato come se fosse 0.

In entrambi i casi, l'oggetto temporaneo teorico verrà ottimizzato, pertanto questa soluzione non deve essere considerata affatto inefficiente.

+0

Vale la pena ricordare che '" x "' è una stringa letterale e quindi il valore finale di 'result-> fx' che punta a non sarà modificabile. Questo è un limite all'approccio dell'OP. – alk

+1

Ciò significa che dovrai creare un altro oggetto temporaneo nello stack. Una soluzione migliore sarebbe forse quella di creare un 'nodo const statico' con tutto già in posizione. – Lundin

+0

@Lundin Ho compilato con '-O1' e non ci sono oggetti temporanei creati nello stack. L'istruzione di montaggio 'movq' è usata per posizionare' 'x'' direttamente nello spazio malloc'd. Puoi mostrare il codice per il tuo suggerimento? (tenendo presente che OP probabilmente intende '" x "' come valore ottenuto in fase di runtime) –