C 中的 typedef 和函数指针

typedef in C and function pointers

我在自己的头文件和 c 文件中编写了一些结构和对它们进行操作的相应函数。

我想知道是否可以为代码创建一个新的头文件和 c 文件,以使用新的适当描述性声明“继承”那些特定类型和函数?是否可以以这种方式对函数和结构进行 typedef 以重用代码?

我研究了函数指针,但我不确定这是否是实现我所追求目标的正确工具。我想另一种选择是重构代码,使名称通用。

代码示例:

// function1.h

typedef struct src_data {
      ...
} src_data;

src_data* process_src_data(...) {
   ...
   return new_data;
}
// function2.h

#include "function1.h"
typedef src_data dest_data;

typedef dest_data* (*process_dest)(void);
process_dest process_dest_data = &process_src_data;

用法如下:

#include "function1.h"
#include "function2.h"

src_data *sourceData = process_src_data(...);

dest_data *destinationData = process_dest_data(...); 

if it was possible to create a new header and c file for code that would "inherit" those particular types and functions with a new appropriatly descriptive declaration?

C 是一种非常(如今 ;)简单的语言,您必须自己写很多东西。其他语言——特别是 object-oriented 语言、C++、Java——具有内置的“继承”功能,该语言本身允许将所有功能从一个地方“导入”到另一个地方。

C没有这个功能。在 C 中,你必须自己从头开始写。

I am not sure if this is the correct

  1. 不要在 header 文件中 定义 函数。不要:

// function1.h
src_data* process_src_data(void) { /* NO */ }

而是将函数 声明 放入 header 并在源文件中定义。

// function1.h
src_data* process_src_data(void); //ok
// function1.c
src_data* process_src_data(void) { ok(); }

否则它不是“正确的”,从某种意义上说,包含 header 的多个 .c 文件链接在一起会导致“多重定义”问题。

  1. 类似于函数指针声明:

// function2.h
process_dest process_dest_data = &process_src_data;

要么制作函数指针static,要么将其移动到单独的C 源文件并将extern 添加到header。如果它打算保持不变,请另外添加 const,以便它可以优化为 read-only 部分并且不使用 RAM。

// function2.h
extern const process_dest process_dest_data;
// function2.c 
const process_dest process_dest_data = &process_src_data;

tool to achieve what I am after.

函数指针占用内存。调用函数指针需要取消引用它们。它们很难优化。

在 C 中编写简短的 static 包装函数是典型的做法:

// function2.h
static process_dest process_dest_data(void) {
     return process_src_data();
}

如果函数很短,它将被编译器内联并从生成的可执行文件中删除。更长的时间,只需编写一个调用底层实现的常规函数​​即可。

粗略的解决方案:

// function2.h
#define process_dest_data process_src_data

一种稍微好一点的方法是使用 static inline 函数作为包装器:

// function2.h
static inline dest_data* process_dest_data(void) {
    return process_src_data();
}

使用 inline 将帮助您避免有关未使用函数的警告。

两者可能会产生相似的目标代码。

宏相对于包装器有一个微妙的优势。假设 process_src_data 有外部链接。表达式 &process_dest_data 可能 在每个翻译单元中具有不同的值。如果使用宏,则值将相同,等于 &process_src_data.