#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. Хорошо, большое спасибо. Копирование в моем случае нормально, я просто подумал, могу ли я этого избежать.