Поведение поля типа данных объединения - PullRequest
0 голосов
/ 11 июня 2019

Мне трудно понять, как работает этот фрагмент кода. В основном меня смущает то, как x.br получает значение 516 после того, как x.str.a и x.str.b получают их значения 4 и 2 соответственно. Я новичок в профсоюзах, так что, может быть, что-то мне не хватает, но разве в одно время не должно быть только 1 активного поля в профсоюзе?

#include <stdio.h>
void f(short num, short* res) {
    if (num) {
        *res = *res * 10 + num % 10;
        f(num / 10, res);
    }
}
typedef union {
    short br;
    struct {
        char a, b;
    } str;
} un;
void main() {
    short res = 0; un x;
    x.str.a = 4;
    x.str.b = 2;
    f(x.br, &res);
    x.br = res;
    printf("%d %d %d\n", x.br, x.str.a, x.str.b);
}

Я был бы очень благодарен, если бы кто-нибудь прояснил это для меня, спасибо!

Ответы [ 3 ]

3 голосов
/ 11 июня 2019

Чтобы добавить к ответу @Deepstop и исправить важный момент о вашем понимании -

не должно ли быть только 1 активное поле в объединении в любой момент времени?

В союзах нет такого понятия, как активное поле .Все разные поля относятся к одному и тому же точному фрагменту памяти (кроме выровненных данных.

Вы можете рассматривать разные поля как разные способы интерпретации одних и тех же данных, т.е. вы можете считать свой союз как дваполя или 8 бит или одно поле из 16 бит. Но оба всегда будут «работать» одновременно.

1 голос
/ 11 июня 2019

как x.br получает значение 516 после того, как x.str.a и x.str.b получают их значения 4 и 2

Ваше определение объединения

typedef union {
    short br;
    struct {
        char a, b;
    } str;
} un;

Указывает, что un.br использует тот же адрес памяти, что и un.str.В этом весь смысл союза.Это означает, что когда вы изменяете значение un.br, вы также изменяете значения для un.str.a и un.str.b.

Я новичок в профсоюзах, так что, возможно, есть что-то, что яотсутствует, но не должно ли быть только 1 активное поле в объединении в любой момент времени?

Не уверен, что вы подразумеваете под "быть только 1 активным полем", но члены объединениявсе они сопоставлены с одним и тем же адресом памяти, поэтому каждый раз, когда вы записываете значение в член объединения, оно записывает это значение в тот же адрес памяти, что и другие члены.Если вы хотите, чтобы элементы отображались на разные адреса памяти, чтобы при записи значения элемента изменялось только значение этого конкретного элемента, вам следует использовать struct, а не union.

1 голос
/ 11 июня 2019

OK short - это 16-разрядное целое число. Char a, b - каждый 8-битный символ.

Итак, вы используете одну и ту же 16-битную ячейку памяти для обоих.

0000 0010 0000 0100 is the 16 bit representation of 516
0000 0010           is the 8 bit representation of 2
          0000 0100 is the 8 bit representation of 4

Процессор, на котором вы работаете, имеет «младший порядок», поэтому младший байт 16-разрядного целого числа идет первым, то есть 2, а старший байт 4 - вторым.

Итак, записав 2, а затем 4 в последовательные байты и считав их обратно как 16-битное целое число, вы получите 516, то есть 2 * 256 + 4. Если вы написали 3, то 5, вы получите 3 * 256 + 5, что составляет 783.

Дело в том, что объединение помещает две структуры данных в одно и то же место памяти.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...