C和C 类型(TypeDEF)之间的差异



我正在尝试通过重新设计我从DB类中完成的项目(创建自己的数据库系统(来理解C和C 之间的区别C语言。现在,我正在尝试重新设计项目的API,该项目也可以在用C 语言编写的应用程序中使用。

我与typedef structenumfloat等混淆了

标题文件中的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的声明。


structenum变得更加复杂,因为它们具有所谓的 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是类型名称。

相同的规则以相同的方式适用于enums。

请注意,C 确实不是" 自动typedef " a structenum。它仅允许单独使用标签名称参考这些类型。因此,额外的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>然后使用booltruefalse

即使不需要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它们在类或名称空间中(。

最新更新