c 语言几个特殊写法

1 零长度和变量长度数组

  • 零长度数组
    GNU C 编译器允许使用零长度数组,在定义变长对象的头结构体时,这个特性非常有效,例如:
struct var_data
{
  int len;
  char data[0];
};

char data[0] 仅仅意味着程序中通过 var_data 结构体实例的 data[index] 成员可以访问len 之后的第 index 个地址,它并没有为 data[]数组分配内存,因此 sizeof(struct var_data) = sizeof(int)。

假设struct var_data 的数据域就保存在 struct var_data紧接着的内存区域中,则通过如下代码可以遍历这些数据:

struct var_data s;
...
for(i = 0; i < s.len; i++)
    printf("%02x", s.data[i]);
  • 变量长度数组
    GNU C中也可以使用 1 个变量定义数组,例如如下代码中定义 double x[n]:
int main(int argc, char **argv)
{
  int i, n = argc;
  double x[n];
  for (i = 0; i < n; i++)
    x[i] = i;
  return 0;
}

2 宏定义语句表达式

GNU C 把包含在括号中的复合语句看成一个表达式,成为语句表达式,它可以出现在任何允许表达式的地方。我们可以在语句表达式中使用原本只能在复合语句中使用的循环、局部变量等。例如:

#define min_t(type, x, y) \
( { type __x = (x);  \
type __y = (y);  \
__x < __y? __x : __y; \
})
int ia, ib, mini;
float fa, fb, minf;
mini = min_t(int, ia, ib);
minf = min_t(float, fa, fb);

3 typeof 关键字

typeof(x)语句可以获得 x 得类型,可以借助typeof重定义宏。

#define min_t(x, y) \
( { typeof(x) __x = (x);  \
typeof(x) __y = (y);  \
__x < __y? __x : __y; \
})

4 可变参数宏

标准c 就支持可变参数函数,意味着函数得参数时不固定得,例如printf() 函数得原型为:
printf(const char *fmt, arg...);
在 GNU c 中,宏也可接收可变数目得参数,例如:
#define pr_debug(fmt, atg...) prink(fmt, ##arg)

使用 ## 是为了处理arg不代表任何参数得情况,此时,前面的逗号就多余了,使用 ## 后,GNU预处理器会丢弃前面的逗号。

5 标号元素

标准 C 要求数组或结构体的初始化值必须以固定的顺序出现,在GNU C 中,通过指定索引或结构体成员名称,允许初始化值以任意顺序出现。

指定数组索引的方法是在初始化值前加“[index] =”,当然也可以用 "[fisrt ... last]="的形式指定一个范围。例如:
unsigned char data[MAX] = { [0 ... MAX - 1] = 0};

结构体初始化,例如:

struct test_t a =
{
.lseek = 1,
.read = 2,
};

6 特殊属性声明

GNU C 允许声明函数、变量和类型的特殊属性,以手动优化代码和定制代码检查的方法。要指定一个声明的属性,只需要在声明后添加 attribute((ATTRIBUTE)),其中 ATTRIBUTE 为属性说明,如果存在多个属性,则用逗号隔开。GNU C 共支持 noreturn、 format、section、aligned、packed等十多个属性。

  • noreturn 属性作用于函数,表示函数从不返回。这会让编译器优化代码并消除不必要的警告。例如:
#define ATTRIB_NORET   __attribute__((noreturn))
asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET
  • format 属性也作用于函数,表示该函数使用 printf,scanf 或 strftime 风格的参数,指定 format 属性可以让编译器根据格式化字符串检查参数。
    asmlinkage int printk(const char *fmt, ...) __attribute__((format (printk, 1, 2)));
  • unused 作用于未用到的函数或变量,用于消除编译警告。
  • aligned 作用指定变量、结构体、联合体的对齐方式,以字节为单位。
struct example_struct 
{
  char a;
   int b;
  long c;
} __attribute__((aligned(4)));
  • packed 属性用于变量或结构体成员时表示最小可能的对齐,用于枚举、结构体或联合体类型时表示该类型使用最小内存。
struct example_struct 
{
  char a;
  int b;
  long b __attribute__((packed));
};

7 内建函数

GNU C 提供了大量内建函数,其中大部分标准 C 库函数的 GNU C 库的内建版本,例如 memcpy() 等,它们与对应的标准 C 库函数功能相同。

不属于标准库函数的其它内建函数的命名通常以 __builtin 开始,如下所示。

  • 内建函数 __builtin_return_address(LEVEL),返回当前函数或其调用者的返回地址,参数 LEVEL 用于指定调用栈的级数,如 0 表示当前函数的返回地址,1 表示当前函数的调用者的返回地址。

注意:在使用 gcc 编译 c 程序的时候,如果使用 “-ansi -pedantic” 编译选项,则会告诉编译器不适用 GNU 的扩展语法。使用上述特性就会出现编译告警。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容

  • 官网 中文版本 好的网站 Content-type: text/htmlBASH Section: User ...
    不排版阅读 4,359评论 0 5
  • 第2章 基本语法 2.1 概述 基本句法和变量 语句 JavaScript程序的执行单位为行(line),也就是一...
    悟名先生阅读 4,114评论 0 13
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,579评论 18 139
  • 2017年2月16日 一度症结是来源于两个人的冲突,一个人的父母状态是哪里来的呢? 是父母那里学习过来的! 就是他...
    阿甘阿干阅读 363评论 0 0
  • 释放天性的活儿,总能让人忘乎自我,兴趣所在的东西,总会让人忘记时间的流淌。晚安!
    邻里的林阳光阅读 214评论 0 0