2016-05-14 11 views
15

Я начинающий программист C, вчера я узнал, как использовать C-структуры и возможное их применение в отношении разрешения специфические проблемы. Однако, когда я экспериментировал с моей C IDE (Codeblocks 16.01), чтобы изучить этот аспект программирования на C, я столкнулся с какой-то странной проблемой. Код состоит в следующем:«ошибка: присваивание выражению с ошибкой типа массива», когда я назначаю поле структуры (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; 
} 

Во время компиляции, компилятор (GCC 4.9.3-1 под Windows) сообщил мне ошибку, которая говорит

"error: assignment to expression with array type error"

по инструкции

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

в то время как, если я принимаю

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

это работает. Что я делаю неправильно?

+6

Вы обнаружили одно из отличий между назначением и инициализацией. –

+1

Можете ли вы уточнить? спасибо;) – Chief096

+0

Вы можете написать 's1 = (const data) {" Paolo "," Rossi ", 19};' –

ответ

23

Вы столкнулись проблемы в

s1.name="Paolo"; 

, потому что, в LHS, вы используете массив тип, который не является назначаемые.

Выработать из C11, глава §6.5.16

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

и относительно модифицируемых Lvalue из главы §6.3.2.1

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

Вы должны использовать strcpy() для копия в массив.

Это говорит о том, что data s1 = {"Paolo", "Rossi", 19}; отлично работает, поскольку это не является прямым назначением с участием оператора назначения. Там мы используем список инициализаторов , заключенный в скобки, чтобы предоставить начальные значения объекта . Это следует закон инициализации, как указано в главе §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

Если я habe 'char * b =" Hello "', и если у меня есть 'char c [], = "hello" ', оба работают, если для первого случая я делаю' b = "helloworld" ', он тоже работает, но для второго случая, если я делаю' c = "helloworld" ', это не почему так? –

+0

@SurajJain - это именно то, что объясняется в ответе. Вы не можете назначить массив. –

+1

Это было быстро. –

5

Пожалуйста, проверьте этот пример здесь: Accessing Structure Members

Там объясняется, что правильный способ сделать это, как это:

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

у этого есть дополнительная служебная функция вызова функции (какие компиляторы могут выбрать встроенную, но обычно этого не делают), которая делает цикл, а не встроенный, и этот цикл не исключается, если машина, которую вы компилируете, может скопировать все в одном move, он всегда выполняет хотя бы одну итерацию. Похоже, что это невозможно решить без предварительной обработки исходного кода, так как C не сделает это за вас. 'char x [2] = {'h', 0}; * (char (*) [2]) & x = * (char (*) [2]) & x; 'должен быть значительно быстрее, чем' strcpy (x, x, 2) ', если он действителен C. – Dmitry