C语言总结

来源:互联网 发布:java instance单例 编辑:程序博客网 时间:2024/05/22 15:37
1、把小写字母转化成大写字母int Lower(int c){if(c >= 'A' && c <= 'Z'){return c + 'a' - 'A';}else{return c;}}2、Max宏#define Max(A,B) ((A) > (B) ? (A) : (B))3、关于##define Dprintf(Expr) printf(#Expr " = %d\n",Expr)Dprintf(x/y);展开后printf("x/y = %d\n",x/y);#define Paste(Front,Back) Front ## BackPaste(Name,1);将会建立记号Name14、关于void指针任何类型的指针都可以转换成void指针,并且在奖它转换回原来的类型不会丢失信息。5、关于int *Fun()和int (*Fun)()两个声明int *Fun()是一个函数,返回一个int指针。int (*Fun)()是一个函数指针返回一个int类型。6、关于局部变量和结构体成员的顺序32位CPU要学会享受,定义成32位变量比定义为8位运算速度快。如下定义在keil4下浪费RAM,结构体中也是这样,貌似结构体有个关键字,不同的编译器不同名称Keil4下叫 __packed 使用此关键字,结构体以压缩的方式存放成员,不存在RAM浪费,但是耗费了时间。void MyFun(void){gUINT32 Temp1;/*这样定义浪费内存*/gUINT8 Temp2;/*浪费三个字节*/gUINT32 Temp3;gUINT8 Temp4;/*浪费三个字节*/gUINT32 Temp5;gUINT8 Temp6;/*浪费三个字节*//*..........................*/}应当这样定义void MyFun(void){gUINT32 Temp1;gUINT32 Temp3;gUINT32 Temp5;gUINT8 Temp4;gUINT8 Temp2;gUINT8 Temp6;/*浪费了一个字节*//*..........................*/}7、RO、RW、ZI含义RO:存放只读代码和常量RW:存放已经初始化的变量ZI:存放没有初始化的变量8、函数参数传递、函数返回值、局部变量 (详见ATPCS文档)在ARM中参数传递:使用R0-R3,多于4个使用栈传递。R0第一个参数返回值:  使用R0-R3,一个字使用R0,两字R0-R1、三个字R0-R2、四个字R0-r3局部变量:使用R4-R11(ARM)、R4-R7(Thumb),过多的使用栈保存中断函数中只使用R0-R3,不使用R4-R11,进入中断程序前一定要保存R0-R3等寄存器(凭自己的推断,貌似在哪里见过不太确定)Cortex-M3内核进入异常服务例程时,自动压栈了R0-R3,R12,LR(R14,连接寄存器),;PSR(程序状态寄存器)和PC(R15).并且在返回时自动弹出。不用加__irq关键字这也是推断的理由之一看到周立功的ARM7 ucos例程也没有保存R4-R11,理由二9、实时操作系统任务切换的时候为什么要保存R0-R15 (ARM)R0-R3  保存的当前任务的参数,切换到其他任务可能别修改,当任务切换回来现场以经改变。故必须保存R4-R11 保存了当前任务中的局部变量,可能被其他任务更改。也必须保存R12    过程调用中间临时寄存器R13    栈指针R14    连接寄存器保存子函数返回的地址R15    程序PC10、中断函数没有参数没有返回值11、函数指针这样定义uint8_t (* pfnRcvIntHandlerCan1) (CpCanMsg_ts *, _U08);函数参数只写类型。注意函数指针的括号12、typedef void (*TmrHandler_fn)(void);  //声明main(){TmrHandler_fn  fnTmrCall;//定义......}这两句就是定义了一个函数指针: void (*fnTmrCall)(void); //无参数,无返回值这样做可以使函数指针的定义简单化,类似定义变量,看起来直观13、struct McTmrFunc_s   //声明结构体{   uint32_t       ulControl;   uint32_t       ulTickCurrent;   uint32_t       ulTickPeriod;   TmrHandler_fn  fnTmrCall;};typedef struct McTmrFunc_s McTmrFunc_ts;//起别名static McTmrFunc_ts atsTmrFuncS[MC_TMR_FUNCTION];//定义结构体一下方法可以实现相同功能,并且更简洁。typedef struct McTmrFunc_s   //声明结构体,并起别名{   uint32_t       ulControl;   uint32_t       ulTickCurrent;   uint32_t       ulTickPeriod;   TmrHandler_fn  fnTmrCall;}McTmrFunc_ts;static McTmrFunc_ts atsTmrFuncS[MC_TMR_FUNCTION];//定义结构体14、返回值是函数指针的函数typedefint (*pFunc)(int *,int);pFunc Function(int Par)定义了一个函数,这个函数的返回值是个函数指针,这个函数指针指向有两个参数且返回值是int型的函数。{......}15、函数调用另一个函数为了现场保护会导致入栈、出栈、跳转等操作,导致效率降低,某些比较简单的函数,改用宏实现可以提高效率。当然使用宏的方法将会产生较大程序代码,要注意。如:两个数比较大小(这是比较简单的例子,还有更复杂的宏函数)#define MAX(a,b) ((a)>(b)?) (a) : (b)#define MIN(a,b) ((a)<(b)?) (a) : (b)16、const关键字const char *Ptr; //指针指向的内容不能改变 ,即。指向的对象只读。Ptr可以改变char const *Ptr;   //同上char *const Ptr;  //Ptr只读,不能改变指向。17、头文件的书写加上下面的宏,会避免重复定义等现象出现。#ifndef  _CP_MSG_H_#define  _CP_MSG_H_............//头文件内容写在这里......#endif18、#error关键字,移植方便。注:DNS_MSG_COS 和 DNS_CLASS_2B都是宏#if  (DNS_MSG_COS == 0) && (DNS_CLASS_2B == 1)#error Please disable class 2B for this configuration#endif编译时如果条件成立,编译器就会输出error信息Please disable class 2B for this configuration19、如果编译器是C++编译器,告诉编译器中间是C代码,使用C代码的编译方法编译。#ifdef __cplusplus extern "C" {#endif............ C 代码......#ifdef __cplusplus }#endif20、sizeof是个关键字不是个函数,要注意。21、在Keil4、LPC2129、不使用分散加载文件的环境下。RAM的分配是这样的LPC2129的RAM地址是0x40000000,大小是0x4000从0x40000000开始依次存放的是:已经初始化的全局变量,其后是没有初始化的全局变量(BBS区),然后是堆区,然后是栈区,最后是没有使用的RAM。+------------------+-----> 0x40000000RAM开始|  初始化的全局变量   |   DATA区+------------------+-----> 0x40000184|  未始化的全局变量   |    BBS区+------------------+-----> 0x40000d18 |        堆          |   这里堆区空间是0+------------------+-----> 0x40000d18 栈底|        栈          |   栈区                     +------------------+-----> 0x400011a0栈顶|     空闲RAM       |+------------------+-----> 0x40004000RAM结束一般不使用标准库的内存分配函数的话,堆区可以设置为0,也就是不使用堆。要注意的是:局部变量存放在栈区,如果局部变量过多超过了栈的大小。因为栈是满递减的会把堆区,甚至全局变量覆盖,导致程序崩溃。编写程序时一定要注意。