c语言的一些技巧
来源:互联网 发布:少儿编程入门教程 编辑:程序博客网 时间:2024/05/16 06:07
1 有一个鲜为人知的运算符叫”趋向于”, 写作“-->”。比如说如果要实现一个倒数的程序,我们可以定义一个变量x,然后让它趋向于0...C++有另一个更鲜为人知的运算符叫做“快速趋向于”,比如同样是从10到0,这里这么写
#include <stdio.h>int main(void){ int x = 10; while (0 <---- x) { printf("%d ", x); } return 0;}
8 6 4 2
作者:Geek An
链接:https://www.zhihu.com/question/27417946/answer/36617347
来源:知乎
2 以下等式皆成立:
a[5] == 5[a];"ABCD"[2] == 2["ABCD"] == 'C';
*(a + 5) == *(5 + a)
下面这个打印是否让你惊奇?#include <stdio.h>int main(void){ int x = 5; printf("%d and ", sizeof(x++)); // note 1 printf("%d\n", x); // note 2 return 0;}
它会打印出:
4 and 5
因为 sizeof 是编译时行为,运行时不会执行
作者:Geek An
链接:https://www.zhihu.com/question/27417946/answer/36617347
来源:知乎
3 代码来自参与过的开源工程ovs,OpenFlow的业界标杆)
#define OFPACTS \ /* Output. */ \ OFPACT(OUTPUT, ofpact_output, ofpact, "output") \ OFPACT(GROUP, ofpact_group, ofpact, "group")#define OFPACT(ENUM, STRUCT, MEMBER, NAME) \ BUILD_ASSERT_DECL(offsetof(struct STRUCT, ofpact) == 0); \ \ enum { OFPACT_##ENUM##_RAW_SIZE \ = (offsetof(struct STRUCT, MEMBER) \ ? offsetof(struct STRUCT, MEMBER) \ : sizeof(struct STRUCT)) }; \ \ static inline struct STRUCT * \ ofpact_get_##ENUM(const struct ofpact *ofpact) \ { \ ovs_assert(ofpact->type == OFPACT_##ENUM); \ return ALIGNED_CAST(struct STRUCT *, ofpact); \ }OFPACTS#undef OFPACT
看懂以上代码的功能了吗?它定义了一些字段,然后再通过宏来批量生成函数和enum,狂拽酷炫!
学名叫做x macro,是节省冗余代码利器,好处是非常好用,跟机关枪一样;坏处是懂的人不多,大家看到一个没有被索引的ofpact_get_GROUP很容易就进入痴呆状态。
完整版的黑魔法五可以点这里 cowry/x_macro.c at master · geekan/cowry · GitHub
4 C语言还有另一个更加鲜为人知的运算符,叫做蝌蚪运算符(tadpole operator),用于实现单目的加一、减一运算。
语法 含义 助记-~y y + 1 蝌蚪游向一个值让它变大~-y y - 1 蝌蚪离开一个值让它变小
有了这两个运算符,我们可以改写如下的代码
x = (y + 1) % 10;x = (y + 1) * (z - 1);x = (double)(f(y) + 1);
变为
x = -~y % 10;x = -~y * ~-z;x = (double)-~f(y);
减少了括号的使用,使代码更简单。
-----------
作者:武振伟
链接:https://www.zhihu.com/question/27417946/answer/49040520
来源:知乎
6 作者:justjavac
链接:https://www.zhihu.com/question/27417946/answer/36585519
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
摘自《C专家编程》 (如果你正在学习C/C++,建议你多读几遍这本书。网上有电子版,我就不给链接了。)
根据位模式构建图形图标(icon)或者图形(glyph),是一种小型的位模式映射于屏幕产生的图像。一个位代表图像上的一个像素。如果一个位被设置,那么它所代表的像素就是“亮”的。如果一个位被清除,那么它所代表的像素就是“暗”的。所以,一系列的整数值能够用于为图像编码。
类似Iconedit这样的工具就是用于绘图的,他们所输出的是一个包含一系列整型数的ASCII文件,可以被一个窗口程序所包含。它所存在的问题是程序中的图标只是一串十六进制数。
在C语言中,典型的16X16的黑白图形可能如下:
static unsigned short stopwatch[] = {0x07C6,0x1FF7,0x383B,0x600C,0x600C,0xC006,0xC006,0xDF06,0xC106,0xC106,0x610C,0x610C,0x3838,0x1FF0,0x07C0,0x0000};
正如所看到的那样,这些C语言常量并未有提供有关图形实际模样的任何线索。
这里有一个惊人的#define定义的优雅集合,允许程序建立常量使它们看上去像是屏幕上的图形。
#define X )*2+1#define _ )*2#define s ((((((((((((((((0 /* For building glyphs 16 bits wide */
定义了它们之后,只要画所需要的图标或者图形等,程序会自动创建它们的十六进制模式。使用这些宏定义,程序的自描述能力大大加强,上面这个例子可以转变为:
static unsigned short stopwatch[] ={s _ _ _ _ _ X X X X X _ _ _ X X _ ,s _ _ _ X X X X X X X X X _ X X X ,s _ _ X X X _ _ _ _ _ X X X _ X X ,s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,s _ X X _ _ _ _ _ _ _ _ _ X X _ _ ,s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,s X X _ _ _ _ _ _ _ _ _ _ _ X X _ ,s X X _ X X X X X _ _ _ _ _ X X _ ,s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,s X X _ _ _ _ _ X _ _ _ _ _ X X _ ,s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,s _ X X _ _ _ _ X _ _ _ _ X X _ _ ,s _ _ X X X _ _ _ _ _ X X X _ _ _ ,s _ _ _ X X X X X X X X X _ _ _ _ ,s _ _ _ _ _ X X X X X _ _ _ _ _ _ ,s _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _};
显然,与前面的代码相比,它的意思更为明显。标准的C语言具有八进制、十进制和十六进制常量,但没有二进制常量,否则的话倒是一种更为简单的绘制图形模式的方法。
7作者:Shanicky
链接:https://www.zhihu.com/question/27417946/answer/36583624
来源:知乎
当你需要将错误码对应到错误信息时
/* Entries may not correspond to actual numbers. Some entries omitted. */#define EINVAL 1#define ENOMEM 2#define EFAULT 3/* ... */#define E2BIG 7#define EBUSY 8/* ... */#define ECHILD 12/* ... */
你可以使用
char *err_strings[] = { [0] = "Success",[EINVAL] = "Invalid argument",[ENOMEM] = "Not enough memory",[EFAULT] = "Bad address",/* ... */[E2BIG ] = "Argument list too long",[EBUSY ] = "Device or resource busy",/* ... */[ECHILD] = "No child processes"/* ... */};
这样的代码初始化 err_strings时,指定的元素会被初始化为对应的字符串,其余元素默认初始化为08 作者:we1we1
链接:https://www.zhihu.com/question/27417946/answer/36627464
来源:知乎
不知道这个「奇技淫巧」是怎么定义的,但在用C设计模块接口的时候,有很多非常实用小tricks还是值得提一下的。
...
Redis里的sds(简易动态字符串库)struct sdshdr { int len; int free; char buf[];};
sds sdsnewlen(const void *init, size_t initlen) { struct sdshdr *sh; if (init) { sh = zmalloc(sizeof(struct sdshdr)+initlen+1); } else { sh = zcalloc(sizeof(struct sdshdr)+initlen+1); } if (sh == NULL) return NULL; sh->len = initlen; sh->free = 0; if (initlen && init) memcpy(sh->buf, init, initlen); sh->buf[initlen] = '\0'; return (char*)sh->buf; //返回了char *}
而新申请的sds返回了char *,而不是struct sdshdr *。直接使用的也是char *。这样做的目的是为了兼容一些类似strcmp、strcat的库函数。
而要使用到sds的信息时,只需要将字符串地址减去sds的大小就可以的到sds的地址。
例如:
static inline size_t sdslen(const sds s) { struct sdshdr *sh = (void*)(s-(sizeof(struct sdshdr))); //获取sds的地址 return sh->len; //返回长度}
0 0
- c语言的一些技巧
- c语言的一些技巧
- 这些天学到的一些C语言小技巧
- C/C++语言的一些技巧(1)
- C语言的一些小技巧 小知识
- C语言printf()函数中一些不为人知的技巧!
- C语言printf()函数中一些不为人知的技巧!
- 一些基本的调试技巧--C语言(二)
- 一些语言方面的技巧
- 一些C语言算法和技巧
- c语言编程一些小技巧
- C语言:C语言的一些基本概念
- C语言的学习技巧
- 编写C语言的技巧
- C语言的使用技巧
- C语言的学习机技巧
- 分享一下 本人现在在学习C语言 谁有学好C语言的一些技巧 多谢
- 编写C语言程序时需要注意的一些小技巧1
- Java集合类的混淆点总结(一)
- 简单谈谈ES6的十大特性
- 【设计模式】桥接模式
- redis安装
- POJ 3630 Phone List 静态字典树Trietree
- c语言的一些技巧
- Linux虚拟机文件传输神器psftp用法
- Box2d源码学习<十四>TOI之碰撞时间的实现
- spark学习11之在idea中将eclipse导入的java project改成maven project
- Glib学习(7) 动态指针数组 Pointer Arrays
- spring数据连接泄漏
- Linux中利用shutdown命令关闭系统方法
- memcached安装
- HYSBZ 1758 重建计划