C

39. fread file

  while( ((i=fread(buffer,1,160,infile))>0) && (runcond) )
    {
        rtp_session_send_with_ts(session,buffer,i,user_ts);
        user_ts+=160;
    }

    while(!feof(ts_file)){  
        int read_len = fread(buf+count, 1, TS_PACKET_SIZE, ts_file);   
        count += read_len;   
    }

 

38. Handle a signal

https://rosettacode.org/wiki/Handle_a_signal

 

37. 将socket设置为非阻塞(non-blocking)

正确的做法应该是使用fcntl:
int flags = fcntl(m_sock, F_GETFL, 0);
fcntl(m_sock, F_SETFL, flags|O_NONBLOCK);

https://www.cnblogs.com/zhangxuan/p/6306326.html

https://blog.csdn.net/qq_24373811/article/details/52356064

 

36. log

https://github.com/waynetran/log.c

https://github.com/pymumu/tinylog

 

35、c语言 判断ip是否合法的简单例子

https://blog.csdn.net/liupengying123/article/details/38514425

34、c 语言配置文件导入

1、inih-r43

2、https://blog.csdn.net/wang_xya/article/details/33733257

 

33、指针里的*符号是要靠近变量类型还是要靠近变量名称?

https://blog.csdn.net/zhanshen112/article/details/80722762

 

32、log

#ifdef NDEBUG
#define LOG(fmt, ...)   ((void)0)
#define LOGI(fmt, ...)  ((void)0)
#define LOGD(fmt, ...)  ((void)0)
#define LOGE(fmt, ...)  ((void)0)
#else
#define LOG(fmt, ...)   do{ printf(fmt "\n", ##__VA_ARGS__); } while(0)
#define LOGI(fmt, ...)  do{ printf("%s: " fmt "\n", __FILENAME__, ##__VA_ARGS__); } while(0)
#define LOGD(fmt, ...)  do{ printf("\033[33m%s: " fmt "\033[m\n", __FILENAME__, ##__VA_ARGS__); } while(0)
#define LOGE(fmt, ...)  do{ printf("\033[31mERROR: %s: %s: %d: " fmt "\033[m\n", __FILENAME__, __func__, __LINE__, ##__VA_ARGS__); } while(0)
#endif

 

#include <stdio.h>
#include <time.h>

const char* uatime()
{
    struct timeval tv;
    static char buf[23];
    
    memset(buf, 0, sizeof(buf));
    
    // clock time
    if (gettimeofday(&tv, NULL) == -1) {
        return buf;
    }
    
    // to calendar time
    struct tm* tm;
    if ((tm = localtime((const time_t*)&tv.tv_sec)) == NULL) {
        return buf;
    }
    
    snprintf(buf, sizeof(buf), 
        "%d-%02d-%02d %02d:%02d:%02d.%03d", 
        1900 + tm->tm_year, 1 + tm->tm_mon, tm->tm_mday, 
        tm->tm_hour, tm->tm_min, tm->tm_sec, 
        (int)(tv.tv_usec / 1000));
        
    buf[sizeof(buf) - 1] = 0;
    
    return buf;
}

#ifdef UA_DISABLE_LOG
    #define ualog1(msg, ...) (void)0
#else
    #define ualog1(msg, ...) printf("[%s] ", uatime());printf(msg, ##__VA_ARGS__);printf("\n")
#endif

#define ualog(a,b...) fprintf(stderr,b);fprintf(stderr,"\n>")
#define uaslog(a,b...) printf("[%s]", uatime());fprintf(stderr,b);fprintf(stderr,"\n>")

 

31、C++ int与string的相互转换(含源码实现)

30、回调函数

/**
 * Sound stream operations.
 */
