项目中写代码的注意事项大总结 我会带着你远行 2023-01-16 06:58 121阅读 0赞 1,c++中怎么使用c语言中声明的函数(直接使用),c语言中使用c++中声明的函数(加入下面这个extern "c"; #ifdef __cplusplus extern "C" { #endif 函数的结尾加上 #ifdef __cplusplus } #endif 参考文章: [c语言文件如何使用c++函数\_陌上花开缓缓归以的博客-CSDN博客][c_c_-CSDN] 2,函数返回值一般用于返回错误码,不要用于直接返回函数的执行结果。 #define MAX_PORT 20 int test_fun(int port,int* buf) { if(port < 0 || port > MAX_PORT) { return -1; } if( buf == NULL) { return -1; } //buf用于保存数据 return 0; } 参考文章:[c语言论函数返回值的重要性\_陌上花开缓缓归以的博客-CSDN博客\_c语言的函数返回值的作用][c_-CSDN_c] 3,有符号和无符号数据类型的混合运算,应注意类型转换; #include<stdio.h> //typedef unsigned int size_t; //size_t sizeof( ) int main() { char *s = "tangtest"; if(sizeof(s) <= -1) { printf("sizeof(s) get length failure\n");//代码打印的这个 } else { printf("sizeof(s)= %ld\n",sizeof(s)); } return 0; } 将if(sizeof(s) <= -1)改为 if((signed int)sizeof(s) <= -1) 立即数作为无符号类型使用时,后面应加上U标识. #include<stdio.h> int main() { signed int a = -1; if(a < 1U) { printf("a < 1\n"); } else { printf("a > 1\n"); } if(a < 1) { printf("a < 1\n"); } else { printf("a > 1\n"); } return 0; } 4,不要把子程序的参数用作工作变量,如果需要,另设一个临时变量来处理; void process(int a,int b,int c); int func(int arg1, int arg2, int arg3) { process(arg1, arg2, arg3); return 0 } 我们最好不要像这样直接使用变量,我们最好使用一个临时变量保存而后对其进行操作: void process(int a,int b,int c); int func(int arg1, int arg2, int arg3) { int temp1 = arg1; int temp2 = arg2; int temp3 = arg3; process(temp1, temp2, temp3); return 0; } 5,项目中禁止直接使用全局变量,一般用set/get函数来实现对全局变量的读写; 参考文章:[项目中全局变量的使用(怎么对全局变量进行读写操作)\_陌上花开缓缓归以的博客-CSDN博客][-CSDN] 6,防止字符串拷贝时,存储空间不够,应保证有NULL结束符,既是在获取拷贝字符串时,应该意识到存储空间的大小,宁可截断,也不要越界。 char g_dst[20] = {0}; int mycopy(char* src) { if(src == NULL) { return -1; } else if(strlen(src) >= 20) { memcpy(g_dst,src,19); g_dst[20] ='\0'; } else { memcpy(g_dst,src,strlen(src)); } return 0; } 7,函数返回值不应简单的返回成功0或失败-1,而应该返回指示具体错误原因的错误码,错误码按照固定的编码格式定义。 typedef enum return_value { return_ok = 0, read_failre = -1, write_failure = -2, para_error = -3, not_ready = -4, status_failure = -5 }RETURN_VALUE; 8,函数实现时除了实现函数功能的代码外,还需要包含完善的日志打印,以便于进行函数的调试和维护。 参考文章:[c语言实现logfile库(打印日志库的实现)\_陌上花开缓缓归以的博客-CSDN博客][c_logfile_-CSDN] 9,尽量用乘法或其它运算方法代替除法,特别是浮点运算中的除法,浮点运算除法要消耗较多CPU资源。因为通过将除法运算替换为乘法运算,编译器可以省去多个循环; #define PI 3.1415926 float except_result(float num) { return num / PI; } #define PIP 1/3.1415926 float mult_result(float num) { return num * PIP; } 10,注意运算表达式是否会导致缓冲区的上溢、下溢 11,当代码段较长,特别是多重嵌套时,我们一般在程序块的结束行右方加注释标记,以表明某程序块的结束,增加程序块的可阅读性; int function() { if(condition) { test_fun(); }/*******test fun******/ return 0; } 12,信号量嵌套调用的时候,注意占用和释放的顺序,在使用嵌套调用信号量保护时,后占用的先释放,先占用的后释放,因为使用嵌套信号量调用时,不先释放后占用的信号量,会导致信号量死锁; int mutext_a; int mutext_b; int mutext_test() { pthread_mutext_lock(&mutext_a); pthread_mutext_lock(&mutext_b); test_fun(); pthread_mutex_unlock(&mutext_b); pthread_mutex_unloc(&mutext_a); return 0; } 13,数组的下标尽量避免使用表达式,且下标表达式要做合法性检查; 参考文章:[c语言越界问题(字符串,数组下标)\_陌上花开缓缓归以的博客-CSDN博客][c_-CSDN] 14,非定长内存拷贝时应进行长度检查,确保拷贝不会越界; 参考文章: 15,进行非定长内存拷贝之前需检查拷贝字符串长度,确保拷贝不会越界。 参考文章:[c语言内存管理(内存泄漏和句柄泄露)\_陌上花开缓缓归以的博客-CSDN博客\_句柄泄露和内存泄露][c_-CSDN 1] 16,循环控制不能用char型变量,由于char型值范围是-128--127,可能出现死循环; 参考文章:[c语言负数翻转问题\_陌上花开缓缓归以的博客-CSDN博客\_c语言负数转换][c_-CSDN_c 1] 17,多维数组的非零初始化应用括号指明维度; a\[2\]\[3\] = \{ \{0\}\}; 18,枚举类型要么首元素“=”赋值,要么所有元素使用“=”赋值,首元素赋值遵循了后续元素依次加1的规则,所有元素赋值明示了每个元素的值。 enum color { red = 3, blue, green, yellow = 5 };/*不推荐*/ enum color { red = 3, blue = 4, green = 5, yellow = 5 };/*推荐*/ 19,对unsigned char或unsigned short型数据做位运算后应将结果强制转换为该数据的原始类型 Uint16_t result_16 = ((uint16_t)(~(uint16_t)port)) >> 4; 20,避免使用BOOL参数,在编程过程尽量使用c语音定义的基本数据结构(枚举),BOOL参数无意义,TRUE/FALSE含义非常模糊;BOOL参数值不利于扩充; 21,**尽量少用可变长数组,**虽然可变长数组的效率比在堆上动态申请的效率要高,但是由于我们一些产品还在使用较早的编译器,可能对C99标准的支持不够好,生成的可变长数组(VLA)代码存在缺陷而引入难以排查的异常问题; 22,在for循环或者while循环时,如果循环内数组下标与循环的参数无关联并且对下标有所操作时,在循环最开始检查数组是否溢出; //计算数组中2-n个数据的总和 int sum(int* a,int n) { int sum = 0; if( a == NULL) { return -1; } if(n < 2) { return 0; } for(int i = 0; i < n; i++) { if((i + 2) >= n) { break; } sum = sum + a[i+2]; printf("a[i+2] = %d,sunm =%d\n",a[i+2],sum); } return sum; } int a[3]={1,2,3} int offset=0; for(i=0;i<3;i++) { if((offset+2)>=3) { break; } offset +=2; a[offset]=1; } 23,同类宏定义采用枚举变量替代; 参考文章:[c语言枚举enum的使用总结\_陌上花开缓缓归以的博客-CSDN博客][c_enum_-CSDN] 24,调用有返回值的函数时要即时做异常处理,且风格要统一; 参考文章:[c语言论函数返回值的重要性\_陌上花开缓缓归以的博客-CSDN博客\_c语言的函数返回值的作用][c_-CSDN_c] 25,函数栈变量长度不要超过1K,超过1k建议用malloc或者new分配堆内存。 26,尽量少使用变参函数,比如printf这种函数; 27,单个功能函数不要超过500行,嵌套不要超过? 28,结构体里面的元素字数不宜过多; [c_c_-CSDN]: https://blog.csdn.net/qq_40008325/article/details/113748295 [c_-CSDN_c]: https://blog.csdn.net/qq_40008325/article/details/103772875 [-CSDN]: https://blog.csdn.net/qq_40008325/article/details/111303671 [c_logfile_-CSDN]: https://blog.csdn.net/qq_40008325/article/details/111304442 [c_-CSDN]: https://blog.csdn.net/qq_40008325/article/details/111398561 [c_-CSDN 1]: https://blog.csdn.net/qq_40008325/article/details/111398513 [c_-CSDN_c 1]: https://blog.csdn.net/qq_40008325/article/details/111399095 [c_enum_-CSDN]: https://blog.csdn.net/qq_40008325/article/details/102751453
还没有评论,来说两句吧...