本文首发于公众号:嵌入式软件实战派
交换俩变量数据,一般做法是:
// 方法1
temp = a;
a = b;
b = temp;
// 方法2
a=a+b;
b=a-b;
a=a-b;
方法1需要第三个变量,方法二存在数据溢出可能,可以尝试下以下方法:
a = a ^ b;
b = a ^ b;
a = a ^ b;
const
数值放在前面通常条件语句写成
if(n == 0){
/*...*/ }
但是,有可能手误写成
if(n = 0){
/*...*/ }
这种错误只有机器在运行时候知道,而人不一定能发现这种bug。
把数值放在前面就不怕了,==
写成=
,编译器就知道
if(0 == n){
/*...*/ }
if...else...
语句这个用法应该很普遍了,不算什么特别的技巧了。
if(y < 0)
{
x = 10;
}
else
{
x = 20;
}
可以改成以下一行代码即可
x = (y < 0) ? 10 : 20;
也许你会不断地将这个数除以2,除到底,然而Linux kernel有个巧妙的办法:
#define is_power_of_2(n) ((n) != 0 && ((n) & ((n) - 1)) == 0)
((n) & ((n) - 1)) == 0
这个不理解?那先想想2的X次方的值的二进制是怎样的。
直接看代码
struct mylist {
int a;
struct mylist* next;
};
#define cons(x, y) (struct mylist[]){
{x, y}}
struct mylist *list = cons(1, cons(2, cons(3, NULL)));
struct mylist *p = list;
while(p != 0) {
printf("%d\n", p->a);
p = p -> next;
};
#include
#include
struct line
{
int length;
char contents[0];
};
struct line *thisline = (struct line *) malloc (sizeof (struct line) + this_length);
thisline->length = this_length;
struct f1 {
int x; int y[]; } f1 = {
1, {
2, 3, 4 } };
struct f2 {
struct f1 f1; int data[3]; } f2 = {
{
1 }, {
2, 3, 4 } };
详见6.18 Arrays of Length Zero
int a[10] = {
0,1,2,3,4,5,6,7,8,9};
int b[10] = {
0};
b = a;
这样是非法的,但是你可以放数组穿个马甲:
typedef struct
{
int n[10];
}S;
S a = {
{
0,1,2,3,4,5,6,7,8,9}};
S b = {
0};
b = a;
#include
的不一定是要.h
文件#include
后面跟的可以是任意后缀的,但文件内容一定要是合法的。不信?你试试这个:
// plus.fxxk
int plus(int a, int b)
{
return a+b;
}
// main.c
#include
int a = 1, b = 1;
#include "plus.fxxk"
int main(void)
{
printf("plus %d + %d = %d\n", a, b, plus(a,b));
return 0;
}
#define var(left, right) __typeof__(right) left = (right)
var(s, 1LL); // 相当于 long long s = 1LL;
是不是有点像C++ 11的auto类型?
MIN(x,y)
的终极做法#define MIN(x, y) x < y? x : y // 这样给0分
#define MIN(x, y) (x < y? x : y) // 这样给50分
// 不信你试试这个
int n = 3 * MIN(3, 4 < 5 ? 4 : 5);
#define MIN(x, y) ((x) < (y)? (x) : (y)) // 这个给90分
// 不信你试试这个
double xx = 1.0;
double yy = MIN(xx++, 1.5);
printf("xx=%f, yy=%f\n",xx,yy);
// 以下放大招了,看看GNU的
#define MIN(A,B) ({ __typeof__(A) __a = (A); __typeof__(B) __b = (B); __a < __b ? __a : __b; })
double xx = 1.0;
double yy = MIN(xx++, 1.5);
printf("xx=%f, yy=%f\n",xx,yy);
未完待续……