LinuxForum.Fans
Тема

Варианты присвоения значений структуре (не программист).

Автор: smaharbA 12 сообщений 2651 просмотров
#362410

Имеем

text
void
func (struct x *y)
{
    struct a b = { .a = y, .b = y->x, .c = 0 };
   ...
}

Привидите кому не в лом аналоги записи.

#362424

Если a - это x, то просто b=*y, если нет и у b и x есть одинаковые члены,
то, в предположении, что они называются одинаков,
то только поэлементно: b.el1=y->el1.

Пётр.

#362428
Peter написал:
Если a - это x, то просто b=*y, если нет и у b и x есть одинаковые члены,
то, в предположении, что они называются одинаков,
то только поэлементно: b.el1=y->el1.

Пётр.

Еще вариант. Если структуры одинаковы, то можно и так:

text
memcpy((void *)&a,(void *)&b,sizeof(a)); 
#362471

чет вы мудрите
так, это аналог или нет ?

text
struct a *b;
b->a = &y;
b->b = y->x;
b->c = 0;

Да, эдемент "x" у структуры "y" - целое.

#362478

С копирование так будет выглядеть ?

text

struct a b;
memcpy(&b->a,&y,sizeof(b->a));
b.bi = y->x;
b.c = 0;
#362481

Так понимаю, что если вложенная структура такая же, что и переденная, то можно тупо так (компилятор сам разберется) ?

text
struct a b;
b.a = y;
b.bi = y->x;
b.c = 0;
#362489
smaharbA написал:
чет вы мудрите
так, это аналог или нет ?
text
struct a *b;
b->a = &y;
b->b = y->x;
b->c = 0;

Да, эдемент "x" у структуры "y" - целое.

Нет, данная запись ошибочна. А именно - Вы не отвели память под объект структуры b, только объявили указатель на неё и не более. Указатель в таком случае может указывать вообще в любое место памяти, или в NULL. Если нужен именно указатель на b, то писать надо так:

text
struct a *b=new a;

А далее - каку Вас. И не забыть по окончании манипуляций с b написать

text
delete b;
#362491

Откудова в си new ?

тогда уж malloc ?

По вопросу нужны примеры записи

text
struct a b = { .a = y, .b = y->x, .c = 0 };

В "развернутом" виде.

При том, что элемент "b.a" та же структура, что и "y", а "b.b", "y->b" и "b.c" - целочисленные.

#362501
smaharbA написал:
Откудова в си new ?

тогда уж malloc ?

А телепаты местные в отпуске. Догадаться, что надо использовать чистый С как?
А хорошим тоном в программировании будет использование typedef. То есть - правильно писать так:

typedef stuct a{
/* здесть все определения, что входит в структуру */
} A;

func ( A *a ){
A *b=(A *)calloc(sizeof(A)); /* Или A b; */
b->el1=a->el1; /* Или b.el1 = a.el1; */
/* ...
и так далее
*/
free(b); /* если отводили как указатель */
}

#362505

typedef не используется
т.е всеж таки нужно отводить память или достаточно простого присвоения ?

конструкция

text
struct a b = { .a = y, .b = y->x, .c = 0 };

является правильной записью или нет (при том, что "y" - это структура) ?

и если не затруднит, напишите пример именно для таких имен переменных.

#362617
smaharbA написал:
typedef не используется
т.е всеж таки нужно отводить память или достаточно простого присвоения ?

конструкция
text
struct a b = { .a = y, .b = y->x, .c = 0 };

является правильной записью или нет (при том, что "y" - это структура) ?

и если не затруднит, напишите пример именно для таких имен переменных.

1. Typedef следует использовать по целому ряду причин. Например, его применение резко снижает риск неправильной работы с данными структуры. А именно, пусть мы определим структуру

text
struct a {
      int el1;
      int el2;
      int el3;
      };

Далее, по какой-то надобности нам потребуется расширить перечень этих элементов (а программа уже содержит сотню файлов и неисчислимые тыщи строк кода. И в одном месте мы модифицируем структуру так:

text
struct a {
      int new_elem;
      int el1;
      int el2;
      int el3;
      };

А в другом - этак (особенно это возможно, если проект ведут несколько программистов:

text
struct a {
      int el1;
      int el2;
      int el3;
      int new_elem;
      };

Вы полагаете, что это одинаковые структуры? Отнюдь. А вот поиск ошибок, возникших внезапно на пустом месте съест очень много рабочего времени.
Использование конструкции typedef жестко типизирует Ваши структуры и подобную ситуацию исключает. Ну и делает программу на порядок читабельнее. Это первое.
Второе - похоже Вы плохо различаете указатели на структуры с самими этими объектами. Если Вы объявляете указатель, то в нём нет ничего, он просто указывает на некий адрес в памяти и говорит компилятору, как надо оперировать с частью памяти, начинающимся с данного адреса. Вполне возможно, не знаю, Вам надо присвоить локальный указатель на некую структуру, созданную где-то ранее и поманипулировать её содержимым. Тогда зачем отводить память? А если Вы создаете свой экземпляр структуры - здесь отведение памяти под неё необходимо.
Далее, я никогда не занимался подобной инициализацией элементов структуры. Мне это было неактуально, а справочники говорят, что структуры можно инициализировать точно так же, как массивы. То есть так:

text
struct a b = {"Sergey", 'B', 4.5 };

То есть - никаких имен элементов структуры для её тотальной инициализации не требуется.
Для выборочной инициализации нужно указывать имена элементов структуры, которые инициализируются (так как Вы написали). Но _инициализация_ элементов структуры производится на _этапе_компиляции_ и инициализируется она _константами_ (заранее заданными). А не переменными, которые возникают в ходе выполнения программы. В своем примере Вы, скорее всего, получите ошибки на этапе компиляции, так как компилятор совершенно не знает нужных Вам адресов.
В Вашем же случае надо не инициализировать элементы структуры, а присваивать им нужные значения "руками":

text
void func (struct x *y)
{
    struct {
      struct x *a;
      не знаю что (по типу элемента x.x) b;
      int c; 
    } b { .c=0 };
    b.a = y, b.b = y->x;
   ...
}

y и y->x есть переменные и ими не инициализируются.

#362629

Имена требуются, структура гораздо больше 3 элементов.
typedef - не имею морального права использовать, код из модуля ядра, лопатить все связи муторно.

Исходный код инициализации именно такой

text
struct a b = { .a = y, .b = y->x, .c = 0 };

Но на старом компиляторе вываливается при компиляции в segfault, если код меняю на следующий

text
struct a b;
b.a = y;
b.b = y->x;
b.c = 0;

как и в случае с malloc и далее копированием memcpy(&b->a,&y,sizeof(b->a)) все собирается и модуль вроде как работает, вот и сабж с просьбой привести аналоги записи, может какие камни есть под водой.

Войдите или зарегистрируйтесь, чтобы ответить.