项目中写代码的注意事项总结

1,c++中怎么使用c语言中声明的函数(直接使用),c语言中使用c++中声明的函数(加入下面这个extern "c";

#ifdef  __cplusplus
extern "C" 
{
#endif

函数的结尾加上

#ifdef  __cplusplus
}
#endif

参考文章: 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语言的函数返回值的作用 

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博客

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博客

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博客

14,非定长内存拷贝时应进行长度检查,确保拷贝不会越界;

参考文章:

15,进行非定长内存拷贝之前需检查拷贝字符串长度,确保拷贝不会越界。

参考文章:c语言内存管理(内存泄漏和句柄泄露)_陌上花开缓缓归以的博客-CSDN博客_句柄泄露和内存泄露

16,循环控制不能用char型变量,由于char型值范围是-128--127,可能出现死循环;

参考文章:c语言负数翻转问题_陌上花开缓缓归以的博客-CSDN博客_c语言负数转换

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博客

24,调用有返回值的函数时要即时做异常处理,且风格要统一;

参考文章:c语言论函数返回值的重要性_陌上花开缓缓归以的博客-CSDN博客_c语言的函数返回值的作用

25,函数栈变量长度不要超过1K,超过1k建议用malloc或者new分配堆内存。

26,尽量少使用变参函数,比如printf这种函数;

27,单个功能函数不要超过500行,嵌套不要超过?

28,结构体里面的元素字数不宜过多;

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

陌上花开缓缓归以

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

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

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

打赏作者

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

抵扣说明:

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

余额充值