微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C 中的 typedef 和函数指针

如何解决C 中的 typedef 和函数指针

我在自己的头文件和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(...); 

解决方法

一个粗略而简单的解决方案:

// 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

,

是否可以为代码创建一个新的头文件和 c 文件,以便使用新的适当描述性声明“继承”这些特定类型和函数?

C 是一种非常(现在;)简单的语言,您必须自己编写很多。其他语言——尤其是面向对象的语言、C++、Java——具有内置的“继承”特性,该语言本身允许将所有函数从一个地方“导入”到另一个地方。

C 没有这个特性。在 C 中,您必须自己从头开始编写所有内容。

我不确定这是否正确

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

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

而是在源文件中的头文件和定义中放置一个函数声明

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

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

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

// function2.h
process_dest process_dest_data = &process_src_data;

要么将函数指针设为static,要么将其移动到单独的C源文件并在头文件中添加extern。此外,如果它打算保持不变,则向其中添加 const,因此可以将其优化为只读部分而不使用 RAM。

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

实现我所追求的工具。

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

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。