C语言小程序

13、__FILE__,__func__,__LINE__

printf("%s,%s,%d\n",__FILE__,__func__,__LINE__);

12、二级指针的应用 1)改变指针的值

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i = 9;
    int* p = &i;

    *p = 0xb;
    //用指针改变一个变量的值
    printf("i=0x%x\n",i);
    printf("p=0x%x\n",p);

    int** q = &p;

    **q = 0xc;

    //用二级指针改变一个变量的值
    printf("i=0x%x\n",i);
    printf("p=0x%x\n",p);

    *q = (int *)0xFFFFFFFF;
    //用二级指针改变一个指针的值
    printf("i=0x%x\n",i);
    printf("p=0x%x\n",p);

    return 0;
}

2)用函数来改变指针的值

# include <stdio.h>
void f(int ** q);
int main(void)
{
    int i = 9;
    int * p = &i;
    printf("p=0x%x\n", p);
    f(&p);
    printf("p=0x%x\n", p);

    return 0;
}
void f(int ** q)
{
    *q = (int *)0xFFFFFFFF;
}

11、CRC

#include "stdio.h"
#include "stdint.h"

uint16_t CRC_calc(uint8_t *start, uint8_t *end)
{
  uint16_t crc = 0x0;
  uint8_t  *data;

  for (data = start; data < end; data++)
  {
    crc  = (crc >> 8) | (crc << 8);
    crc ^= *data;
    crc ^= (crc & 0xff) >> 4;
    crc ^= crc << 12;
    crc ^= (crc & 0xff) << 5;
  }
  return crc;
}

//计算CRC的地址从start--->end+1
int main(void)
{
   uint8_t a[7]={0x00,0x06,0x00,0x00,0x00,0xa0,0x00};
   uint8_t c[7]={0x2b,0x06,0x00,0x00,0x00,0xa0,0x00};

   uint16_t b=CRC_calc(&a[0],&a[6]);
   //uint16_t b=CRC_calc(&c[0],&c[6]);

    printf("b=0x%x\r\n",b);

}

10、清除数组为0的项

#include <stdio.h>
#include <stdint.h>

uint8_t a[10]={1,2,3,4,5,6,7,8,9,0};

static uint8_t delete_zero_item(uint8_t data[] , uint8_t n)
{
    uint8_t i = 0, j, len = n;
    while (i < len){
        if( (data[i] == 0) ){
            for (j = i; j < len; j++){
                data[j] = data[j + 1];
            }
            len--;
        }
        else
            i++;
    }

    return len;
}

int main(void)
{
    uint8_t k=delete_zero_item(a,10);

    printf("%d\n",k);

    for(int i=0;i<k;i++) printf("%d",a[i]);

}

9、简易abs函数功能实现(求无符号整形表达式的绝对值) 无符号整形数据的差值,不能用if来判断,加一个常数截在一个区间。

#include "stdio.h"
#include "stdint.h"

#define ABS(x) (x>0?x:-(x))

int main()
{
    uint32_t utc_time_tmp = 11;
    uint32_t utc_time_r = 5;

   if(utc_time_tmp - utc_time_r + 5 > 10)
   //也是够了
  //if(ABS(utc_time_tmp - utc_time_r)>5)
  //也是够了
   //if(((utc_time_tmp > utc_time_r) && (utc_time_tmp - utc_time_r > 5))||
   //    ((utc_time_tmp < utc_time_r) && (utc_time_r - utc_time_tmp > 5))
   //)
        printf("in\r\n");
    else printf("out\r\n");

    return 0;
}

8、在字符串中截取字符/字符串(GPS NMEA协议解析)

#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include <stdio.h>

int main(){
    char* str = "123,456,789,0123456,123456,0,09,10";
    char sub[3];
    int count = 0, index = 0;
    for (index = 0; index < strlen(str); ++index){
        if (str[index] == ',')
            ++count;
        if (count == 6)
            break;
    }
    strncpy(sub, &str[index+1], 2);

    sub[2] = '\0';
    printf(sub); //123,456,789

    int n = atoi(sub);
    printf("string = %s integer = %d\n", sub, n);

}