typedef struct pjmedia_aud_stream_op
{
    /**
     * See #pjmedia_aud_stream_get_param()
     */
    pj_status_t (*get_param)(pjmedia_aud_stream *strm,
                 pjmedia_aud_param *param);

    /**
     * See #pjmedia_aud_stream_get_cap()
     */
    pj_status_t (*get_cap)(pjmedia_aud_stream *strm,
               pjmedia_aud_dev_cap cap,
               void *value);

    /**
     * See #pjmedia_aud_stream_set_cap()
     */
    pj_status_t (*set_cap)(pjmedia_aud_stream *strm,
               pjmedia_aud_dev_cap cap,
               const void *value);

    /**
     * See #pjmedia_aud_stream_start()
     */
    pj_status_t (*start)(pjmedia_aud_stream *strm);

    /**
     * See #pjmedia_aud_stream_stop().
     */
    pj_status_t (*stop)(pjmedia_aud_stream *strm);

    /**
     * See #pjmedia_aud_stream_destroy().
     */
    pj_status_t (*destroy)(pjmedia_aud_stream *strm);

} pjmedia_aud_stream_op;

 

static pjmedia_aud_stream_op alsa_stream_op =
{
    &alsa_stream_get_param,
    &alsa_stream_get_cap,
    &alsa_stream_set_cap,
    &alsa_stream_start,
    &alsa_stream_stop,
    &alsa_stream_destroy
};

 

回调函数_结构体

https://blog.csdn.net/u010333084/article/details/51339469

回调函数_注册

https://blog.csdn.net/u010333084/article/details/51406405

回调函数_数组

https://blog.csdn.net/u010333084/article/details/51381352

 

29、c语言查找/创建进程

#include<unistd.h> 
#include<sys/types.h> 
#include<sys/wait.h> 
#include<stdio.h> 
#include<stdlib.h> 
#include<fcntl.h> 
#include<limits.h> 
 
#define BUFSZ PIPE_BUF 
 
int main(void) 
{ 
    FILE* fp; 
    int count; 
    char buf[BUFSZ]; 
    char command[150]; 
    char *name = "pjsua-arm-unknown-linux-gnueabihf";

    sprintf(command, "ps -C %s|wc -l", name ); 
     
    if((fp = popen(command,"r")) == NULL) 
        perror("popen"); 
     
    if( (fgets(buf,BUFSZ,fp))!= NULL ) 
    {
        count = atoi(buf); 
        if((count - 1) == 0) 
            printf("%s not found\n",name); 
        else
            printf("process : %s total is %d\n",name,(count - 1)); 
    } 
    pclose(fp);
    
    return 0; 
}

gcc -Wall -pipe -O3 -o getpid getpid.c

 

hello.c

#include<stdio.h> 

int main()
{
    printf("hello,world");
    while(1);
}

gcc  -o hello hello.c

 

28、向文件dump信息

main.c

char *path = "/data/test.txt";

remove(path);

dump_to_file(path,"hello,world");

 

dump.c

int dump_bin(const char * file, char *buf, int len)
{
    FILE *fp = fopen(file, "a+b");
    if(fp)
    {
     fwrite(buf, len, 1, fp);
     fclose(fp);
     fp = NULL;
     return -1;
    }
    return 0;
}

int dump_str(const char * file, char *buf, int len)
{
    FILE *fp = fopen(file, "a+b");
    if(fp)
    {
     fprintf(fp,"%s",buf);
     fclose(fp);
     fp = NULL;
     return -1;
    }
    return 0;
}

 

read file

static off_t file_size;

static char* get_h264_frame(char* raw_file)
{
    int raw_fd = open(raw_file, O_RDONLY);
    if (raw_fd < 0) {
        printf("open h264 raw file %s failed.\n", raw_file);
        return NULL;
    }
    
    file_size = lseek(raw_fd, 0, SEEK_END);
    if (file_size <= 0) {
        printf("h264 raw file %s empty.\n", raw_file);
        return NULL;
    }
    //printf("read entirely h264 raw file, size=%dKB \n", (int)(file_size / 1024));
    
    char*h264_raw = (char*)malloc(file_size);
    if (!h264_raw) {
        printf("alloc raw buffer failed for file %s.\n", raw_file);
        return NULL;
    }
    
    lseek(raw_fd, 0, SEEK_SET);
    ssize_t nb_read = 0;
    if ((nb_read = read(raw_fd, h264_raw, file_size)) != file_size) {
        printf("buffer %s failed, expect=%dKB, actual=%dKB.\n", 
            raw_file, (int)(file_size / 1024), (int)(nb_read / 1024));
        return NULL;
    }

    close(raw_fd);

    return h264_raw; 
}

 

 

