Почему в этом интерфейсе используется `typedef void * COMPLEX`? - PullRequest
0 голосов
/ 23 февраля 2012

У меня есть программа, и я не могу понять, как она работает.Вот часть этого.Я не понимаю строку typedef void *COMPLEX, команду this и почему используется struct COMPLEX_IMPL.

#ifndef _COMPLEX_H 
#define _COMPLEX_H 

typedef void *COMPLEX; 

COMPLEX NewCOMPLEX (double a, double b ); 

void DeleteCOMPLEX(COMPLEX this ); 

double GetA (COMPLEX this ); 

double GetB (COMPLEX this ); 

COMPLEX AddComplex (COMPLEX c1, COMPLEX c2, COMPLEX res); 
COMPLEX MultComplex (COMPLEX c1, COMPLEX c2, COMPLEX res); 

#endif /* _COMPLEX_H */

#ifndef _COMPLEX_H 
#define _COMPLEX_H 

typedef void *COMPLEX; 

COMPLEX NewCOMPLEX (double a, double b ); 

void DeleteCOMPLEX(COMPLEX this ); 

double GetA (COMPLEX this ); 

double GetB (COMPLEX this ); 

COMPLEX AddComplex (COMPLEX c1, COMPLEX c2, COMPLEX res); 
COMPLEX MultComplex (COMPLEX c1, COMPLEX c2, COMPLEX res); 

#endif /* _COMPLEX_H */

#include <stdio.h> 
#include "complex.h" 

struct COMPLEX_IMPL { double a; double b; }; 

double GetA(COMPLEX this) { 
    struct COMPLEX_IMPL *this_impl = (struct COMPLEX_IMPL*)this; 
    return this_impl->a; 
}

Ответы [ 4 ]

8 голосов
/ 24 февраля 2012

typedef определяет имя для типа. Так

typedef void *COMPLEX;
COMPLEX z;

эквивалентно

void *z;

Тип указателя обычно указывает, на какие данные указывает указатель. void * является исключением: это способ иметь указатель без указания типа значения, на которое он указывает. Вы можете свободно назначать любой тип указателя на void * указатель и обратно.

void * указатели обычно используются в общих библиотечных функциях, которые должны работать с данными любого типа. Например, рассмотрим стандартную библиотечную функцию memcpy:

void *memcpy(void *dest, const void *src, size_t n);

Вы передаете этой функции указатель на объект любого типа src, указатель на другой объект (который обычно, но не всегда, того же типа) dest и количество байтов для копирования. Функция копирует байты, ей все равно, что означают байты, поэтому достаточно передать два указателя на неопределенный тип.

Использование void * здесь не является хорошей или обычной практикой программирования. Комплексное число представляется как его действительная часть и ее мнимая часть:

struct COMPLEX_IMPL { double a; double b; };

Типичная библиотека комплексных чисел сделала бы это типом COMPLEX.

Код, который вы опубликовали, скрывает реализацию типа COMPLEX. Тот факт, что комплексные числа реализованы в виде структуры, содержащей два элемента double, очевиден только в complex.c. Пользователи библиотеки видят только, что COMPLEX является указателем на что-то. Это форма абстракции данных : скрытие подробностей представления типа данных. Но это плохо сделано: с этим определением любой указатель на что-либо может быть назначен на COMPLEX. Обычным способом является использование неполной структуры , которая объявлена ​​и явно является структурой, но члены которой не указаны. В complex.h вы бы написали:

struct COMPLEX_IMPL;
typedef struct COMPLEX_IMPL *COMPLEX;

Таким образом, единственный способ юридически создать COMPLEX_IMPL - через функции, предоставляемые complex.h, но переменная типа COMPLEX явно указывает на представление комплексного числа, определенного в complex.c.

О, а this - обычное имя переменной.

2 голосов
/ 23 февраля 2012
typedef void *COMPLEX;

делает COMPLEX псевдонимом для типа void *.(Это зло, кстати, так как вы не должны использовать указатель typedef, а void эффективно отключает проверку типов.)

Нет "команды" this, это просто имяаргумента.

struct используется для хранения вместе элементов a и b.Вот для чего нужны структуры.

0 голосов
/ 02 августа 2016

typedef void *

используется для определения функции в dll, используемой вашим проектом

0 голосов
/ 23 февраля 2012
  • typedef void* COMPLEX делает 'COMPLEX' псевдонимом для типа указателя void 'void *'
  • COMPLEX_IMPL используется, потому что комплексное число состоит из двух частей, поэтому оно группирует их вместе
  • 'this' является переменной

Я думаю, что учебник по Си принесет вам большую пользу.

...