7、sqrt的实现

#include <stdio.h>
#ifdef CONFIG_64BIT
#define BITS_PER_LONG 64
#else
#define BITS_PER_LONG 32
#endif
/**
 * int_sqrt - rough approximation to sqrt
 * @x: integer of which to calculate the sqrt
 *
 * A very rough approximation to the sqrt() function.
 */
unsigned long int_sqrt(unsigned long x)
{
    unsigned long op, res, one;
    op = x;
    res = 0;
    one = 1UL << (BITS_PER_LONG - 2);
    while (one > op)
        one >>= 2;

    while (one != 0) {
        if (op >= res + one) {
            op = op - (res + one);
            res = res +  2 * one;
        }
        res /= 2;
        one /= 4;
    }
    return res;
}

int main(void)
{
    printf("%d\n",int_sqrt(16))    ;
    return 0 ;
}

6、数据转换(hex - char - byte array - acsii)

网上的整理过来的,来源记不清了,感谢作者。

DataConvert.c

#include <stdio.h>
#include <string.h>
#include "DataConvert.h"

int strToHex(char *ch, char *hex)
{
  int high,low;
  int tmp = 0;
  if(ch == NULL || hex == NULL){
    return -1;
  }

  if(strlen(ch) == 0){
    return -2;
  }

  while(*ch){
    tmp = (int)*ch;
    high = tmp >> 4;
    low = tmp & 15;
    *hex++ = valueToHexCh(high); //先写高字节
    *hex++ = valueToHexCh(low); //其次写低字节
    ch++;
  }
  *hex = '\0';
  return 0;
}

int hexToStr(char *hex, char *ch)
{
  int high,low;
  int tmp = 0;
  if(hex == NULL || ch == NULL){
    return -1;
  }

  if(strlen(hex) %2 == 1){
    return -2;
  }

  while(*hex){
    high = hexCharToValue(*hex);
    if(high < 0){
      *ch = '\0';
      return -3;
    }
    hex++; //指针移动到下一个字符上
    low = hexCharToValue(*hex);
    if(low < 0){
      *ch = '\0';
      return -3;
    }
    tmp = (high << 4) + low;
    *ch++ = (char)tmp;
    hex++;
  }
  *ch = '\0';
  return 0;
}

int hexCharToValue(const char ch){
  int result = 0;
  //获取16进制的高字节位数据
  if(ch >= '0' && ch <= '9'){
    result = (int)(ch - '0');
  }
  else if(ch >= 'a' && ch <= 'z'){
    result = (int)(ch - 'a') + 10;
  }
  else if(ch >= 'A' && ch <= 'Z'){
    result = (int)(ch - 'A') + 10;
  }
  else{
    result = -1;
  }
  return result;
}

char valueToHexCh(const int value)
{
  char result = '\0';
  if(value >= 0 && value <= 9){
    result = (char)(value + 48); //48为ascii编码的‘0’字符编码值
  }
  else if(value >= 10 && value <= 15){
    result = (char)(value - 10 + 65); //减去10则找出其在16进制的偏移量,65为ascii的'A'的字符编码值
  }
  else{
    ;
  }

  return result;
}

int hexChartoByte(char *s,char *byte)
{
    int i,n = 0;
    for(i = 0; s[i]; i += 2)
    {
        if(s[i] >= 'A' && s[i] <= 'F')
            byte[n] = s[i] - 'A' + 10;
        else byte[n] = s[i] - '0';
        if(s[i + 1] >= 'A' && s[i + 1] <= 'F')
            byte[n] = (byte[n] << 4) | (s[i + 1] - 'A' + 10);
        else byte[n] = (byte[n] << 4) | (s[i + 1] - '0');
        ++n;
    }
        return n;
}