int remove(char * filename);

 

int ftruncate(int fildes, off_t length);

 

1.ftruncate清空文件后,需要使用rewind或fseek将文件指针移到文件头。

 

2.ftruncate第一个参数是文件描述符int,而不是文件指针FILE *

 

 

27、向文件写入各种类型数据

#include <stdio.h>
#include <stdlib.h>
int main() {
    char *s="That's good news"; 
    int i=617; 
    FILE *fp;
    fp=fopen("test.dat", "w"); /*建立一个文字文件只写*/ 
    fputs("Your score of TOEFL is",fp); /*向所建文件写入一串字符*/ 
    fputc(':', fp); /*向所建文件写冒号:*/ 
    fprintf(fp, "%d/n", i); /*向所建文件写一整型数*/ 
    fprintf(fp, "%s", s); /*向所建文件写一字符串*/ 
    fclose(fp);
}

 

26、字符串分离

#include <stdio.h>
#include<string.h>
int main()
{
  char str[] = "mv a.c b.c";
  char *p;
  char *buff;
  buff=str;
  p = strsep(&buff, " ");
  while(p!=NULL)
  {
    printf("%s\n", p);
    p = strsep(&buff, " ");
  }
  return 0;
}

 

25、debug

#define BASIC() printf("[ %s %s() +%d ] ", __FILE__, __FUNCTION__, __LINE__ )

 

#define LOGI(args...) BASIC();printf(args)

#define LOGE(args...) LOGI(args)

 

 

24、socket http文件下载器c语言实现 ,带进度条

https://blog.csdn.net/xiongyangg/article/details/50767482

https://blog.csdn.net/qq_31629063/article/details/80846673

https://www.cnblogs.com/wainiwann/p/3148884.html

 
23、ERROR模块
/* $Id: errno.c 4613 2013-10-08 09:08:13Z bennylp $ */
/* 
 * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
 * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 */
#include <pjsip-simple/errno.h>
#include <pj/string.h>

/* PJSIP-SIMPLE's own error codes/messages 
 * MUST KEEP THIS ARRAY SORTED!!
 * Message must be limited to 64 chars!
 */

#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)

static const struct 
{
    int code;
    const char *msg;
} err_str[] = 
{
    /* Event errors */
    { PJSIP_SIMPLE_ENOPKG,        "No SIP event package with the specified name" },
    { PJSIP_SIMPLE_EPKGEXISTS,        "SIP event package already exist" },

    /* Presence errors */
    { PJSIP_SIMPLE_ENOTSUBSCRIBE,   "Expecting SUBSCRIBE request" },
    { PJSIP_SIMPLE_ENOPRESENCE,        "No presence associated with the subscription" },
    { PJSIP_SIMPLE_ENOPRESENCEINFO, "No presence info in the server subscription" },
    { PJSIP_SIMPLE_EBADCONTENT,        "Bad Content-Type for presence" },
    { PJSIP_SIMPLE_EBADPIDF,        "Bad PIDF content for presence" },
    { PJSIP_SIMPLE_EBADXPIDF,        "Bad XPIDF content for presence" },
    { PJSIP_SIMPLE_EBADRPID,        "Invalid or bad RPID document"},

    /* isComposing errors. */
    { PJSIP_SIMPLE_EBADISCOMPOSE,   "Bad isComposing indication/XML message" },
};


#endif    /* PJ_HAS_ERROR_STRING */


/*
 * pjsipsimple_strerror()
 */
