c语言常用技巧

 



1
:宏函数的实现

#definereadl(addr) (*(volatile unsigned int*)(addr))
#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b)):

     宏函数里也可以定义变量

       #define readb(addr) \
         ({ unsigned char __v =(*(volatile unsigned char *) (addr)); __v; })  /*  \
后面就是一个回车键,宏定义就是字符串替换*/
        #define readw(addr) \
          ({ unsigned short__v = (*(volatile unsigned short *) (addr)); __v; })

     局部变量的合法定义位置,依赖于编译器遵循的C规范版本:

                   1、仅支持C89规范的编译器,只支持在作用域起始部分定义变量。

                   2、支持C99或者部分支持C99的编译器:局部变量可以定义在任何位置

 

2:寄存器结构体的地址转化

#defineS3C24X0_CLOCK_POWER_BASE 0x4C000000

structs3c24x0_clock_power {
 u32 LOCKTIME;
 u32 MPLLCON;
 u32 UPLLCON;
 u32 CLKCON;
 u32 CLKSLOW;
 u32 CLKDIVN;
#if defined (CONFIG_S3C2440)
 u32 CAMDIVN;
#endif
};

staticinline struct s3c24x0_clock_power *s3c24x0_get_base_clock_power(void)
{
 return (struct s3c24x0_clock_power *)S3C24X0_CLOCK_POWER_BASE;/*
将这一块内存转化为结构体类型*/
}

structs3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

 

3:代码屏蔽

#if0       //这段代码屏蔽掉
 unsigned long cpu_clk; /* cpu频率*/
 unsigned long bus_clk;/*
总线频率*/
 phys_size_t ram_size; /* RAM
大小设置,64M*/
 unsigned long reset_status; /*
重新设置状态地址*/
#endif

 

4:条件编译

  flash_info[i].flash_id=
#if defined(CONFIG_AMD_LV400)
//include/flash.h
中对flashMANUFACTVENDMASKTYPEMASK有定义,主要是flashID
   (AMD_MANUFACT & FLASH_VENDMASK) |
   (AMD_ID_LV400B & FLASH_TYPEMASK);
#elif defined(CONFIG_AMD_LV800)
   (AMD_MANUFACT & FLASH_VENDMASK) |
   (AMD_ID_LV800B & FLASH_TYPEMASK);
#else
#error "Unknown flash configured"
#endif

 

5NULL空的定义

   空指针:

                        #ifndef NULL
                         #defineNULL               ((void*) 0)
                           #endif    /*NULL*/

       空值:

                           #ifndefNULL

                          #define NULL 0

                          #endif

 6:带路径的头文件包含

     board.c

      #include "../drivers/net/smc91111.h"

       ..是表示当前board.c源文件所在目录的上层目录

       .表示当前board.c源文件所在的当前目录

       例子中board.c完整路径:      D:\ouyangLinux\uboot sourceinsight工程\u-boot-2010.03-embedclub-201111\u-boot-2010.03\lib_arm\board.c

                   smc91111.h完整路径:D:\ouyangLinux\ubootsourceinsight工程\u-boot-2010.03-embedclub-201111\u-boot-2010.03\drivers\net\smc91111.h

        注意wen7Linux的路径斜杠方向相反,很容易记反,打开计算机的搜索路径就知道斜杠方向,Linux方向就是烦的

7:如何给数组整体赋值

     C语言中是没有整体给数组赋值的函数

     我们只能通过内存操作来一个一个字节的给数组的成员全部赋值,所以一般我们是对一个数组进行整体清零的操作,而不能通过内存操作函数来实现给数组整体赋一个非零的值

      int i , hash[256];  

       memset(hash , 0 , sizeof(hash)); 

8:函数参数不能传递整个数组,只能传递数组的首地址,至于数组的内存的尾地址在哪里?传递的数组有多少个数组成员?一种方法是数组末尾成员用NULL‘\0’等填充这个成员,另一种方法是再多传递一 个参数,指明数组有几个数组成员。

     函数参数如何传递结构体?其实和传递int一样,会在函数内部定义一个局部变量,然后将它复制参数。所以传递结构体时我们也经常用指针方式传递。

9&&条件的注意

   //dev是在内核进行驱动和设备匹配时得到的设备的结构体, type是我们要取哪一种类型的资源,num是要取这种类型资源的第几个,

struct resource*platform_get_resource(struct platform_device *dev,

                                          unsigned int type, unsigned int num)

{

         inti;

 

         for(i = 0; i < dev->num_resources; i++) {

                 structresource *r = &dev->resource[i];

 

                 if(type == resource_type(r) && num-- == 0)

                          returnr;//注意只有在资源类型匹配时,后面的语句才会执行,例如取这种资源类型type的第一个资源,则num--==0立刻满足条件,这///里是后减减,如果取第一个资源,则1!=0,下次再次遍历到这个资源类型是0--==0满足条件,就可以取出这个资源了

         }

         returnNULL;

}

 10:结束数组遍历的方法:循环数组最后一个元素的初始化,数组最后一个元素为空或为-1:全身上下都是零

#include <stdio.h>

struct test{

   int a;

   char b;

   

};

struct test array[]={

  [0] = {0,0},

   {1,2},

   {3,4},

   {},//c语言语法会自动填零

};

 