unsigned char ChartoAscii(const unsigned char cha)
{
    unsigned char ascii;
    if ((cha >= 0x0A) && (cha <= 0x0F))
    {
        ascii = cha + 'A' - 10;
    }
    else
    {
        ascii = cha + '0'; 
    }
    return ascii;
}

DataConvert.h

#ifndef __DATA_H
#define __DATA_H

int strToHex(char *ch, char *hex);
int hexToStr(char *hex, char *ch);
int hexCharToValue(const char ch);
char valueToHexCh(const int value);
int hexChartoByte(char *s,char *byte);
unsigned char ChartoAscii(const unsigned char cha);
#endif

main.c

#include <stdio.h>
#include <string.h>
#include "DataConvert.h"

#define MCU_FIRWARE_VERSION "V1.0.0"
#define BLE_FIRWARE_VERSION "V1.0.0"
#define FONT_VERSION "V1.0.0"


int main(int argc, char *argv[])
{
    int i;
    char result[1024];
    char *p_result = result;

    //转换版本号数据
    char mcu_version_hex[12];
    char mcu_version_byte[6];
    char *p_ch = MCU_FIRWARE_VERSION;
    char *p_hex = mcu_version_hex;
    strToHex(p_ch,p_hex);
    int n = hexChartoByte(mcu_version_hex,mcu_version_byte);

    char ble_version_hex[12];
    char ble_version_byte[6];
    p_ch = BLE_FIRWARE_VERSION;
    p_hex = ble_version_hex;
    strToHex(p_ch,p_hex);
    int m = hexChartoByte(ble_version_hex,ble_version_byte);

    char font_version_hex[12];
    char font_version_byte[6];
    p_ch = FONT_VERSION;
    p_hex = font_version_hex;
    strToHex(p_ch,p_hex);
    int k = hexChartoByte(font_version_hex,font_version_byte);   


    //填充版本号数据
    for(int i = 0;i<n;i++)
        printf ("%X ",0XFF & mcu_version_byte[i]);

    for(int i = 0;i<m;i++)
        printf ("%X ",0XFF & ble_version_byte[i]);

    for(int i = 0;i<k;i++)
        printf ("%X ",0XFF & font_version_byte[i]);

    hexToStr(p_hex, p_result);
        printf("the string is:%s\n", p_result);
}

以上demo将字符串转换成utf8的字节流,可用utf8的转换工具(LoveString)还原成字符串验证。

5、union与数据的拆分与合并以及大小端的判断

1) 将int型的i拆分成4字节char型的c

 
#include<stdio.h>  
union var{ 
 char c[4]; 
 int i; 
}; 
 
int main(){ 
 union var data; 
 data.i = 0x11020304; 
 printf("%x\n",data.c[0]);
 printf("%x\n",data.c[1]);
 printf("%x\n",data.c[2]);
     printf("%x\n",data.c[3]);
     return 0; 
}

2) 合并就是反过来

#include<stdio.h>  
union var{  
        char c[4];  
        int i;  
};  
  
int main(){  
        union var data;  
        data.c[0] = 0x04;
        data.c[1] = 0x03;
        data.c[2] = 0x02;  
        data.c[3] = 0x11;  
        printf("%x\n",data.i); 
     return 0; }

3) 大小端的判断

#include<stdio.h>  
union var{  
        char c[4];  
        int i;  
};  
  
int main(){  
        union var data;  
        data.i = 0x11020304; 
        printf("%x\n",data.c[0]);
        printf("%x\n",data.c[1]);
        printf("%x\n",data.c[2]);
     printf("%x\n",data.c[3]);

        if( data.c[0] == 0x11 )
        {
          printf("Systerm is BigEndian");
        }
     return 0; 
}

4、连接符#的应用

1) 连接数值类型用双#

#include <stdio.h>

#define   COMB(a,b,c)   a##b##c
  
void main()
{    
       printf("%d\n",COMB(1,2,3));  
}

2) 连接字符类型用单#