PJ_DEF(pj_str_t) pjsipsimple_strerror( pj_status_t statcode, 
                       char *buf, pj_size_t bufsize )
{
    pj_str_t errstr;

#if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)

    if (statcode >= PJSIP_SIMPLE_ERRNO_START && 
    statcode < PJSIP_SIMPLE_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
    {
    /* Find the error in the table.
     * Use binary search!
     */
    int first = 0;
    int n = PJ_ARRAY_SIZE(err_str);

    while (n > 0) {
        int half = n/2;
        int mid = first + half;

        if (err_str[mid].code < statcode) {
        first = mid+1;
        n -= (half+1);
        } else if (err_str[mid].code > statcode) {
        n = half;
        } else {
        first = mid;
        break;
        }
    }


    if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
        pj_str_t msg;
        
        msg.ptr = (char*)err_str[first].msg;
        msg.slen = pj_ansi_strlen(err_str[first].msg);

        errstr.ptr = buf;
        pj_strncpy_with_null(&errstr, &msg, bufsize);
        return errstr;

    } 
    }

#endif    /* PJ_HAS_ERROR_STRING */


    /* Error not found. */
    errstr.ptr = buf;
    errstr.slen = pj_ansi_snprintf(buf, bufsize, 
                   "Unknown pjsip-simple error %d",
                    statcode);
    if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)
    errstr.slen = bufsize - 1;
    return errstr;
}

 

 

22、指针作为返回值的坑
/*
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>
#include <iostream>

using namespace std;

char* GetMemory()
{
    char *p = new char[100];
    memcpy(p,"hello,world",strlen("hello,world"));
    return p;
}

int main()
{
    char *str = GetMemory();
    cout << str << endl;
    delete [] str;       //防止内存泄露!
    return 0;
}
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>

char* GetMemory()
{
    char *p = (char *)malloc(sizeof(char)*100);
    memcpy(p,"hello,world \n",strlen("hello,world \n"));
    //p = "hello,world \n";
    return p;
}

int main()
{
    char *str = GetMemory();
    printf(str);
    free(str);       //防止内存泄露!
    return 0;
}


/*
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>
#include <unistd.h>

void GetMemory()
{
    char p[100];
    memcpy(p,"hello,world \n",strlen("hello,world \n"));
    printf(p);
    //return p;
}

int main()
{
    GetMemory();
    //printf(str);
    //free(str);       //防止内存泄露!
    return 0;
}
*/
 
21、debug背景颜色定义
# linux shell color support.
RED="\\033[31m"
GREEN="\\033[32m"
YELLOW="\\033[33m"
BLACK="\\033[0m"
    
 if [ $SRS_GPERF_MC = YES ]; then
        echo -e "${YELLOW}gmc(gperf memory check) for srs are builded -- Performance may suffer${BLACK}"
    else
        echo -e "${GREEN}note: gmc(gperf memory check) for srs are not builded${BLACK}"
    fi
 
20、结构体或对象排序
https://www.cnblogs.com/-beyond/p/5902113.html

19、结构体初始化的4种方式

https://blog.csdn.net/ericbar/article/details/79567108

 

18、 bool

/* define our own boolean type */
typedef int qbool;
#define true ((qbool)1)
#define false ((qbool)0)

 

17、逐行读写字符串

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

void ip_config_updata(char *ip, char *port)
{
    FILE * fd;

    fd=fopen("ip.config","w");
    if(fd==NULL)
    {
        perror("open file");
        exit(0);
    }
        if(ip!=NULL)
            fputs(ip,fd);
            fputc( '\n', fd );
        if(port!=NULL)
            fputs(port,fd);
            fputc( '\n', fd );

        fclose(fd);
}

main()
{
    ip_config_updata("hello","world");

    FILE * fp;
    char buf[1024];
    int len;

    fp=fopen("ip.config","r");
    if(fp==NULL)
    {
        perror("open file");
        exit(0);
    }

    fgets(buf,sizeof(buf),fp);
        len = strlen(buf);
        if((buf[len-1]=='\r')||(buf[len-1]=='\n'))
            buf[len-1] = '\0';
        printf("%s %d \n",buf,len - 1);
    fgets(buf,sizeof(buf),fp);
        len = strlen(buf);
        if((buf[len-1]=='\r')||(buf[len-1]=='\n'))
            buf[len-1] = '\0';
        printf("%s %d \n",buf,len - 1);

    fclose(fp);
}

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
    FILE * fp;
    FILE * fd;
    char buf[1024];
    int len;

    fp=fopen("data1.txt","r");
    if(fp==NULL)
    {
        perror("open file");
        exit(0);
    }
    fd=fopen("data2.txt","w");
    if(fd==NULL)
    {
        perror("open file");
        exit(0);
    }

    while(fgets(buf,sizeof(buf),fp)!=NULL)
    {
        fputs(buf,fd);
        printf("%s", buf);

        len = strlen(buf);
        buf[len-1] = '\0';  /*去掉换行符*/
        printf("%s %d \n",buf,len - 1);
    }

    fclose(fd);
    fclose(fp);
    return 0;
}

 

