c语言复合语句开始字符,C语言的小括号和花括号结合使用&&复合语句

先上代码,对于基于f-statck协议栈改进项目时候,看到一段代码,内核里面的很多宏也经常使用这种复合型语句,看了相关的资料和博客,写下来自己的理解:

static int (*real_clock_gettime) (clockid_t , struct timespec *);

#define SYSCALL(func) \

({ \

if (unlikely(!real_##func)) { \

real_##func = dlsym(RTLD_NEXT, #func); \

} \

real_##func; \

})

相关调用:

int clock_gettime_real(clockid_t clk_id,struct timespec *tp)

{

return SYSCALL(clock_gettime)(clk_id, tp);

}

第一次看大概明白real_clock_gettime函数未定义(大概率)时,从动态链接库操作句柄与符号,获得函数的地址,并赋给函数指针real_clock_gettime,而在函数clock_gettime_real被调用时候,先进行SYSCALLL的宏替换并调用函数real_clock_gettime(clk_id,tp)返回值等于该函数返回值。但是第一次看还是觉得理解就好并且只是认为默认都这么用,没有关心这背后的道道,怎么最终变成return real_clock_gettime(clk_id,tp);

这边涉及到复合语句的使用,结合,看了一些博客,又重新熟悉了一遍复合语句使用。

复合语句:根据百度词条描述的是,把多个语句用括号{}括起来组成的一个语句称复合语句。

复合语句用的最多的一个地方就是在一些语句中,如选择和循环语句,if,for,while中,本来只能后面跟随一条语句,利用复合语句可以达到多条语句变成一条语句的效果。当然在,用{}也是一个代码块,有代码块作用域,一些变量声明在代码块声明时,也只能在这块区域内才能被访问。

而当复合语句被小括号包裹起来时,能被充当表达式的作用(个人理解),借用别人博客的例子说明:

https://blog.csdn.net/npy_lp/article/details/7015066

#include int main(void)

{

int a = ({ int b = 8;

int c = 99;

b + c;

b + c - 10;

});

printf("a = %d\n", a);

return 0;

}

这里的执行结果a = 97,因此({ })的作用是一个表达式,表达式的值是最后复合语句的最后一个语句的值,类型是最后一个语句的类型。这边时候已经大概明白({})的作用了,如图:

45bedd4ee4924bde941f366e9444ed6e.jpg

像(Statements and Declarations in Expressions)这类的复合语句,我更愿意理解为是一个表达式,即小括号加上复合型语句变成一个表达式,整体({})执行的过程为先执行复合语句里面的每个表达式直到最后一个,然后返回一个表达式,而表达式值为小括号内最后一个表达式的值,数据类型也为最后一个表达式的数据类型。

当时为了证明这一个过程,写了一些测试代码

#include int main(void)

{

char *p;

char a, b, c;

char new[100] = "expression";

b = ({a = 3; new;})[0];

c = (({a = 4; new;}), a, *(({a = 5; new;}) + 1));

printf ("b:%c\n", b);

printf ("c:%c\n", c);

printf ("sizeof(p):%d\n", sizeof(p));

printf ("sizeof(new):%d\n", sizeof(new));

printf ("sizeof(new[0]):%d\n", sizeof(({a = 3; new;})[0]));

printf ("sizeof(expression):%d\n", sizeof(({a = 3; new;})));

}

b:e

c:x

sizeof(p):8

sizeof(new):100

sizeof(new[0]):1

sizeof(expression):8

根据这一理解,b的等号右边是先算复合型语句,({a=3;new;}),值为new的值,由于new是数据名,也是指针常量,所以new的值是一个地址,数据类型为,(char *)类型,这时候下标表达式其实跟间接访问一致,最终值为new[0]的值为字符"e“。

C的等号右边是逗号表达式,逗号表达的值为最后一个表达式的值,所以最后表达式的值为new[1]

最下面的3个sizeof的打印值

第一个相当于类型(char *)的占得字节大小

第二个是new这个数组的长度(顺便说一句,数组名通常情况下是指针常量,只有在两种情况下不用指针常量表达,一个就是sizeof操作符,一个是单目操作符&,取一个数组名的地址是一个指向数组的指针)

第三个就是指new[0]占得字节大小

第四个就是这个表达式占得字节大小

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值