• C语言笔记


    •  当函数前面加上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

  • 相关阅读:
    06-局部变量和全局变量
    05-python中函数的使用
    04-字典的常见操作
    04-python第四天学习
    Openstack认证过程
    03-字典的增删改查
    01-名字管理系统.py
    02-python中列表的增删改查
    01-python中字符串的常见操作
    ubuntu16.04卸载软件
  • 原文地址:https://www.cnblogs.com/lifexy/p/7183495.html
Copyright © 2020-2023  润新知