Если вы хотите использовать структуру, вы должны определить ее где-нибудь. В противном случае компилятору не хватит информации для сборки программы (он даже не знает, сколько памяти требуется объекту Complex
). Он не может понять, как выглядит тип данных, просто используя структуру.
Однако, если вы знаете размер сооружения, вы все равно можете использовать его, хотя и в ограниченном и потенциально опасном виде. Например, вы можете включить следующее определение в ваш файл C:
typedef char[2*sizeof(float)] Complex;
Это позволит вам использовать тип данных Complex
основным способом (по сути, рассматривая его как кусок необработанных данных). Вы бы не могли бы нормально обращаться к членам структуры, но вы можете передавать Complex
объекты (или Complex*
указатели) между функциями, читать / записывать их в файл и сравнивать их друг с другом. , Если вы смелы, вы можете получить доступ к данным внутри структуры, используя указатели char
и ссылки на отдельные байты. Будьте осторожны, потому что это требует глубоких знаний о том, как ваш конкретный компилятор будет размещать структуру в памяти, включая любые байты выравнивания / заполнения. Вот пример доступа к внутренним элементам с помощью байтового смещения, при условии, что структура «упакована» (без заполнения):
typedef char[2*sizeof(float)] Complex;
Complex add(Complex a, Complex b) {
Complex res;
float real, imag;
real = ((float*)&a)[0] + ((float*)&b)[0];
imag = ((float*)&a)[1] + ((float*)&b)[1];
((float*)&res)[0] = real;
((float*)&res)[1] = imag;
return res;
}
Этот код должен давать вам тот же результат, что и код, который вы опубликовали, при условии, что определение Complex
не отличается от вашего примера кода. Это невероятно рискованно, и если вы решите это сделать, не называйте мое имя, пожалуйста.
Этот метод работает, только если вы знаете точный размер «реальной» Complex
структуры во время компиляции, и разрешает только грубый доступ к структуре. Любой код, который пытается использовать его с точечной нотацией (как в вашей функции в first.c), выдаст ошибку компилятора. Чтобы получить доступ к внутренним элементам структуры с помощью точечной нотации, вам необходимо полное определение структуры.
Если first.c будет скомпилирован в библиотеку, с которой будет ссылаться ваш код, то вы можете внести следующие изменения, чтобы позволить вам использовать функцию add
без использования first.h:
/* In start.c */
Complex add(Complex* a, Complex* b) {
Complex res;
res.real = a->real + b->real;
res.imag = a->imag + b->imag;
return res;
}
/* In your code */
typedef char[2*sizeof(float)] Complex;
Complex add(Complex* a, Complex* b);
Теперь вы должны иметь возможность создавать объекты типа Complex
и передавать их туда и обратно в функцию add
, не зная ничего о внутренних элементах структуры (кроме размера).