C杂项_190117
2019-02-19 本文已影响0人
ppzbreeze
分层
要具有一定的分层意识!!!函数用起来千万不要瞎调用,而且不同的硬件之间的连接关系一定要明确
memcpy处理int类型
拷贝普通的char类型是没问题的,但是int型就需要仔细考虑一下了,一个占4位而不是1位;
scanf使用
需要加取地址符!!!
轻度算法问题
遇到算法问题,一定要思路清晰,先分解问题,单独构造需要的每一个函数,最后再统一调度
宏定义加U
#define mark01 1u
上述的1u即表示无符号的1,u为unsigned的意思,这种语法应该是用于宏定义和运算中居多,定义赋值时通常不用
struct和typedef
struct STUA{
int st1;
} STA;
//STUA为结构体类型名--星体,STA为具体结构体名--地球
typedef struct STUB{
int st2;
} STB;
void main()
{
struct STUA sup1;
struct STUB sup2;
STA supa1;//会报错,此种方法不可用
STB supb2;//可正常使用
STA.st1 = 1;//可正常使用
STB.st2 = 2;//会报错
//res = get_area(0,0,1,1,-1,-1,3,3);
printf("%d %d\n ",STA.st1,sup1.st1);
}
typedef的struct在用的时候会有一定的省略,用法也稍有不同
加了typedef的struct STB具有了类似结构体类型名称的属性,可以直接用STB supb2的方法来定义,但是不具有了具体结构体名的属性,不能够使用STB.st2直接赋值
ifdef三连
#ifndef TRUE
#define TRUE 1
#endif
函数用作参数
初步总结
1.只要用函数作指针,或要使用函数作参数,均需要定义一个指针函数,返回值类型和参数要和实体函数完全相同,用来在具体使用中(实际主函数调用或结构体定义)替代实体函数,通常描述为typedef void (*pfunc)(int a,XXX)
实例如下图
.h
typedef void (*rec_u)(uint8_t *msg, uint16_t len);//描述函数参数类型
.c
static void UDP_Receive(uint8_t *msg, uint16_t len)//函数实体
{
XXXXX
}
uint32_t CreateSocket(const char *ip, uint16_t port,rec_u readcb)//调用函数中的函数参数类型描述
{
XXXXX
}
void main()
{
ret = CreateSocket("3.0.4.3", 83, UDP_Receive);//主函数调用
}
!!!如果直接用函数UDP_Receive()做参数如下图
CreateSocket("3.0.4.3", 83, UDP_Receive())
则是用返回值做参数哦,含义大不一样
函数用作结构体内容的应用描述
.h文件
描述结构体,定义函数一律用指针类型
typedef void (*rec_r)(T_Mode mode, uint32_t msgId, TUri uri, uint8_t *msg);//指针
typedef void (*rec_u)(uint8_t *msg, uint16_t len);
typedef struct st1
{
uint8_t used;
uint8_t socketId;
uint8_t refId;
uint32_t lifetime;
char udp_ip[16];
uint16_t udp_port;
StRes res[SIZE];
uint8_t res_cnt;
rec1 res_cb;
rec2 udp_cb;
} StNBIoTInstance;
.c文件
实际函数的参数要保证和结构体中的函数体一致,在映射的时候不用带参数(直接用函数名称赋值)
void func1(T_Mode mode, uint32_t msgId, TUri uri, uint8_t *msg)//定义两种函数作参数形式
{
XXXX
}
void func2(uint8_t *msg, uint16_t len)
{
XXXX
}
void main()//主函数调用
{
st1 st;
st.res_r = func1;
st.res_u = func2;
}