Присвоить структуру A B, где элементы A являются подмножеством B

#c #struct

#c #структура

Вопрос:

Насколько я понимаю, назначение массивов — это операция копирования в память, сработает ли это?

 struct x{
    int i;
    int j;
} A[5];

struct y{
    int i;
    int j;
    struct y * next;
} B[5];
  

Тогда могу ли я сделать:

 B[0] = A[0];
  

и ожидать, что i и j скопированы для индекса [0]?

РЕДАКТИРОВАТЬ: Что я действительно хочу знать, так это как заставить это работать на C.

Комментарии:

1. Что произошло, когда вы попробовали это? Или вы спрашиваете, знаем ли мы другой способ заставить это работать?

2. Да, это более подходящий вопрос. Как заставить это работать. Я отредактирую исходный вопрос с тем, что я делаю

3. Понял. memcpy сделает это за вас. Вот ссылка на memcpy .

Ответ №1:

Мое предложение состоит в том, чтобы внедрить struct x в struct y , вот так:

 struct x{
    int i;
    int j;
} A[5];

struct y{
    struct x x;
    struct y * next;
} B[5];
  

Таким образом, это легко назначить, и расположение первых sizeof(struct x) байтов в памяти обеих структур гарантированно будет одинаковым, даже в C89.

Теперь вы можете сделать

 B[0].x = A[0];
  

Поскольку struct x гарантированно отображается в первом байте struct y в памяти, вы все равно можете сделать

 memcpy(amp;B[0], amp;A[0], sizeof A[0]);
  

Вы можете поиграть с этим макетом в http://codepad.org/2rCJA0cx

Комментарии:

1. 1: Не говоря уже о том, что если вы измените структуру x позже, вы будете уверены, что ничего не нарушите.

Ответ №2:

Нет, эта строка кода не будет компилироваться.

Смотрите http://codepad.org/6g3c9Ctz

Вы можете использовать memcpy , чтобы заставить это работать. Смотрите http://codepad.org/1I9Z3npC

 #include <string.h>
#include <stdio.h>

struct x{
    int i;
    int j;
} A[5];

struct y{
    int i;
    int j;
    struct y * next;
} B[5];

int main() {
    A[0].i = 5;
    A[0].j = 7;
    memcpy(amp;B[0], amp;A[0], sizeof A[0]);
    printf("%d %dn", B[0].i, B[0].j);
    return 0;
}
  

Комментарии:

1. Обязательно ли выравнивание памяти для x.j и y.j ? Я знаю, что это, вероятно, будет на практике, но я думаю, что это гарантировано только для i . Более простым решением является внедрение struct x в struct y .

2. Добавление: Тот факт, что это работает, был формализован в C99. До C99 не было никаких гарантий, но это все равно работало во всех реализациях.

3. @gnud: Начиная с C99, явно гарантируется, что он будет работать даже без встраивания struct x в struct y . Как отметил комитет по стандартам, это всегда работало в любом случае , и они просто хотели кодифицировать существующие практики.

4. Здесь используется стандарт C99. Подробности о том, почему memcpy работает здесь, приведены в 6.7.2.1. В основном там говорится, что поля расположены в объявленном порядке, и что заполнение (я думаю), если оно существует, должно применяться последовательно.

Ответ №3:

Нет, вы не можете, потому что struct x и struct y не являются совместимыми типами.

Ответ №4:

Вы можете использовать приведение:

 (struct x)(B[0]) = A[0];