- 当函数前面加上static时,表示该函数仅在本文件里被调用,不会与其它文件相同函数发生冲突
- 调用库的头文件使用<>,调用自己创建的头文件使用""
memset
memset对于强制转换类型不同的指针,赋值是有误的
例如:
#include "stdio.h" #include "string.h" int main() { unsigned char s[4]={0x12,0x34,0x56,0x12}; unsigned short *p16=(unsigned short *)s; memset(p16,0x1234,2); for(int i=0;i<2;i++) printf("0x%x ",*p16++); return 0; }
输出结果:
因为s[4]转为16位后,数据为:0x3412 0x1256,而执行 memset(p16,0x1234,2)代码时,
由于*p16的内容实际是8位的,所以只能放入0x34低8位,放入0x12高8位时便出错返回了.
所以*p16打印的结果为: 0x3434 0x1256
改为以下代码,不使用memset便可以实现:
#include "stdio.h" #include "string.h" int main() { unsigned char s[4]={0x12,0x34,0x56,0x12}; unsigned short *p16=(unsigned short *)s; for(int i=0;i<2;i++) p16[i]=0x1234; for(int i=0;i<2;i++) printf("0x%x ",*p16++); return 0; }
struct
struct internal{ int i; int j; }inter; //定义一个 struct internal inter变量
typedef
typedef struct LNode LNode; //通过LNode别名代替struct LNode typedef struct LNode *LinkList; //表示LinkList指向struct LNode,
//比如LinkList p ; 等价于: struct LNode *p;
对于指针typedef而言, 其实和指针结构体很像
例如:
#include "stdio.h" typedef struct internal{ int i; int j; }Inter, *Pint; //Inter类型等价于struct internal , Point 等价于 struct internal* int main() { inter buff[100]={ {1,2},{2,3},{3,4} }; Pint p=buff; //等价于 struct internal *p=buff; for(int i=0;i<3;i++) { p->i++; p->j++; p++; } for(int i=0;i<3;i++) printf("%d %d ",buff[i].i,buff[i].j); printf("%d ",p-buff); }
输出结果:
#define
我们平时编译代码时,首先会进入预处理器,预处理器会去检查代码规范,以及将define宏替代为文本.
所以define也可以这样使用:
#include <stdio.h> #define SWAP(t, a, b) do { t c = a; a = b; b = c; }while(0) int main( ) { int a=0,b=1; SWAP(int,a,b); printf("%d,%d ",a,b); return 0; }
运行打印:
1,0
在我们测试产品时,需要串口打印,产品成功后,又要取消串口打印,不妨通过define宏来处理,例如:
#if defined(DEBUG_U3) #define debug u3_printf #elif defined(DEBUG_U2) #define debug u2_printf #elif defined(DEBUG_U1) #define debug u1_printf #else #define debug(...) //表示预处理器遇到debug(...)时,会省略掉该语句,从而不打印输出
当判断一个宏是否存在时,尽量使用:
#if defined(CONFIG_XXX) //... ... #endif
不要使用 #ifdef CONFIG_XXX
当判断宏等于多少时:
#if ( CONFIG_LCD_HIDE_OFF == 1 )//SIZE_FONT_32X32 u8 MaxFont = SIZE_FONT_100X100; #else u8 MaxFont = SIZE_FONT_32X32; #endif
最小二乘法拟合曲线公式
利用最小二乘法将一系列的XY坐标数据拟合为二次曲线
用EXCEL显示出的拟合曲线公式,和通过公式计算出来的公式对比:
代码如下:
#define N 1e-13
/*************************************************************************** * count: 表示XY坐标点数 * * a b c: y=ax*x+bx+c; * *******************************************************************************/ void analyzeCurve(double *x,double *y,double *a,double*b,double *c,int count) { double m1,m2,m3,z1,z2,z3; double sumx=0,sumx2=0,sumx3=0,sumx4=0,sumy=0,sumxy=0,sumx2y=0; int i; *a=*b=*c=0; z1=z2=z3=999; for(i=0;i<count;i++) { sumx+=x[i];sumy+=y[i]; sumx2+=pow (x[i],2); sumxy+=x[i]*y[i]; sumx3+=pow(x[i],3); sumx2y+=pow(x[i],2)*y[i]; sumx4+=pow(x[i],4); } while((z1>N)||(z2>N)||(z3>N)) { m1=*a; *a=(sumx2y-sumx3*(*b)-sumx2*(*c))/sumx4; z1=(*a-m1)*(*a-m1); m2=*b; *b=(sumxy-sumx*(*c)-sumx3*(*a))/sumx2; z2=(*b-m2)*(*b-m2); m3=*c; *c=(sumy-sumx2*(*a)-sumx*(*b))/count; z3=(*c-m3)*(*c-m3); } printf (" y=%9.6fx*x+%9.6fx+%9.6f",*a,*b,*c); } int main() { double x[21]={0.00,20,40,60,80}; double y[21]={0.00,23,60,77.69,79.64}; double a,b,c ; analyzeCurve(x,y,&a,&b,&c,5); return 0; }
指针
在指针中*是取内容,&是取地址
(在结构体中时:变量结构体用".",指针结构体用"->",比如p指针: p->val <---> (*p).val )
通常有两种的表示:
1. 通过指针向指向的地址内容赋值
*p=a; //将p指向的地址里赋a值
注意:若a和p定义的变量类型不一样时,需要用到强制转换才行.
当指针指向的地址内容是一个变量时,
实例如下:
int main() { int *p=0x12345678; //定义一个int型指针*p,p=0x12345678这个地址。 char a='0'; //定义一个char型变量b *p=(int)a; //*p等于a(0x12345678这个地址的内容等于a变量的值) }
当指针指向的地址内容是另一个指针指向的地址内容时,
实例如下:
int main() { int *p=0x12345678; //定义一个int型指针*p,p=0x12345678这个地址。 char b='0'; //定义一个char型变量b char *a=&b; //定义一个char型指针*a,a=&b,表示a指针的地址等于b的地址。 *p=*(int *)a; //首先是先执行(int *)强制转换为int型指针,然后*p等于*a(0x12345678地址的内容等于'0'这个变量) }
2. 指针指向其它的地址
p=&a; //将p的地址 指向a的地址
它和"int a=0,*p=&a;"一个意思,这里的*只是代表定义一个指针(不是指向地址的内容),然后指针p=&a;
实例如下:
int main() { int a=0,*p; //定义一个int型指针p,p等于0x12345678这个地址。 p=&a; //p等于a的地址,则*p=0 }
3.指针地址与数值相加
指针地址与数值相加和数值与数值相加不一样,
char型指针:0X3000+1=0X3001 (因为1个地址保存8位数据,而char是8位.)
short型指针:0X3000+1=0X3002 (16位)
int、long型指针:0X3000+1=0X3004 (32位)
long long型指针:0X3000+1=0X3008 (64位)
变量与变量相加,实例如下:
#include "stdio.h" #define tag_next(t) ((int *)((unsigned long)(t) + 1)) int main() { int i=3,*t=&i; printf(" %x,%d ", t,*t); t=tag_next(t); //t= *(t+1) printf(" %x,%d ", t,*t); }
这里的tag_next(t): 将t地址强制转换为u32变量,与另一个变量1相加
代码输出如下:
也就是t=0X28ff18+1=0x28ff19
int型指针地址与变量相加,实例如下:
#include "stdio.h" #define tag_next(t) ((int *)((unsigned int*)(t) + 1)) int main() { int i=3,*t=&i; printf(" %x,%d ", t,*t); t=tag_next(t); //t=*((unsigned long *)t +1) printf(" %x,%d ", t,*t); }
这里的tag_next(t): 将t地址强制转换为u32*指针,然后这个指针地址与另一个变量1相加
代码输出如下:
也就是t=0X28ff18+1=0x28ff18+4=0x28ff1c