Избегайте разыменования при работе с одним и тем же набором данных с разными структурами

#c #pointers #struct #dereference

#c #указатели #структура #разыменование

Вопрос:

с тех пор я уже давно читаю Stackoverflow и многому научился.

Но теперь у меня есть проблема, которую я не смог найти в Stackoverflow, даже это должен быть своего рода «стандартный» вопрос. Поэтому, пожалуйста, простите меня, если на эту тему уже был дан ответ.

Проблема:

Я пишу модуль с определенными интерфейсами для структур ввода и вывода. Это должен быть своего рода «мультиплексор» , возможно, с тремя входами и одним выходом. Модуль должен переключать один из входов на выход (в зависимости от некоторой логики).

Рабочий пример показан здесь:

 #include lt;stdio.hgt;  typedef struct{  short myVariable1;  short myVariable2; } myType;  struct input_type{  myType Inp1;  myType Inp2;  myType Inp3; };  struct output_type{  myType Out1; };  struct input_type input; struct output_type output;  void main(){    for (int i=0; ilt;10; i  ){ // this for loop simulates a cyclic call of a function where all the inputs are written  input.Inp1.myVariable1 = i;  input.Inp2.myVariable1 = i*2;  input.Inp3.myVariable1 = i*3;  printf("Inp1: %d | Inp2: %d | Inp3: %d n",input.Inp1.myVariable1,input.Inp2.myVariable1,input.Inp3.myVariable1);  output.Out1 = input.Inp2; // Actual routing is done here, but i want to avoid this copy by working on the same dataset (e.g. input.InpX)  printf("Out: %dn",output.Out1.myVariable1);  } }   

В этом разрезе структуры просто копируются каждый цикл. Чтобы избежать этого шага, я мог бы сделать следующее:

 #include lt;stdio.hgt;  typedef struct{  short myVariable1;  short myVariable2; } myType;  struct input_type{  myType Inp1;  myType Inp2;  myType Inp3; };  struct output_type{  myType * Out1; };  struct input_type input; struct output_type output;  void main(){    output.Out1 = amp;input.Inp2; // Actual routing is done here; But in this case, the output structure includes a pointer, therefore all other modules need to dereference Out1 with "-gt;" or "*"    for (int i=0; ilt;10; i  ){ // this for loop simulates a cyclic call of a function where all the inputs are written  input.Inp1.myVariable1 = i;  input.Inp2.myVariable1 = i*2;  input.Inp3.myVariable1 = i*3;  printf("Inp1: %d | Inp2: %d | Inp3: %d n",input.Inp1.myVariable1,input.Inp2.myVariable1,input.Inp3.myVariable1);    printf("Out: %dn",output.Out1-gt;myVariable1);  } }  

Но в этом случае структура вывода больше не совместима с существующим интерфейсом. Доступ к Out1 потребует разыменования.

Можно ли избежать копирования структур из одной в другую без изменения моего интерфейса?

Заранее спасибо за ваши ответы! Рис.

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

1. Я думаю, что смешивать указатели и необработанные переменные-плохая идея. Вы могли бы использовать ссылки, если бы ваш код был написан на c , но в C. такого механизма нет, поэтому, если вы хотите избежать копирования, вам придется использовать указатели. На самом деле, в данном примере нет необходимости в указателях, потому что копирование структуры из двух shorts является относительно быстрой операцией по сравнению с другими операциями ввода-вывода. Однако, если есть возможность, чтобы myType структура стала достаточно большой (чтобы копирование стало неэффективным), указатели являются единственным способом обеспечить хорошую работу этого кода.

2. Спасибо за ваш ответ, я ожидаю ~5 переменных в MyType и ~20 экземпляров. Копирование в порядке вещей, даже во встроенной системе. Я просто ищу лучший способ…

Ответ №1:

Можно ли избежать копирования структур из одной в другую без изменения моего интерфейса?

Под «существующим интерфейсом» я понимаю, что вы подразумеваете, что у вас есть код, который использует объекты этого типа …

 struct output_type{  myType Out1; };  

… и вы хотели бы избежать изменения этого кода.

В таком случае, нет, вы не можете заменить

 struct output_type{  myType * Out1; };  

. Более того, в дизайне предыдущей структуры заложено, что заполнение myType , которое является прямым участником, включает копирование всех данных, которые вас интересуют, будь то на основе каждого участника или на основе всей структуры.

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

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

1. Хорошо, большое спасибо. Копирование в моем случае нормально, я просто подумал, могу ли я этого избежать.