|
структуры, доступ к полям |
|
|
|
Feb 8 2015, 10:08
|
Профессионал
    
Группа: Свой
Сообщений: 1 357
Регистрация: 12-04-05
Из: Петербург
Пользователь №: 4 079

|
вот у нас структура, через typedef Код typedef struct abc_s { int aa; int bb; } abc_t; создаю переменную этого типа Код abc_t abc; дальше, хочу присвоить значение полю aa в моей переменной Код abc.aa = 8; выдает ошибку. Почему? И как правильно? а затолкав в ф-ю - все нормально. Т.е. вне ф-ии нельзя, получается, проводить начальную инициализацию?
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 18)
|
Feb 8 2015, 12:16
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(Метценгерштейн @ Feb 8 2015, 15:14)  нельзя одно поле инициализировать вне ф-ии. Можно только всю структуру пачкой. Можно! Это GNU-расширение стандарта. Нужно использвать компилятор, это умеющий, например, gcc: CODE static struct mtd_partition myboard_nand_partitions[] = { /* All the partition sizes are listed in terms of NAND block size */ { .name = "xloader-nand", .offset = 0, .size = 4*(SZ_128K), .mask_flags = MTD_WRITEABLE }, { .name = "uboot-nand", .offset = MTDPART_OFS_APPEND, .size = 14*(SZ_128K), .mask_flags = MTD_WRITEABLE }, { .name = "params-nand", .offset = MTDPART_OFS_APPEND, .size = 2*(SZ_128K) }, { .name = "linux-nand", .offset = MTDPART_OFS_APPEND, .size = 40*(SZ_128K) }, { .name = "jffs2-nand", .size = MTDPART_SIZ_FULL, .offset = MTDPART_OFS_APPEND, }, };
|
|
|
|
|
Feb 8 2015, 17:20
|

Универсальный солдатик
     
Группа: Модераторы
Сообщений: 8 634
Регистрация: 1-11-05
Из: Минск
Пользователь №: 10 362

|
Цитата(SM @ Feb 8 2015, 20:14)  Обычно, так по привычке выходит... Чтобы, если что, внутри структуры можно было написать нечто вроде struct abc_s *next_item; и никто это не обругал. Попробовал. Не получается. Но и имя структуры тоже не помогает. Нужно саму структуру определить. А, нет, получилось (в обоих вариантах). Когда struct перед типом добавил. Код typedef struct { __IO uint8_t A; __IO uint8_t B; uint16_t RES; // bool a; struct Dev_t *pDev; } Dev_t;
|
|
|
|
|
Feb 8 2015, 17:35
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(ViKo @ Feb 8 2015, 20:20)  Попробовал. Не получается. Все получается: Код typedef struct _abc_s { int a; int b; struct _abc_s *next; } ABC_S, *PABC_S; а вот запись struct ABC_S *next; (вместо struct _abc_s *next;) по логике не совсем корректна, так как ABC_S определен через typedef, а не через сам struct. По крайней мере, не красива, если даже и корректна по стандарту (я тут не уверен).
|
|
|
|
|
Feb 8 2015, 17:41
|
Гуру
     
Группа: Свой
Сообщений: 7 946
Регистрация: 25-02-05
Из: Moscow, Russia
Пользователь №: 2 881

|
Цитата(ViKo @ Feb 8 2015, 20:39)  И я не понимаю причин, почему бы оно не должно работать. Не может оно работать. ВНЕ ФУНКЦИЙ (где объявляют глобальные переменные) нельзя писать отдельное присваивание, как это пытался сделать ТС, а можно только инициализатор. А внутри функции и у автора темы все работает, о чем он и написал. то есть, подробно, на примере: Код typedef struct abc_s { int aa; int bb; } abc_t;
abc_t abc; abc.aa = 8; // это неправильно, это ошибка, описанная в первом сообщении.
abc_t abc1 = { .aa=8 }; // это правильно, это инициализатор.
void main(void) { abc.aa = 8; // и это правильно, так как в функции }
|
|
|
|
|
Apr 2 2015, 13:12
|

Частый гость
 
Группа: Участник
Сообщений: 116
Регистрация: 27-01-10
Из: СПб
Пользователь №: 55 094

|
Цитата(SM @ Feb 8 2015, 21:14)  Обычно, так по привычке выходит... Чтобы, если что, внутри структуры можно было написать нечто вроде struct abc_s *next_item; и никто это не обругал. Так а почему все-таки так нельзя делать? Если просто выполнить typedef так: Код typedef struct { int a; char b; } test_t; то все работает. Но мне для связного списка как раз нужно поле с указателем на следующий элемент: Код typedef struct { int a; char b; test_t *next; } test_t; вот так не работает, пиште "unknown type name". Но почему? Тип test_t ведь определен. Приходится делать так: Код typedef struct { int a; char b; struct test_t *next; } test_t; А чтобы потом в коде еще можно было сделать так: Код test_t *s_test; s_test = s_test->next; (ошибка "a value of type "test_t *" cannot be assigned to an entity of type "struct test_t *") приходится добавлять test_t между идентификатором struct и фигурными скобками: Код typedef struct test_t { int a; char b; struct test_t *next; } test_t;
Сообщение отредактировал ohmjke - Apr 2 2015, 13:20
|
|
|
|
|
Apr 2 2015, 13:40
|

Местный
  
Группа: Участник
Сообщений: 329
Регистрация: 23-04-14
Пользователь №: 81 502

|
Цитата(ohmjke @ Apr 2 2015, 14:12)  Так а почему все-таки так нельзя делать? Ответ на вопрос "почему" читать тут: http://stackoverflow.com/questions/252780/...t-so-often-in-cCODE typedef struct S_Tag { int a; int b;
struct S_Tag* pNext; } S ;
int _tmain(int argc, _TCHAR* argv[]) { S struct1; S struct2; struct2.pNext = &struct1;
return 0; }
|
|
|
|
|
Apr 2 2015, 15:56
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(ohmjke @ Apr 2 2015, 20:12)  Но мне для связного списка как раз нужно поле с указателем на следующий элемент: Проблема решается путём предварительного определения typedef, а потом самой структуры. Это работает потому что при обработке typedef нет неоходимости знать деталей устройства структуры. Код typedef struct test_t test_t; struct test_t { int a; char b; test_t *next; }; Кстати, обратите внимание на то, что имя test_t используется и для имени структуры и как имя нового типа, в С можно так делать (хотя и нежелательно - вводит в заблуждение) потому что эти имена не конфликтуют - они принадлежат разным пространствам имён, а компилятор по контексту определяет что имеется в виду. Но так дело обстоит в С, а в С++ всё сложнее и одновременно проще. В С++ структура это тоже класс, то есть struct s { ... эквивалентно class s { public: ... и поэтому в предыдущем примере нет необходимости объявлять typedef, имя структуры уже является именем нового типа. Но можно и оставить, тавтология с typedef допускается для совместимости с С.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|