#include <stdio.h>

#define   CATSTR(n)   "abcd"#n  

void main()  
{  
        printf("%s\n",CATSTR(100));  
}

3、 时间转换(localtime和mktime)

有些系统没有localtime和mketime, 把linux内核里边这两函数扣出来用。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include <stdint.h>

struct tm {
    /*
     * the number of seconds after the minute, normally in the range
     * 0 to 59, but can be up to 60 to allow for leap seconds
     */
    int tm_sec;
    /* the number of minutes after the hour, in the range 0 to 59*/
    int tm_min;
    /* the number of hours past midnight, in the range 0 to 23 */
    int tm_hour;
    /* the day of the month, in the range 1 to 31 */
    int tm_mday;
    /* the number of months since January, in the range 0 to 11 */
    int tm_mon;
    /* the number of years since 1900 */
    long tm_year;
    /* the number of days since Sunday, in the range 0 to 6 */
    int tm_wday;
    /* the number of days since January 1, in the range 0 to 365 */
    int tm_yday;

    int tm_isdst;
};

static unsigned long mktime(const unsigned int year0, const unsigned int mon0,
        const unsigned int day, const unsigned int hour,
        const unsigned int min, const unsigned int sec)
{
    unsigned int mon = mon0, year = year0;

    /* 1..12 -> 11,12,1..10 */
    if (0 >= (int) (mon -= 2)) {
        mon += 12;    /* Puts Feb last since it has leap day */
        year -= 1;
    }

    return ((((unsigned long)
          (year/4 - year/100 + year/400 + 367*mon/12 + day) +
          year*365 - 719499
        )*24 + hour /* now have hours */
      )*60 + min /* now have minutes */
    )*60 + sec; /* finally seconds */
}


static struct tm * localtime_r(time_t *srctime,struct tm *tm_time)
{
    long int n32_Pass4year,n32_hpery;
    const static char Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
    const static int ONE_YEAR_HOURS = 8760;

    time_t time = *srctime;
    time=time+28800;
    tm_time->tm_isdst=0;
    if(time < 0)
    {
    time = 0;
    }

    tm_time->tm_sec=(int)(time % 60);
    time /= 60;
    tm_time->tm_min=(int)(time % 60);
    time /= 60;
    tm_time->tm_wday=(time/24+4)%7;
    n32_Pass4year=((unsigned int)time / (1461L * 24L));
    tm_time->tm_year=(n32_Pass4year << 2)+70;
    time %= 1461L * 24L;
    tm_time->tm_yday=(time/24)%365;

    for (;;)
    {
        n32_hpery = ONE_YEAR_HOURS;
        if ((tm_time->tm_year & 3) == 0)
        {
            n32_hpery += 24;
        }

        if (time < n32_hpery)
        {
            break;
        }

        tm_time->tm_year++;
        time -= n32_hpery;
    }

    tm_time->tm_hour=(int)(time % 24);
    time /= 24;
    time++;

    if ((tm_time->tm_year & 3) == 0)
    {
        if (time > 60)
        {
            time--;
        }
        else
        {
            if (time == 60)
            {
                tm_time->tm_mon = 1;
                tm_time->tm_mday = 29;
                return tm_time;
            }
        }
    }

    for (tm_time->tm_mon = 0;Days[tm_time->tm_mon] < time;tm_time->tm_mon++)
    {
        time -= Days[tm_time->tm_mon];
    }

    tm_time->tm_mday = (int)(time);
    return tm_time;
}