int array2[4]={

   1,2,3,//c语言语法会自动填零

   

};

 

char *str1="12345";

char *str2="67890";

 

struct str{

   char *string;

};

struct str strarray[]={

   [0]={str1},

   {str2},

   {}   //c语言语法会自动填零

   

};

int main(void)

{

   printf("/*************知道数组大小来结束遍历数组****************/\n");

   int i=0;

   for(;i<4;i++)

   {

      printf("array[%d]:a=%d,b=%d\n",i,array[i].a,array[i].b) ;

   }

   i=0;

   for(;i<4;i++)

   {

      printf("array2[%d]:%d\n",i,array2[i]) ;

   }

   printf("/*************用数组最后一个元素来结束遍历数组****************/\n");

   i=0;

   while(array2[i])

   {

      printf("array2[%d]:%d\n",i,array2[i]) ;

      i++;

   }

   i=0;

   while(strarray[i].string)  //在ASCII中转义字符'\0'对应时进制数是0,所以一个字符串为空""或是填0都可以作为数组遍历结束条件

   {

      printf("strarray[%d]:%s\n",i,strarray[i].string) ;

      i++;

   }

         return0;

}

输出结果:

/*************知道数组大小来结束遍历数组****************/
array[0]:a=0,b=0
array[1]:a=1,b=2
array[2]:a=3,b=4
array[3]:a=0,b=0
array2[0]:1
array2[1]:2
array2[2]:3
array2[3]:0
/*************
用数组最后一个元素来结束遍历数组****************/
array2[0]:1
array2[1]:2
array2[2]:3
strarray[0]:12345
strarray[1]:67890

 11结构体内数组成员如何初始化

typedef struct{

    inttype;

   unsigned scl;

   unsigned sda;

   void (*pinUnMapFunc)(void);

   void (*pinMapFunc)(void);

}I2CHwDefTy;

 

typedef struct

{

   I2CHwDefTy i2cs[SUPPORT_I2C_NUM];

}I2CConfigTy;

 

const I2CConfigTy i2c_conf ={

   .i2cs = {

       /*type  SCL       SDA        unMapFunc    MapFunc */

       {0,   GPIO_PA4,  GPIO_PA3, i2c_ch0_unMap, i2c_ch0_map},

       {0,   GPIO_PB5,  GPIO_PB4, i2c_ch1_unMap, i2c_ch1_map},

       {0,   GPIO_PD28, GPIO_PD27,i2c_ch2_unMap, i2c_ch2_map},

    }

};

亦可写成

const I2CConfigTy i2c_conf ={

   .i2cs = {

       /*type  SCL       SDA        unMapFunc    MapFunc */

                  数组成员就是[0],而不是.[0]了!

       [0]={0,   GPIO_PA4,  GPIO_PA3, i2c_ch0_unMap, i2c_ch0_map},

       {0,   GPIO_PB5,  GPIO_PB4, i2c_ch1_unMap, i2c_ch1_map},

       {0,   GPIO_PD28, GPIO_PD27,i2c_ch2_unMap, i2c_ch2_map},

    }

};

 我的想法:[0]是划分了一块内存,即使你不填入数据这块内存也已经分配好了{0,    GPIO_PA4, ,  }

 .  符合代表初始化哪一个结构体成员变量

 12:结构体数组的成员初始化

typedef struct{

        unsignedint base;

        unsignedint fclk;

        unsignedint irq;

   XDMA_Peripheral_TypeDeftx_dma_perip;

   XDMA_Peripheral_TypeDefrx_dma_perip;

}UartDescTypedef;

 

 

 

static const UartDescTypedef uartDesc[UART_CH_MAX]={

        {0x400E0800,100000000,7,XDMA_UART0_TX,XDMA_UART0_RX},

        {0x400E0A00,100000000,8,XDMA_UART1_TX,XDMA_UART1_RX},

        {0x400E1A00,100000000,44,XDMA_UART2_TX,XDMA_UART2_RX},

        {0x400E1C00,100000000,45,XDMA_UART3_TX,XDMA_UART3_RX},

        {0x400E1E00,100000000,46,XDMA_UART4_TX,XDMA_UART4_RX},

};

13:结构体内用define

typedef struct  {

#define UART_WE   0

#define UART_RD 1

   unsigned charflags;    //

   unsigned char* buf;

   unsigned int len;      //transfer length

   void (*complete_handler)(constvoid*);

}UART_MsgTy;

 14:异或

异或1:取反
异或0:不变

15:while(i--)

int main(void)
{
    int i=10;
    while(i--)
    {
        /*由此可知,while(i--)是先判断i条件,在i--,然后进入循环体*/
        printf("i = %d\t", i);
       
    }
 return 0;
}
//运行结果i = 9 i = 8 i = 7 i = 6 i = 5 i = 4 i = 3 i = 2 i = 1 i = 0 

  15:字符串和数组

#include <stdio.h>
int main(void) { 
         char str1[]="1234567";   //存在栈里
         char *str2="123456";      //str2存在栈里,"123456"存在常量区,不可以修改

         char*str3="123456";       //str3存在栈里,str3指向的和str2是常量区里同一块内存     str1[0] = '0';
         //str2[0] = '0';
         printf("%s\n",str1);
         printf("%s\n",str2);
        
         return 0;
}


 

 

 

 

 

 

 

 

 

 

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值