2016-05-14 17 views
15

Sono un programmatore C principiante, ieri ho imparato l'uso delle strutture C e la possibile applicazione di questi sulla risoluzione di problemi specifici. Tuttavia, quando stavo sperimentando il mio C IDE (Codeblocks 16.01) per apprendere questo aspetto della programmazione in C, ho riscontrato uno strano problema. Il codice è il seguente:"errore: assegnazione all'espressione con errore di tipo array" quando assegno un campo struct (C)

#include <stdio.h> 

#define N 30 

typedef struct{ 
    char name[N]; 
    char surname[N]; 
    int age; 
} data; 

int main() { 
    data s1; 
    s1.name="Paolo"; 
    s1.surname = "Rossi"; 
    s1.age = 19; 
    getchar(); 
    return 0; 
} 

Durante la compilazione, il compilatore (GCC 4.9.3-1 in Windows) mi ha segnalato un errore che dice

"error: assignment to expression with array type error"

su istruzione

s1.name="Paolo" 
s1.surname="Rossi" 

while if I

data s1 = {"Paolo", "Rossi", 19}; 

funziona. Cosa sto sbagliando?

+6

Hai scoperto una delle differenze tra assegnazione e inizializzazione. –

+1

Puoi essere più specifico? grazie;) – Chief096

+0

Puoi scrivere 's1 = (const data) {" Paolo "," Rossi ", 19};' –

risposta

23

Siete di fronte problema in

s1.name="Paolo"; 

perché, nel LHS, si sta utilizzando una matrice di tipo, che non è assegnabile.

di elaborare, da C11, capitolo §6.5.16

assignment operator shall have a modifiable lvalue as its left operand.

e, per quanto riguarda il lvalue modificabile, dal capitolo §6.3.2.1

A modifiable lvalue is an lvalue that does not have array type, [...]

È necessario utilizzare strcpy() per copia nell'array.

Detto questo, data s1 = {"Paolo", "Rossi", 19}; funziona correttamente, perché questo non è un incarico diretto che coinvolge l'operatore di assegnazione. Lì stiamo usando un elenco di inizializzazione di parentesi graffe per fornire i valori iniziali dell'oggetto . Che segue la legge di inizializzazione, come indicato nel capitolo §6.7.9

Each brace-enclosed initializer list has an associated current object. When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: array elements in increasing subscript order, structure members in declaration order, and the first named member of a union.[....]

+1

Se ho 'char * b =" Ciao "', e se ho 'char c [] = "ciao" ', entrambi funzionano, se per prima cosa faccio' b = "helloworld" ', funziona anche, ma per il secondo caso se faccio' c = "helloworld" ', non perché? –

+0

@SurajJain è esattamente ciò che viene spiegato nella risposta. Non è possibile assegnare a un array. –

+1

È stato veloce. –

5

prega di consultare questo esempio qui: Accessing Structure Members

Ci viene spiegato che il modo giusto per farlo è come questo:

strcpy(s1.name , "Egzona"); 
printf("Name : %s\n", s1.name); 
+0

questo ha un overhead di chiamata di funzione extra (che i compilatori possono scegliere di inline ma generalmente non lo fanno), che fa un ciclo piuttosto che inline e questo ciclo non viene eliminato se la macchina su cui si sta compilando può copiare tutto in una sposta, fa sempre almeno un'iterazione. Sembra che non possa essere risolto senza preelaborare il codice sorgente poiché C non lo farà per te. 'char x [2] = {'h', 0}; * (char (*) [2]) & x = * (char (*) [2]) & x; 'dovrebbe essere significativamente più veloce di' strcpy (x, x, 2) 'se fosse valido C. – Dmitry

Problemi correlati