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(¶[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; }