编程经验积累
1.关于位运算
#define SET_BIT(x, y) ((x) |= (1 <<(y)))
利用“或”操作将x的第y位设置为1
#define CLR_BIT(x, y) ((x) &= ~(1 <<(y)))
利用“与”操作将x的第y位设置为0
#define CPL_BIT(x, y) ((x) ^= (1 << (y)))
利用“异或”操作将x的第y位取反
#define GET_BIT(x, y) (((x) & (1 <<(y))) == 0 ? 0 : 1)
利用“与”操作将x的第y位取出
#define LET_BIT(x, y, z) ((x) = (x) & (~(1<< (y))) | ((z) << y))
利用“或且非”操作将x的第y位设置为z
2.关于文件包含
如果使用Makefile文件定义了头文件的位置参数,可以使用
#include "xxxx.h" 包含不在当前目录下的头文件。
3.字符串按数组处理最后要加xxx[i] = '\0';
4.读权限4,写权限2,执行权限1
5.NULL = ((void *)0)
6.结构体嵌套的问题
如果定义中A结构体中包含一个B结构体指针,同时B结构体中包含一个A结构体指针,可以采用如下定义方法:
typedef struct _B B;
typedef struct _A A;
struct _A
{
……
B *pb;
};
struct _B
{
……
A *pa;
};
7.可利用函数的返回值选择执行代码
例如:有一个函数fun()返回值可能是:-1、1、0,可以利用该返回值选择执行代码。
int ret=0;
if((ret=fun()))要有三重括号才可以。
8.利用static 变量控制函数代码
#include <stdio.h>
static int maxspans = 0;
static int can_open_timer(void)
{
#ifdef CONFIG_DAHDI_CORE_TIMER
return 1;
#else
return maxspans > 0;
#endif
};
int main()
{
if (can_open_timer())
printf("return dahdi_timing_open(file);\n");
else
printf("return -ENXIO;\n");
}
9.利用return调用另外一个函数
例如:returndahdi_timing_open(file);
10.switch语句中不用break用return语句结束一个case
11. break 语句结束循环,其后的循环部分不再执行
#include <stdio.h>
int main()
{
intx;
for(x = 0; x < 10; x++) {
if(x == 5) break;
printf("hell %d\n",x);}
}
12 strcmp函数实现
int strcmp(const char *cs, const char *ct)
{
signedchar __res;
while(1) {
if((__res = *cs - *ct++) != 0 || !*cs++)
break;
}
return__res;
}
常用命令
find . -type f -exec grep "string" {} \; -print
find . -type f -regex ".*\.c" -exec grep "string" {} \; -print
find persistent -type d -name.svn | xargs rm -rf
12 使用/proc文件系统
首先包含<linux/proc_fs.h>
定义自己的read_proc函数,
该函数原型是 read_proc(char *page, char **start, off_t off, int count,int *eof,void *data);
page指针指向用来写入的数据缓冲区;start用来指示要返回给用户的数据保存在内存页的开始位置;如果为NULL,内核假定数据保存在内存页偏移量为0的地方,
例如:int dahdi_proc_read(char *page, char **start, off_t off, int count,int *eof, void *data)
定义好自己的read_proc函数后使用
struct proc_dir_entry*create_proc_read_entry(const char *name,
mode_t mode, struct proc_dir_entry *base,read_proc_t *read_proc, void * data)
create_proc_read_entry()函数参数介绍:
name是要创建的文件名称;mode是该文件的保护掩码;base指定该文件所在目录;如果base为NULL,该文件将创建在/proc的根目录;read_proc是实现该文件的read_proc函数;内核会忽略data参数。
把自己的read_proc函数与/proc入口项连接起来。
例如:proc_entries[span->spanno] = create_proc_read_entry(tempfile,0444,
NULL,dahdi_proc_read, (int *) (long) span->spanno);
extern struct proc_dir_entry*proc_mkdir(const char *,struct proc_dir_entry *);
struct proc_dir_entry *proc_mkdir(constchar *name,
structproc_dir_entry *parent)
{
returnproc_mkdir_mode(name, S_IRUGO | S_IXUGO, parent);
}
13 使用赋值语句做判断
例如 if (!(ret=1))
赋值语句的结果是真还是假与所赋值有关,赋值为非零值的时候,结果为真,反之假。
14 复杂语句判断
例如 if a
if b
if c
语句
else
语句
a假什么都不执行。
15.typedef 还可以掩饰复合类型
如指针和数组。你不用像下面这样重复定义有 81 个字符元素的数组:
charline[81];
chartext[81];
定义一个 typedef,每当要用到相同类型和大小的数组时,可以这样:
typedefchar Line[81];
Line text,secondline; getline(text);
typedef short sumtype[DAHDI_MAX_CHUNKSIZE];定义一个数组
static sumtype sums[(DAHDI_MAX_CONF + 1) *3];定义一个元素都是数组的数组
16.希望某些代码只执行一次的做法
在某个函数内部定义一个局部静态变量。
static intinitd_ifaces=0
if(!initd_ifaces){
……函数代码;
initd_ifaces=1;
}
17.指针和数组之间特殊关系
#include<stdio.h>
#include<stdlib.h>
static charwc_iRxBuffer_x[64] = {0};
voidcan_open_timer(int *read, int index)
{
int i;
i = index;
read[i] = wc_iRxBuffer_x[0];
printf("read[i]=%d\n",read[i]);
};
int main()
{
int *pread;
pread = malloc(sizeof(int));
if(pread)
can_open_timer(pread, 0 );
}
18.字节顺序问题
大端Big-Endian低地址存放最高有效位(MSB),既高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。
小端Little-Endian低地址存放最低有效位(LSB),既低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。
嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。
例如,16bit宽的数0x1234
在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 存放内容
0x4001 0x12
0x4000 0x34
而在Big-endian模式CPU内存中的存放方式则为:
内存地址 存放内容
0x4001 0x34
0x4000 0x12
32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为:
内存地址 存放内容
0x4003 0x12
0x4002 0x34
0x4001 0x56
0x4000 0x78
而在Big-endian模式CPU内存中的存放方式则为:
内存地址 存放内容
0x4003 0x78
0x4002 0x56
0x4001 0x34
0x4000 0x12
大端模式下
8位数据转16位数据
0xAB 0x00AB
16位数据=(16位)8位数据左移8位; 8位---------->16位
8位数据= (8位)16位数据右移8位; 16位--------->8位
19.长延时算法
static void wait_just_a_bit(int foo)
{
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(foo);
}
static void wait_just_a_bit(int foo)
{
longnewjiffies;
newjiffies= jiffies + foo;
while(jiffies< newjiffies);
}
20.优先级问题
x = y + z>>n 等价于 x = (y + z) >>n