问题
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;
}
回答1:
typedef
defines a name for a type. So
typedef void *COMPLEX;
COMPLEX z;
is equivalent to
void *z;
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 *
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);
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.
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; };
A typical complex number library would make this the COMPLEX
type.
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;
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
.
Oh, and this
is an ordinary variable name.
回答2:
typedef void *COMPLEX;
makes COMPLEX
an alias for the type void *
. (This is evil, btw., since you shouldn't use a pointer typedef and a void
one effectively turns off type checking.)
There is no "command" this
, that's just the name of an argument.
The struct
is used to keep the a
and b
members together. That's what structs are for.
回答3:
typedef void* COMPLEX
makes 'COMPLEX' an alias for the void pointer type 'void*'- COMPLEX_IMPL is use because a complex number has two parts, so this groups them together
- 'this' is a variable
I think a tutorial in C would benefit you greatly here.
回答4:
typedef void*
use to define function in dll which used by your project
来源:https://stackoverflow.com/questions/9412262/why-is-typedef-void-complex-used-in-this-interface