在实现业务功能的时候,编写代码的时候遇到一些奇怪的问题,做笔记汇总:
1: 用宏的方式实现日志打印,在编译的时候一直有警告,报在宏定义的位置,如下:
#define LOG(TAG, format, ...) \ do \ { \ printf("[" TAG "] %s:%d |" format "\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \ } while (0)
编译时一直提示有告警如下:
In file included from wdn_parse_configfile.c:5:0: wdn_parse_configfile.c: In function ‘print_configfile’: log.h:13:16: warning: format ‘%s’ expects argument of type ‘char *’, but argument 4 has type ‘unsigned int’ [-Wformat=] printf("[" TAG "] %s:%d |" format "\n", __FUNCTION__, __LINE__, ##__V ^ log.h:19:31: note: in expansion of macro ‘LOG’ #define LOG_INFO(format, ...) LOG("INFO", format, ##__VA_ARGS__) ^ wdn_parse_configfile.c:134:2: note: in expansion of macro ‘LOG_INFO’ LOG_INFO("udp_controller port :%s ", config_t->udp_controller_port);
理解:在代码运行时,宏定义会替代宏的代码部分,所以这里的问题并不是宏定义的问题,而是实际调用代码处的问题。
也就是告警对应的note提示:wdn_parse_configfile.c:134:2 处,代码有问题。
===》还是基础不扎实,还研究了一下宏的定义。
2:char**传参,获取到内部申请到的字符串
在实现业务功能的时候,想要拆分代码,使代码逻辑清晰。
这里涉及到一个逻辑,想要在函数内部对char* 做实时内存申请并传递出去。
1:原本想着,char* 本来传递的就是字符串地址,直接传参的形式进行申请内存:
demo及运行结果如下:
#include <stdio.h> #include <stdlib.h> #include <string.h> int get_str(char* str) { char * buff = (char*) malloc(10); memset(buff, 0, 10); memcpy(buff, "hello", 5); str = buff; return 0; } int main() { char * str; get_str(str); if(str == NULL) { printf("error str is null"); }else { printf("success str is %s \n", str); } return 0; } //运行结果如下 ubuntu@ubuntu:~/0707_wdn_master/test$ ./test error str is null
理解:思考了一下,函数的值传递和地址传递,这里的char* 其实就是类似于基础类型,实际是进行拷贝构造传参,拷贝了一份传递给函数,并不是char* 本身。
2:在考虑到值传递的拷贝构造后,我想到可以用地址传参,这里进行测试
demo1:
#include <stdio.h> #include <stdlib.h> #include <string.h> //注意 外部释放内存 int get_str(char** str) { char * buff = (char*) malloc(10); memset(buff, 0, 10); memcpy(buff, "hello", 5); *str = buff; return 0; } //main关函数传递了char*的地址,对char*地址中存的东东做改变 int main() { char * str; get_str(&str); if(str == NULL) { printf("error str is null"); }else { printf("success str is %s \n", str); } free(str); return 0; } //代码测试成功: ubuntu@ubuntu:~/0707_wdn_master/test$ ./test success str is hello
理解:
按地址进行传递,把char*的地址传进去,对地址中存储的数据进行操作。
demo2: 这里其实是不合逻辑,不可靠的
#include <stdio.h> #include <stdlib.h> #include <string.h> //注意 外部释放内存 int get_str(char** str) { char * buff = (char*) malloc(10); memset(buff, 0, 10); memcpy(buff, "hello", 5); *str = buff; return 0; } int main() { char ** str; str = (char**)malloc(sizeof(char**)) get_str(str); if(str == NULL) { printf("error str is null"); }else { printf("success str is %s \n", *str); } free(*str); free(str); return 0; } //虽然代码测试成功:这里要注意,二级指针要分配一个地址后再去用,才符合逻辑 ubuntu@ubuntu:~/0707_wdn_master/test$ ./test success str is hello
理解:
char** 通常是用来保存一级指针的地址,在使用前一定要做地址的内存申请和初始化,不然虽然编译没有问题,但是在运行时会崩溃。