为什么在这个接口中使用`typedef void * COMPLEX`?

时间:2012-02-23 11:36:32

标签: c struct typedef void-pointers

我有一个程序,我无法理解它是如何工作的。这是它的一部分。 我不理解行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 个答案:

答案 0 :(得分:8)

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是指向某事物的指针。这是data abstraction的一种形式:隐藏数据类型的表示细节。但是做得不好:有了这个定义,任何指向任何东西的指针都可以分配给COMPLEX。通常的方法是使用incomplete structure,它被声明并且可见一个结构,但其成员未指定。在complex.h中,您会写:

struct COMPLEX_IMPL;
typedef struct COMPLEX_IMPL *COMPLEX;

这样,合法创建COMPLEX_IMPL的唯一方法是通过complex.h提供的函数,但COMPLEX类型的变量明显是指向complexe表示的指针complex.c中定义的数字。

哦,this是一个普通的变量名。

答案 1 :(得分:2)

typedef void *COMPLEX;

使COMPLEX成为void *类型的别名。 (这很邪恶,顺便说一句,因为你不应该使用指针typedef而void有效地关闭类型检查。)

没有“命令”this,这只是一个参数的名称。

struct用于将ab成员保持在一起。这就是结构的用途。

答案 2 :(得分:0)

  • typedef void* COMPLEX使'COMPLEX'成为void指针类型'void *'
  • 的别名
  • 使用COMPLEX_IMPL是因为复数有两个部分,因此将它们组合在一起
  • 'this'是变量

我认为C中的教程会让你受益匪浅。

答案 3 :(得分:0)

typedef void *

用于定义项目使用的dll中的函数