int main(void)
{
    uint32_t now = 1451577600; /*2016/01/01 00:00:00*/
    struct tm tm = {0};
    char *wday[] = {"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};
    localtime_r(&now, &tm);
    printf("%d/%d/%d \n", 1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday);
    printf("%s %d:%d:%d \n", wday[tm.tm_wday], tm.tm_hour, tm.tm_min, tm.tm_sec);
    now = mktime(1900 + tm.tm_year, 1 + tm.tm_mon, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec);
    printf("rtc value : %d\n", now);
    return 0;
}

2、函数指针(数组)的应用以及参数传递

//预存的APP响应
void (*CmdCallbackArray[APP_CMD_MAX])(uint8_t *para) = {
    0 ,
    FirewareManageCallback , // FirewareManage = 1
    DataSyncCallback ,
    SetCmdCallback,
    HintCmdCallback,
    0,
    BindCallback,
    FactoryTestCallback,
    LogCtrlCallback

};

bool  App_Data_L1_DataParse( uint8_t *L1_Packet,uint8_t *L1_Payload){
  bool ret=true;

  uint8_t para[60] = {0};
  uint16_t L2_len = 0;
  uint16_t check_sum = 0;
  L2_len =((((uint16_t)L1_Packet[5])<<8)|((uint16_t)L1_Packet[6]));

  check_sum = CRC_calc(&L1_Packet[9] , &L1_Packet[9+L2_len]);

  if( ( (((uint16_t)L1_Packet[7])<<8)|((uint16_t)L1_Packet[8]) ) ==  check_sum )
  {
    //正常接收,进入L2_Command_Content

    para[0] = L1_Packet[2];
    memcpy(&para[1],&L1_Packet[10],L2_len-1);
    CmdCallbackArray[L1_Packet[9]](para);
  }
  return ret;
}

 1、结构体指针的嵌套

工作多年,C语言基础还是不扎实,惭愧!

eg.

a.简单实例

#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>

int main()
{
    uint8_t test[8]={1};

    struct b_t {
        uint8_t *data;
    };

    struct a_t {
        struct b_t *b;
    };

    struct a_t *a = (struct a_t*)malloc(sizeof(struct a_t));
    a->b = (struct b_t*)malloc(sizeof(struct b_t));
    a->b->data = malloc(8*sizeof(uint8_t));
    a->b->data = test;
    printf("%d\r\n",*(a->b->data));
    return 0;
}


b.一个具体的的应用,某beacon的蓝牙广播封包

#include<stdlib.h>
#include<stdio.h>
#include<stdint.h>

struct event_t {
    uint16_t id;
    uint8_t data_len;
    uint8_t *data;
};
struct manufacturer_data_t{
    uint8_t data_len;
    uint8_t *data;
};
struct manufacturer_title_data_t{
    uint8_t data_len;
    uint8_t *data;
};
struct x_beacon_t {
    uint8_t length;
    uint8_t bt_sig_type;
    uint16_t x_service_uuid;
    uint16_t frame_control;
    uint16_t product_id;
    uint32_t frame_counter;
    uint8_t mac_add;
    uint8_t capability;
    struct event_t *event;
    struct manufacturer_data_t *manufacturer_data;
    struct manufacturer_title_data_t *manufacturer_title_data;
}*x_beacon;

int main(void)
{
    uint8_t test[8]={1};

    x_beacon = (struct x_beacon_t *)malloc(sizeof(struct x_beacon_t));
    x_beacon->event = (struct event_t*)malloc(sizeof(struct event_t));
    x_beacon->event->data = (uint8_t*)malloc(8*sizeof(uint8_t));
    x_beacon->event->data = test;
    x_beacon->manufacturer_data = (struct manufacturer_data_t*)malloc(sizeof(struct manufacturer_data_t));

    x_beacon->manufacturer_title_data = (struct manufacturer_title_data_t*)malloc(sizeof(struct manufacturer_title_data_t));

    x_beacon->length = 0x09;
    x_beacon->bt_sig_type = 0x16;
    x_beacon->x_service_uuid = 0xfe95;
    x_beacon->frame_control = 0x1021;
    x_beacon->product_id = 0x0157;
    x_beacon->frame_counter = 0x00;
    x_beacon->capability = 0x09;

    printf("%0x\r\n",x_beacon->x_service_uuid);
    printf("%0d\r\n",*(x_beacon->event->data));

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

春哥一号

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值