为什么在这个接口中使用`typedef void * COMPLEX`? [英] Why is `typedef void * COMPLEX` used in this interface?

查看:33
本文介绍了为什么在这个接口中使用`typedef void * COMPLEX`?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个程序,但我无法理解它是如何工作的.这是其中的一部分.我不明白行 typedef void *COMPLEX、命令 this 以及为什么使用 struct COMPLEX_IMPL.

I have a program and I can't understant how it works. Here is a part of it. I don't understand the line typedef void *COMPLEX, the command this and why the struct COMPLEX_IMPL is being used.

#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; 
}

推荐答案

typedef 定义类型的名称.所以

typedef defines a name for a type. So

typedef void *COMPLEX;
COMPLEX z;

相当于

void *z;

指针类型通常表示指针指向的数据类型.void * 是一个例外:它是一种拥有指针的方法,而无需说明它指向的值的类型.您可以自由地将任何类型的指针分配给 void * 指针并返回.

A pointer type normally indicates what kind of data the pointer points to. void * is an exception: it's a way to have a pointer without saying what the type of the value it points to is. You can freely assign any kind of pointer to a void * pointer and back.

void * 指针通常用于必须处理任何类型数据的通用库函数中.例如,考虑标准库函数memcpy:

void * pointers are normally used in generic library functions that must work with data of any type. For example, consider the standard library function memcpy:

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

您向该函数传递一个指向任何类型对象的指针src,一个指向另一个对象(通常但不总是相同类型)的指针dest,以及要复制的字节数.该函数复制字节,它不关心字节的含义,因此传递两个指向未指定类型的指针就足够了.

You pass that function a pointer to an object of any type src, a pointer to another object (which is usually, but not always, of the same type) dest, and a number of bytes to copy. The function copies the bytes, it doesn't care what the bytes mean, so it's enough to pass two pointers-to-an-unspecified-type.

此处使用 void * 不是好的或常见的编程习惯.一个复数表示为它的实部和虚部:

The use of void * here is not good or common programming practice. A complex number is represented as its real part and its imaginary part:

struct COMPLEX_IMPL { double a; double b; };

典型的复数库会将其设为 COMPLEX 类型.

A typical complex number library would make this the COMPLEX type.

您发布的代码隐藏了 COMPLEX 类型的实现.复数被实现为包含两个 double 成员的结构这一事实仅在 complex.c 中显而易见.该库的用户只能看到 COMPLEX 是指向某物的指针.这是数据抽象的一种形式:隐藏数据的表示细节类型.但它做得不好:根据这个定义,任何指向任何东西的指针都可以分配给COMPLEX.通常的方法是使用一个不完整结构,它被声明并且明显是一个结构,但它的未指定成员.在 complex.h 中,你会写:

The code you posted hides the implementation of the COMPLEX type. The fact that complex numbers are implemented as a structure containing two double members is only apparent in complex.c. Users of the library only see that a COMPLEX is a pointer to something. This is a form of data abstraction: hiding the representation details of a data type. But it's poorly done: with this definition, any pointer to anything can be assigned to a COMPLEX. The normal way is to use an incomplete structure, which is declared and visibly a structure but whose members are not specified. In complex.h, you would write:

struct COMPLEX_IMPL;
typedef struct COMPLEX_IMPL *COMPLEX;

那样,合法创建COMPLEX_IMPL的唯一方法是通过complex.h提供的函数,但是COMPLEX类型的变量> 显然是一个指向 complex.c 中定义的复数表示的指针.

That way, the only way to legally create a COMPLEX_IMPL is through the functions provided by complex.h, but a variable of type COMPLEX is visibly a pointer to a representation of a complexe number as defined in complex.c.

哦,还有 this 是一个普通的变量名.

Oh, and this is an ordinary variable name.

这篇关于为什么在这个接口中使用`typedef void * COMPLEX`?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