#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
дает одинаковые значения для соответствующих элементов в каждой структуре. Обычно, если они определены одинаковым образом и с одинаковыми атрибутами, они будут совпадать — но лучше не зависеть от этого и просто использовать один и тот же тип вместо двух типов, которые вероятно идентичны.