我正在尝试通过重新设计我从DB类中完成的项目(创建自己的数据库系统(来理解C和C 之间的区别C语言。现在,我正在尝试重新设计项目的API,该项目也可以在用C 语言编写的应用程序中使用。
我与typedef struct
,enum
,float
等混淆了
标题文件中的C中的代码看起来像:
typedef enum { FALSE = 0, TRUE } bool_t;
typedef float real;
...
typedef struct _hf_record_identification {
int pagenum;
int recnum;
} RECID;
我得出了结论,在阅读了一些有关它的参考后,可以在C 中表示:
enum bool_t {FALSE = 0, TRUE };
float real;
...
struct _hf_record_identification RECID {
int pagenum;
int recnum;
} ;
我的问题是:C和typedef
中的typedef
之间的主要区别是什么C ?在我的C 中使用typedef
并不是不便。我把它与C混淆了。我是否对typedef float real
案件正确完成了?
此行:
typedef float real;
实际上只是typedef
,它将real
定义为float
类型的别名。因此,如果您写
float real;
它是不是 在c 中既不相同。这只是使用类型float
的变量real
的声明。
struct
和enum
变得更加复杂,因为它们具有所谓的 tags 来识别它们:
struct foo
{
int x;
};
这里:foo
是结构的标签。在C 中,您可以通过仅编写标签(只要标签名称是明确的(来参考结构,而C要求您始终包含struct
关键字:
struct foo a; // legal in both C and C++
foo b; // legal only in C++
当然,您还可以使用typedef
创建一个别名类型,以上述示例:
typedef struct foo foo;
现在,第二个声明也是有效的c,因为 foo
是类型名称。
相同的规则以相同的方式适用于enum
s。
请注意,C 确实不是" 自动typedef " a struct
或 enum
。它仅允许单独使用标签名称参考这些类型。因此,额外的typedef
绝对有效C 。
因此,如果您的代码应与C 同时使用(您通常只有标题文件的要求(只需声明您的struct
s:
typedef struct foo foo;
struct foo
{
// members
};
或凝结成单个声明:
typedef struct foo
{
// members
} foo;
请注意,C 还有一个额外的陷阱。考虑以下代码:
struct foo
{
int x;
};
typedef struct foo *foo;
(旁注:typedef
指针是一个坏习惯,仅在这里用于简单演示(
此代码是有效的C,但是不是有效的C 。原因是C 需要与结构或枚举标签同名的typedef
,以指完全相同的结构或枚举类型。在C中,没有这样的要求。
此方法非常过时。要编写C 兼容的C代码,您将使用两种语言的本机bool类型(在1999年C中引入(,而不是1990年代的宏。
#include <stdbool.h>
然后使用bool
,true
和false
。
即使不需要C 兼容性,使用自己的自制布尔类型始终是不好的练习。
没有太多(更确切地说:没有(在重新创建C接口时仅通过用enum X {}
等替换typedef enum {} X
等,因为C 也很好地接受了C代码&ndash;除非您面对任何与C 不相容的C-Features(例如标题中的内联函数中使用的VLA(。否则,您只是在复制代码,这将导致可维护性问题而没有任何进一步的利润。
当然,c 包装器可以有用,但是您将为现有C接口创建一个C 界面,用于引入对象方向和可能的多态性,例如:
:// FILE wrapper in C++:
class File
{
FILE* handle;
public:
int read();
int write();
// or whatever you consider appropriate
};
// sockets:
class Socket
{
public:
// some appropriate common interface
};
class SocketTCP : public Socket
{
// appropriate specialization...
};
class SocketUDP : public Socket
{
// appropriate specialization...
};
很有可能,您可能会用这样的类替换C结构,然后将其包裹在C类型周围,但是,枚举可能会像以前一样离开 - 除非您希望它们具有不同的范围(例如nest它们在类或名称空间中(。