16、堆栈

 
15、C语言中的空字符串

对于char *str字符串,判断其为空的方法为:

if(strlen(str)==0)或者if(*str=='\0')[*p表示字符串中的第一个字符]

对于char str[9]数组,判断其为空的方法为:

if(strlen(str)==0)或者if(str[0]=='\0')

 

14、c++11的新特性总结
 
13、getopt_long函数被用来解析命令行选项参数, 参考bluez开源项目
1)百度百科里的实例
#include <stdio.h>
#include <getopt.h>
char *l_opt_arg;
char* const short_options = "nbl:";
struct option long_options[] = {
{ "name", 0, NULL, 'n' },
{ "bf_name", 0, NULL, 'b' },
{ "love", 1, NULL, 'l' },
{ 0, 0, 0, 0},
};
int main(int argc, char *argv[])
{
int c;
while((c = getopt_long (argc, argv, short_options, long_options, NULL)) != -1)
{
switch (c)
{
case 'n':
printf("My name is XL.\n");
break;
case 'b':
printf("His name is ST.\n");
break;
case 'l':
l_opt_arg = optarg;
printf("Our love is %s!\n", l_opt_arg);
break;
}
}
return 0;
}
[root@localhost wyp]# gcc -o getopt getopt.c
[root@localhost wyp]# ./getopt -n -b -l forever
My name is XL.
His name is ST.
Our love is forever!

 2)Sdptool.c中的应用

static struct {
    char *cmd;
    int (*func)(int argc, char **argv);
    char *doc;
} command[] = {
    { "search",  cmd_search,      "Search for a service"          },
    { "browse",  cmd_browse,      "Browse all available services" },
    { "records", cmd_records,     "Request all records"           },
    { "add",     cmd_add,         "Add local service"             },
    { "del",     cmd_del,         "Delete local service"          },
    { "get",     cmd_get,         "Get local service"             },
    { "setattr", cmd_setattr,     "Set/Add attribute to a SDP record"          },
    { "setseq",  cmd_setseq,      "Set/Add attribute sequence to a SDP record" },
    { 0, 0, 0 }
};

static void usage(void)
{
    int i, pos = 0;

    printf("sdptool - SDP tool v%s\n", VERSION);
    printf("Usage:\n"
        "\tsdptool [options] <command> [command parameters]\n");
    printf("Options:\n"
        "\t-h\t\tDisplay help\n"
        "\t-i\t\tSpecify source interface\n");

    printf("Commands:\n");
    for (i = 0; command[i].cmd; i++)
        printf("\t%-4s\t\t%s\n", command[i].cmd, command[i].doc);

    printf("\nServices:\n\t");
    for (i = 0; service[i].name; i++) {
        printf("%s ", service[i].name);
        pos += strlen(service[i].name) + 1;
        if (pos > 60) {
            printf("\n\t");
            pos = 0;
        }
    }
    printf("\n");
}

static struct option main_options[] = {
    { "help",    0, 0, 'h' },
    { "device",    1, 0, 'i' },
    { 0, 0, 0, 0 }
};

int main(int argc, char *argv[])
{
    int i, opt;

    bacpy(&interface, BDADDR_ANY);

    while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
        switch(opt) {
        case 'i':
            if (!strncmp(optarg, "hci", 3))
                hci_devba(atoi(optarg + 3), &interface);
            else
                str2ba(optarg, &interface);
            break;

        case 'h':
            usage();
            exit(0);

        default:
            exit(1);
        }
    }

    argc -= optind;
    argv += optind;
    optind = 0;

    if (argc < 1) {
        usage();
        exit(1);
    }

    for (i = 0; command[i].cmd; i++)
        if (strncmp(command[i].cmd, argv[0], 4) == 0)
            return command[i].func(argc, argv);

    return 1;
}

 

