1.零长度和变量长度数组
GNU C允许使用零长度数组,在定义变长对象的头结构时,这个特性非常有用。零长度数组可以实现数组扩展,结构体中必须包含长度信息,此结构体只能通过堆方式分配内存
(转)例程
#include <stdlib.h>
#include <stdio.h>
struct device{
int num;
int count;
int reserve[0]; //reserve是一个数组名;该数组没有元素;该数组的其实地址紧随结构题device之后;这种声明方法可以巧妙的实现C语言里的数组扩展
};
int main()
{
struct device * p_dev =
(struct device *) malloc (sizeof(struct device) + sizeof(int)*25);
//sizeof(int)*25是数组reserve的具体空间(25个元素)
p_dev->reserve[0] = 100;
p_dev->reserve[24] = 0;
printf("p_dev->reserve[24] = %d\n", p_dev->reserve[24]);
printf("sizeof(struct device) = %d\n",sizeof(struct device));
// 将结构体device之后的第一个内容(int值,其实就是reserve[0]的值)赋值给变量a
int a = *(&p_dev->count + 1);
printf("a = %d\n", a);
}
# ./a.out
p_dev->reserve[0] = 100
p_dev->reserve[24] = 0
sizeof(struct device) = 8
a = 100
GNU C中可以使用变量定义数组
例程
int main(int argc, char *argv[])
{
int i, n = argc;
double x[n];
for(i=0; i < n; i++)
double[i] = i;
return 0;
}
2.宏定义
第一种方法
#define mint(type, x, y) \
({type _x = (x); type _y = (y); _x < _y ? _x: _y;})
mint(int, x, y)
mint(float, x, y)
第二种方法
#define min(x, y) ( { \
const typeof(x) _x = (x); \
const typeof(y) _y = (y); \
(void) (&_x == &_y); \ //检查_x,_y类型是否一致
_x < _y? _x: _y; })
3.当前函数名
GNU C预定义了两个标志保存当前函数的名称
_ _FUNC_ _/_ _func_ _
_ _PRETTY_FUNCTION_ _保存带语言特色的名字
4.特殊属性声明
要指定一个声明的属性,只需要在声明后加_ _attribute_ _((ATTRIBUTE)),其中ATTRIBUTE为属性说明,如果存在过个属性可以用逗号分隔,GNU C 支持noreturn,format,section,aligned,packed等十几个属性
unused属性作用于函数和变量,表示该函数或变量可能不会被用到,这个属性可以避免编译器产生警告信息
aligned属性用于变量,结构体或联合体,指定对界方式,以字节为单位
例如 struct example{
char a;
int b;
long c;
}_ _attribute_ _((aligned(4)));表示该结构体的变量以4字节对齐
packed属性作用于变量和类型,用于变量或结构体成员时表示只用最小对界,用于枚举,结构体或联合体类型时表示该类型使用最小的内存