Присвоение массива структур структуре typedef

#c

#c

Вопрос:

Как мне присвоить typedef struct массиву другого struct с аналогичной структурой.

 #include <stdio.h>
#include <stdlib.h>

typedef struct {
    int age;
    int height;
} Person[3];

struct internalStruct {
    int age;
    int height;
};

int main(void) {

    //Possible
    Person bob = {{7,5},{4,2},{4,3}};

    //Is it possible to assign array to struct?
    struct internalStruct intr[3] = {{4,32},{2,4},{2,4}};
    Person job = intr; // Does not work :(. 
    printf("%d", jon[0].height);
    return 0;
}
  

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

1. Есть ли какая-либо причина не делать struct internalStruct { int age; int height; }; typedef struct internalStruct Person[3]; ?

2. Я просто пытаюсь понять, одинаковы ли структуры памяти (typedef массива из 3 — это та же структура памяти, что и обычный массив из 3 структур. На самом деле я не кодирую на C.

Ответ №1:

Вы не можете присвоить массив в C. Вы можете инициализировать массив при его объявлении, но выражение массива не может отображаться в левой части оператора присваивания.

Если вы хотите скопировать значение объекта array в другой объект array, вы можете использовать явный цикл для присвоения каждого элемента (предполагая, что тип элемента можно назначить), или вы можете использовать memcpy() . (Обратите внимание, что при вызове memcpy() необходимо указать количество байтов для копирования; используйте sizeof для этого.)

И ваш typedef Person :

 typedef struct {
    int age;
    int height;
} Person[3];
  

опрометчиво. Person Объект (переменная) — это не person; это массив из 3 человек (people?).

Мой совет: отбросьте typedef и просто используйте тег struct (как вы уже делаете для struct internalStruct ) и не пытайтесь создать специальное имя для типа массива:

 struct Person {
    int age;
    int height;
};
  

 struct Person bob[] = {{7,5},{4,2},{4,3}};
  

(Это все еще сбивает с толку, поскольку bob это три человека.)

И struct Person (как я определил это здесь) и struct internalStruct — это два разных типа. Если вы пытаетесь назначить между этими двумя типами, это, вероятно, указывает на недостаток дизайна в вашем коде; объекты, которые вы назначаете друг другу, должны быть одного типа.

Рекомендуется прочитать: часто задаваемые вопросы по comp.lang.c, особенно раздел 6 (массивы и указатели).

Ответ №2:

Я бы не стал предлагать это сложно, поскольку вы можете столкнуться с утечками памяти, когда две структуры отличаются:

 #include <stdio.h>
#include <stdlib.h>

typedef struct {
    int age;
    int height;
} Person[3];

struct internalStruct {
    int age;
    int height;
};

int main(void) {

    //Possible
    Person bob = {{7,5},{4,2},{4,3}};

    //Is it possible to assign array to struct?
    struct internalStruct intr[3] = {{4,32},{2,4},{2,4}};
    Person* jon= (Person *)intr; // Does not work :(.
    printf("%d", jon[0]->height);
    return 0;
}
  

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

1. Это не работает. Мне нужно иметь возможность присваивать intr заданию

2. ах, это ваша проблема, ну, вероятно, не очень хорошая идея переключать типы структур, но вы могли бы сделать это с помощью указателей, я отредактировал свой первый ответ. обратите внимание на тип: job!= jon

Ответ №3:

Ваш Person тип представляет собой массив из трех структур, каждая из которых похожа на вашу struct internalStruct . Итак, вы не можете просто присвоить a struct internalStruct a Person , хотя вы можете (с некоторой помощью) присвоить его одному из элементов a Person .

Кроме того, копирование массивов в C требует копирования поэлементно или копирования блока памяти с помощью функции типа memcpy() .

Таким образом, самым простым способом сделать это было бы определить struct internalStruct перед Person и определить Person в терминах struct internalStruct :

 struct internalStruct {
  int age;
  int height;
};

typedef struct internalStruct Person[3];
  

Выполнение этого таким образом позволяет присваивать struct internalStruct элементу Person без несоответствий типов. Например:

 struct internalStruct s1 = {4,32},
                      s2 = {2,4},
                      s3 = {2,4};
Person jon;
jon[0] = s1;
jon[1] = s2;
jon[2] = s3;
  

Если у вас есть массив из трех struct internalStruct элементов, вы могли бы скопировать его с помощью цикла:

 struct internalStruct st[3] = { {4,32}, {2,4}, {2,4} };
Person jon;
for (int i = 0; i < 3; i  )
  jon[i] = st[i];
  

Если вы не хотите определять Person в терминах struct internalStruct , то вам придется сделать некоторые предположения, например, что расположение двух структур будет идентичным. Если это так, вы могли бы скопировать с помощью memcpy() :

 struct internalStruct intr[3] = { {4,32}, {2,4}, {2,4} };
Person jon;
memcpy(jon, intr, sizeof(Person));
  

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

1. Есть ли способ получить карту памяти различных структур (unions / enum / typedef) для конкретного компилятора.

2. @Anonymous Тщательно просмотрели документацию для компилятора? В противном случае, в коде вы можете проверить, что sizeof дает одинаковый размер для обеих структур, и что offsetof дает одинаковые значения для соответствующих элементов в каждой структуре. Обычно, если они определены одинаковым образом и с одинаковыми атрибутами, они будут совпадать — но лучше не зависеть от этого и просто использовать один и тот же тип вместо двух типов, которые вероятно идентичны.