GLib基础——标准宏

概览

为了使用的方便,GLib定了常用的一些宏,比如MIN、MAX等。

涉及内容

布尔类型

TRUE、FALSE、NULL的含义不说自明。

#define	FALSE	(0)
#define	TRUE	(!FALSE)
#define NULL ((void *)0)

整数相关

整数与指针相互转换

为了提高程序效率,在Glib、GTK等一些库中,为了函数中参数传递的数据常常为指针。特别地,对于32位整数类型,GLib提供4个宏,方便整数与指针的相互转换:

  • 有符号整数:GINT_TO_POINTER(i)、GPOINTER_TO_INT( p )
  • 无符号整数:GUINT_TO_POINTER(u)、GPOINTER_TO_UINT( p )

举个简单的例子如下:

#include <glib.h>

int main(int argc, char const *argv[]) {
    gpointer p;

    gint i = 10;
    p = GINT_TO_POINTER(i);
    gint j = GPOINTER_TO_INT(p);
    g_print("%d\n", j);

    guint m = -10;
    p = GUINT_TO_POINTER(m);
    guint n = GPOINTER_TO_UINT(p);
    g_print("%d\n", n);
}
// 输出
10
-10

至于为什么这样设计,读者可以自行查阅官方的文档,这里仅抛出如下几个问题:

  1. 为什么不使用 int *ip?
  2. 为什么仅仅支持32位整数?

数字大小及截断

  • MAX、MIN、ABS分别表示取最大、最小与绝对值。
  • CLAMP(x, low, high)是截断函数,用于限制x的值位于low与high之间。
  • G_APPROX_VALUE(a, b, epsilon)用于判断a与b差的绝对值是否小于epsilon,即在误差epsilon下,a与b是否足够接近。
#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
#define ABS(a)	   (((a) < 0) ? -(a) : (a))
#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
#define G_APPROX_VALUE(a, b, epsilon) \
  (((a) > (b) ? (a) - (b) : (b) - (a)) < (epsilon))

结构体相关

  • G_SIZEOF_MEMBER(struct_type, member) 用于获取结构体struct_type中member的字节大小;
  • G_STRUCT_OFFSET(struct_type, member) 用于获取结构体struct_type中member的偏移量大小;
  • G_STRUCT_MEMBER(member_type, struct_p, struct_offset) 用于返回指向member_type类型的struct_p指针的偏移struct_offset字节的成员member;
  • G_STRUCT_MEMBER_P(struct_p, struct_offset) 用于返回不确定类型的结构体struct_p指针的偏移struct_offset字节后的指针;

数组相关

define G_N_ELEMENTS(arr) 用于返回数组中元素的个数,数组的大小必须要在编译时是确定的。

#define G_N_ELEMENTS(arr)		(sizeof (arr) / sizeof ((arr)[0]))

系统相关

G_OS_WIN32、G_OS_UNIX只会在WINDOW或LINUX有定义,可以用来区分当前操作系统。
与之相关的还有目录分隔符G_DIR_SEPARATOR、搜索路径分隔符G_SEARCHPATH_SEPARATOR,分别都是字符。此外,还有相应返回字符串的版本G_**_SEPARATOR_S。比如,在LINUX下,G_DIR_SEPARATOR是’/‘,G_SEARCHPATH_SEPARATOR是’:'。

补充说明:上述中的目录分割符,也就是一般意义上的路径的分隔符。而搜索路径分隔符指定的是多个路径之间的分隔符,这个在环境变量中十分常见,linux下为 :,Windows下为**;**。

无返回函数的优化

针对与无返回函数,GNU C或MSVC在编译器中可能会有优化。G_NORETURN用来指明函数为无返回值,G_NORETURN_FUNCPTR用于指向无返回值的函数的指针。

# define G_NORETURN __attribute__ ((__noreturn__))
#define             G_NORETURN_FUNCPTR

// 示例
G_NORETURN void g_abort (void);
G_NORETURN_FUNCPTR void (*funcptr) (void);

数值计算相关

几个常数

GLib定义了若干个常用的数值,比如

  • G_E,自然常数e;
  • G_LN2,以自然常数e为底2的对数,即 log ⁡ e 2 = ln ⁡ 2 \log_e2=\ln2 loge2=ln2
  • G_LN10,以自然常数e为底2的对数,即 log ⁡ e 10 = ln ⁡ 10 \log_e10=\ln10 loge10=ln10
  • G_PI,圆周率 π \pi π
  • G_PI_2,圆周率的一半 π / 2 \pi/2 π/2
  • G_PI_4,圆周率的四分之一 π / 4 \pi/4 π/4
  • G_SQRT2,根号2, 2 \sqrt{2} 2
  • G_LOG_2_BASE_10,以10为底2的对数 log ⁡ 10 2 \log_{10}2 log102.

IEEE754浮点数定义

IEEE754单精度 float、双精度double的结构定义

/*  单精度
 *        31 30           23 22            0
 * +--------+---------------+---------------+
 * | s 1bit | e[30:23] 8bit | f[22:0] 23bit |
 * +--------+---------------+---------------+
 * B0------------------->B1------->B2-->B3-->
 *
 * 双精度
 *        63 62            52 51            32   31            0
 * +--------+----------------+----------------+ +---------------+
 * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit |
 * +--------+----------------+----------------+ +---------------+
 * B0--------------->B1---------->B2--->B3---->  B4->B5->B6->B7->
 */

此外,在联合体中分别对上述结构按段起了名字,同时指明了段是多少位。需要注意的是下面结构体mpn中的定义的顺序与前面所描述的是反过来的 (此处是小端模式,大端模式是一致的),读者可以自行对照。

union GFloatIEEE754 {
  gfloat v_float;
  struct {
    guint mantissa : 23;
    guint biased_exponent : 8;
    guint sign : 1;
  } mpn;
};
union GDoubleIEEE754 {
  gdouble v_double;
  struct {
    guint mantissa_low : 32;
    guint mantissa_high : 20;
    guint biased_exponent : 11;
    guint sign : 1;
  } mpn;
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值