fgets函数被用来命令行交互, 参考pjsip开源项目

static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len)
{
    char *p;

    printf("%s (empty to cancel): ", title); fflush(stdout);
    if (fgets(buf, (int)len, stdin) == NULL)
    return PJ_FALSE;

    /* Remove trailing newlines. */
    for (p=buf; ; ++p) {
    if (*p=='\r' || *p=='\n') *p='\0';
    else if (!*p) break;
    }

    if (!*buf)
    return PJ_FALSE;

    return PJ_TRUE;
}

 

static void ui_answer_call()
{
    pjsua_call_info call_info;
    char buf[128];
    pjsua_msg_data msg_data_;

    if (current_call != -1) {
    pjsua_call_get_info(current_call, &call_info);
    } else {
    /* Make compiler happy */
    call_info.role = PJSIP_ROLE_UAC;
    call_info.state = PJSIP_INV_STATE_DISCONNECTED;
    }

    if (current_call == -1 ||
    call_info.role != PJSIP_ROLE_UAS ||
    call_info.state >= PJSIP_INV_STATE_CONNECTING)
    {
    puts("No pending incoming call");
    fflush(stdout);
    return;

    } else {
    int st_code;
    char contact[120];
    pj_str_t hname = { "Contact", 7 };
    pj_str_t hvalue;
    pjsip_generic_string_hdr hcontact;

    if (!simple_input("Answer with code (100-699)", buf, sizeof(buf)))
        return;

    st_code = my_atoi(buf);
    if (st_code < 100)
        return;

    pjsua_msg_data_init(&msg_data_);

    if (st_code/100 == 3) {
        if (!simple_input("Enter URL to be put in Contact",
        contact, sizeof(contact)))
        return;
        hvalue = pj_str(contact);
        pjsip_generic_string_hdr_init2(&hcontact, &hname, &hvalue);

        pj_list_push_back(&msg_data_.hdr_list, &hcontact);
    }

    /*
    * Must check again!
    * Call may have been disconnected while we're waiting for
    * keyboard input.
    */
    if (current_call == -1) {
        puts("Call has been disconnected");
        fflush(stdout);
        return;
    }

    pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data_);
    }
}

 

 
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、linux静态库和动态库的应用

https://blog.csdn.net/m0_38087936/article/details/81262181

 

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;
}

 

typedef struct task
{
    pthread_t id;
    int fd;
    uint8_t buf[1024];
    int size;
}task_t;

void (*task_array[])(int fd, uint8_t* buf, uint8_t size) = {
    qx_raw ,
    qx_raw_2_ubx ,
    qx_raw_2_ubx_zhd ,
    zhd_raw,
    zhd_raw_2_ubx,
    zhd_raw_2_ubx_zhd,
};

static void* 
task_done(void *arg)
{
    task_t task = *(task_t*)(arg);
    int i = 0;
    while(task_array[i] != NULL){
        (task_array[i])(task.fd, task.buf, task.size); 
        i++;
    }
    printf ("task %d done !\n", task.fd);     
}

 

static int send_ubx2mc(int fd, unsigned char *cmd, int len);

static int send_zhd2mc(int fd, unsigned char *cmd, int len);

static void agnss_update(int fd, QX_report_data_t rp, int (*send_cmd2mc)(int, unsigned char*, int));

 

 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、C语言结构体初始化的四种方法 

https://blog.csdn.net/ericbar/article/details/79567108

结构体等效

struct msg_t{
    long type;
    char buf[100];
};

struct msg_t msg;

初始化

struct msg_t msg={1,"login"};

typedef struct {
    long type;
    char buf[100];
}msg_t;

msg_t msg;

初始化

msg_t msg={1,"login"};

等效

posted @ 2017-01-04 13:20  dong1  阅读(496)  评论(0编辑  收藏  举报