编程积累

来源:互联网 发布:淘宝链接怎么发给客服 编辑:程序博客网 时间:2024/05/16 08:27

编程经验积累

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

 

 


原创粉丝点击