这阵子在C语言环境做开发,写了大量宏函数,写得头疼,但使用宏函数模板的确可以提高开发效率及代码质量,所以还得硬着头皮写,在一个偶然的机会发现有个叫P99的开源项目,P99提供了大量的的宏和函数定义,用于简化C编程,。说白了,P99提供的就是一大堆.h头文件,.h文件中定义了大量的宏函数,利用这些宏函数可以简化C代码开发。

比如下面用了P99中提供的例程实现了C++中才有的try-catch-finally语句:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <stdatomic.h>
#include <p99_try.h>
void test_try(){unsigned char*volatile buffer = 0;P99_TRY {buffer = malloc(200);if (!buffer) P99_THROW(thrd_nomem);printf("return %s\n",__FUNCTION__);// do something complicated with buffer//favorite_func(buffer);} P99_FINALLY {free(buffer);}}
int main(void) {test_try();return EXIT_SUCCESS;
}

定义enum

// 定义名为`enum_test`,包含`hello,world)`两个值的枚举类型
P99_DECLARE_ENUM(enum_test,hello,world);

宏展开后的代码

typedef enum enum_test { hello,world ,                                                \/*! upper bound of the @ref T constants */                     \enum_test_amount,                                        \/*! the largest @ref T constant */                             \enum_test_max = ((size_t)(enum_test_amount) - 1u), \/*! the smallest @ref T constant */                            \enum_test_min = 0                                        \
} enum_test;                                                                          \
__attribute__((__const__))                                             \
__attribute__((__always_inline__)) __inline__                                                     \
char const* enum_test_getname(enum_test p00_x) {                 \switch ((uintmax_t)p00_x) {                                  \case hello: return "hello"; case world: return "world";                       \default: return "((" "enum_test" ")unknown value)";                   \}                                                            \
}                                                              \
extern void p00_harmless_declaration_declare_enum_getnameenum_test(void);                                     \
__attribute__((__pure__))                                              \
__attribute__((__always_inline__)) __inline__                                                     \
enum_test enum_test_parse(char const p00_s[]) {                  \enum_test p00_ret = enum_test_amount;                          \if (p00_s) {                                                 \size_t p00_c = 0;                                          \size_t const p00_len = strlen(p00_s);                      \if (!memcmp("hello", p00_s, p00_len)) {               \++p00_c;                                                     \p00_ret = hello;                                                 \}; if (!memcmp("world", p00_s, p00_len)) {               \++p00_c;                                                     \p00_ret = world;                                                 \};                      \if (p00_c > 1) p00_ret = enum_test_amount;           \}                                                            \return p00_ret;                                              \
}                                                              \
extern void p00_harmless_declaration_declare_enum_parseenum_test(void)

定义struct

P99_DEFINE_STRUCT(struct_test,int hello,char* world);

展开后的代码

struct fl_buf_info {                                                  \int hello; char* world;                             \
};                                                             \
typedef int hello_P99_typedef_of_fl_buf_info;
typedef char* world_P99_typedef_of_fl_buf_info

参数判断

P99_IS_ONE(first,...)可以检查first是否属于__VA_ARGS__参数列表中的一个

// 先定义一个包含所有参数名的enum
P99_DECLARE_ENUM(enum_names,tom,jerry,sam,smith,trump,bill)if (P99_IS_ONE(tom, jerry,sam,smith,trump,bill)) {// one of the guys is 23, do something special} else {// handle the base case}

函数声明

// 定义一个函数声明
P99_PROTOTYPE (void,hello,int,void*);

展开

void (hello)(int,void*);     \typedef void hello_prototype_ret;                   \typedef int hello_prototype_0; typedef void* hello_prototype_1

还有很多其他的功能不一一列举,参见p99手册 《P99 - Preprocessor macros and functions for C99 and C11
》。
为了快速熟悉P99的内容建议从分类说明入手《Modules》

安装

p99提供的只是一堆头文件,所以从http://p99.gforge.inria.fr/ 这里下载p99.zip或p99.tgz解压到自己的项目文件夹下,并添加到include搜索路径就算安装完成了。
建立下载说明文档p99-html.zip到本地以便随时查看,内容实在太多,不看文档搞不清楚。

参考资料

《P99_TRY》
《P99_IS_ONE》

c语言下利用p99:模拟实现try-cath-finally相关推荐

  1. Delphi下利用WinIo模拟鼠标键盘详解

    本文最早在编程论坛上发表,文章地址:http://programbbs.com/bbs/view12-17207-1.htm,相关文件可以在上述地址的页面中下载.转载时请注明出处. 前言 一日发现Se ...

  2. Delphi下利用SendInput模拟鼠标键盘

    前言 发了一篇<Delphi下利用WinIo模拟鼠标键盘详解>(http://programbbs.com/bbs/view12-17207-1.htm),再发一个利用SendInput模 ...

  3. 停止等待协议算法c语言实现,利用udp模拟arq停止等待协议

    停止等待arq协议: 停止等待协议(stop-and-wait)是最简单但也是最基础的数据链路层协议.很多有关协议的基本概念都可以从这个协议中学习到."停止等待"就是每发送完一个分 ...

  4. Linux 下利用netem模拟广域网特性

    一.netem 与 tc: netem 是 Linux 2.6 及以上内核版本提供的一个网络模拟功能模块.该功能模块可以用来在性能良好的局域网中,模拟出复杂的互联网传输性能,诸如低带宽.传输延迟.丢包 ...

  5. java tess4j训练库_java语言下利用tess4j开源库进行图片中的文本提取

    一,tess4j 简单介绍 Tess4J是对tesseract -OCR API.的Java JNA 封装,使java能够通过调用Tess4J的API来使用tesseract -OCR 我有一篇博客也 ...

  6. matlab腔内光子寿命,mcFORnp matlab环境下,利用蒙特卡洛模拟光子包在生物组织内的光路传输 271万源代码下载- www.pudn.com...

    文件名称: mcFORnp下载  收藏√  [ 5  4  3  2  1 ] 开发工具: matlab 文件大小: 215 KB 上传时间: 2014-12-29 下载次数: 8 提 供 者: 徐某 ...

  7. c语言大作业 模拟泊松分布,C语言下泊松分布以及指数分布随机数生成器实现

    最近实验室的项目需要实现模拟文件访问序列,要求单位时间内的数据请求次数符合泊松分布,而两次请求见的时间间隔符合指数分布.没办法只好重新捡起已经丢掉多时的概率知识.于是也就有了这篇关于在C语言下符合泊松 ...

  8. Windows10下利用Visual Studio Code搭建C语言开发环境

    Windows10下利用Visual Studio Code搭建C语言开发环境 1. 前言 2. 下载安装VSCode以及MinGW 2.1 下载安装VSCode 2.2 下载安装MinGW-w64 ...

  9. c语言编程模拟机械钟表行走,C语言课程设计报告-模拟时钟转动程序

    1. 课程设计报告题 目 课 程 名 称 结构化程序设计课程设计 院 部 名 称 专 业 班 级 学 生 姓 名 王蕾 学 号 课程设计地点 课程设计学时 指 导 教 师 金陵科技学院教务处制 程序设 ...

最新文章

  1. 8.8线段树和树状数组
  2. linux c指定相对路径,linux c编程,选用popen()得到一个相对路径的绝对路径
  3. Mybatis报错 TooManyResultsException
  4. 重写系统中的UINavigationController返回按钮的事件
  5. 不同的容器里实现 RadioButton的单选
  6. 阿里面试回来,想和 Java 程序员谈一谈
  7. mysql 删除重复数据_日常答疑|MySQL删除重复数据踩过得坑
  8. node ajax validator,使用validator.js对字符串数据进行验证
  9. python使用print不换行
  10. java 7 40,Java 7u40 Java SE 8 sun.reflect.Reflection.getCallerClass
  11. 系统协调服务器,协调网络系统 Collaboration network system
  12. 杭电 1060 Leftmost Digit
  13. java定时器与ThreadLocal编程陷阱
  14. ie visio 打开_Visio viewer 不能从IE打开vsd文件
  15. java程序设计基础陈国君_Java程序设计基础(第6版)
  16. 黑猴子的家:JavaWeb 之 CSS
  17. 用Cat.1+GPS+蓝牙+RFID实现工卡式室内室外定位器
  18. Why we need activation function?
  19. TexStudio 快捷键 ctrl+R 查找替换
  20. Backpack Cryptography【背包密码】

热门文章

  1. 探寻胡适的精神世界——欧阳哲生著
  2. excel如何拆分分数条
  3. 关于360浏览器F12 network中看不到请求头的原因
  4. pbl和sbl_PBL+SBL在计算机公共课程教学中的应用
  5. 基于OIDC实现单点登录SSO、第三方登录
  6. php正则判断qq,JavaScript中的正则表达式使用及验证qq号码的正则
  7. 移动端H5直播/点播前端入坑简易手册
  8. Python学习笔记(2)
  9. 20222934 2022-2023-2 《网络攻防实践》第3次作业
  10. 就医160_【就医160】就医160下载-PChome下载中心