#c #объединение #сетевое_программирование
Я, видимо, не совсем понимаю, как работают union в Си, поэтому просьба прокомментировать мои вопросы по следующему небольшому коду. (Чтобы сократить код, приведу только функцию main()) int main(void) { int sockfd; socklen_t size = 2000; union { struct sockaddr sa; char mas[2000]; }un; sockfd = socket(AF_INET, SOCK_STREAM, 0); getsockname(sockfd, (struct sockaddr*)un.mas,&size); printf("%d\n\n", un.sa.sa_family); return 0; } 1) Я ведь даже не заполняю структуру struct sockaddr sa, почему printf() печатает правильный ответ? 2) Если я вместо union напишу struct, то ответ будет неправильный. 3) Если переменные не будут находиться в union или struct, то вылезает предупреждение sa.sa_family’ is used uninitialized in this function. Помогите, пожалуйста, разобраться
Ответы
Ответ 1
Неудобный пример. Представьте что у вас есть юнион: typedef union { struct { int value; // 4 байта }; struct { char a; // 1 байт char b; // 1 байт char c; // 1 байт char d; // 1 байт }; } Test; Первое поле - int - объединяет в себе последующие char поля. В этом концепция union-ов. Вот трейс: Test test; test.value = 0; // value = { 00000000 00000000 00000000 00000000 } test.a = 1; // value = { 00000000 00000000 00000000 00000001 } test.b = 2; // value = { 00000000 00000000 00000010 00000001 } test.c = 3; // value = { 00000000 00000011 00000010 00000001 } test.d = 4; // value = { 00000100 00000011 00000010 00000001 } Видно, что меняя одно из мелких char полей меняется и большое int поле с именем value. По сути, наш union - это int число, но, для удобства, мы разделили это число на 4 байта a,b,c,d. Можем работать как со всеми 4 байтами сразу - value, так и с каждым отдельным байтом - a,b,c,d. В вашем случае всё аналогично. Есть struct sockaddr sa, далее, его представляют как массив из char длинной в 2000 байт. 1.) Заполняете. getsockname(sockfd, (struct sockaddr*)un.mas,&size); // передаёте указатель на начало массива char.Данные пишутся туда, как видно из моего примера с int числом, заполняя a,b,c,d мы меняем value. Здесь так же. Заполняя массив, мы меняем sa. 2.) И это логично, структура - это структура, юнион - это юнион. Не путайте их. 3.) Неужели даже так не получается? struct sockaddr sa; sockfd = socket(AF_INET, SOCK_STREAM, 0); getsockname(sockfd, (struct sockaddr*)&sa,&size); printf("%d\n\n", sa.sa_family);
Комментариев нет:
Отправить комментарий