C语言总结

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 ## Back
	Paste(Name,1);将会建立记号Name1

4、关于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    程序PC

10、中断函数没有参数没有返回值

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、返回值是函数指针的函数
typedef	int (*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_
......
......		//头文件内容写在这里
......
#endif

18、#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 configuration

19、如果编译器是C++编译器,告诉编译器中间是C代码,使用C代码的编译方法编译。
#ifdef __cplusplus 
extern "C" {
#endif
......
...... C 代码
......			
#ifdef __cplusplus 
}
#endif

20、sizeof是个关键字不是个函数,要注意。

21、在Keil4、LPC2129、不使用分散加载文件的环境下。RAM的分配是这样的
LPC2129的RAM地址是0x40000000,大小是0x4000
从0x40000000开始依次存放的是:
已经初始化的全局变量,其后是没有初始化的全局变量(BBS区),然后是堆区,然后是栈区,最后是没有使用的RAM。

+------------------+-----> 0x40000000		RAM开始
|  初始化的全局变量   |	   DATA区
+------------------+-----> 0x40000184
|  未始化的全局变量   | 	   BBS区
+------------------+-----> 0x40000d18 		
|        堆          |	   这里堆区空间是0
+------------------+-----> 0x40000d18 		栈底
|        栈          |	   栈区                     
+------------------+-----> 0x400011a0		栈顶
|     空闲RAM       |
+------------------+-----> 0x40004000		RAM结束

一般不使用标准库的内存分配函数的话,堆区可以设置为0,也就是不使用堆。
要注意的是:局部变量存放在栈区,如果局部变量过多超过了栈的大小。因为栈是满递减的会把堆区,甚至全局变量覆盖,导致程序崩溃。
编写程序时一定要注意。


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值