【C语言】如何写出好(易于调试)的代码——assert和const的使用

目录

一、优秀的代码

 二、示范:模拟实现库函数:strcpy

三、宏assert 

四、const的作用

1、const修饰变量

2、const修饰指针 

五、 strcpy库函数


一、优秀的代码

1. 代码运行正常

2. bug很少

3. 效率高

4. 可读性高

5. 可维护性高

6. 注释清晰

7. 文档齐全

常见的coding技巧:

1. 使用assert
2. 尽量使用const
3. 养成良好的编码风格
4. 添加必要的注释
5. 避免编码的陷阱

 二、示范:模拟实现库函数:strcpy

如果只是写成这样,那么会面临一些问题:当函数传入空指针时,是非常危险的。 

#include <cassert>

char* myStrcpy(char* dst, char* src)
{
	
	char* ret = dst;
	while (*dst = *src)
	{
		dst++;
        src++;
	}
	return ret;
}


int main()
{
	char arr1[] = {"Hello nash"};
	char arr2[11] = { 0 };
	myStrcpy(arr2, arr1);
	int i = 0;
	printf("%s\n", arr2);
	return 0;
}

那么这样的话,有的人想到的解决方法是在执行之前先判断一下传入的参数,如果不等于NULL再执行。

char* myStrcpy(char* dst, char* src)
{
	if(dst != NULL && src != NULL)
	{
        char* ret = dst;
	    while (*dst = *src)
	    {
		    dst++;
            src++;
	    }
    }
	return ret;
}

 但是这样写又面临一个问题,因为if语句不管在debug模式还是release模式下,只要进入函数就一定会执行if语句,这样就降低了函数的效率,浪费时间。而这里我给大家介绍一个宏:assert

三、宏assert 

assert只会在debug模式下被使用,能够防止程序员错误使用空指针。当在release模式下时会被自动优化消失,不参与编译。这样既能做到不让程序员使用空指针,又能不降低效率。

336673db307a497bbd22f87b57463c74.png

包含头文件: cassert

当给assert传入的表达式如果为假,那么就会触发宏报错,并且还会返回报错信息,这样也能帮助程序员快速解决问题,显然比直接使用if判断好很多。

43244d22e62f42f5b0bc34b3afae5487.png

 那么只要将src和dst传给assert,就可以避免错误运行函数。

char* myStrcpy(char* dst, char* src)
{
	assert(src&&dst);
	char* ret = dst;
	while (*dst++ = *src++)
	{
		;
	}
	return ret;
}

四、const的作用

1、const修饰变量

const能够限制被修改。当const修饰变量时,只是在语法层面限制了变量的修改,但本质上它依然是变量,是一种并不能被修改的变量。

7b11927a56ad4a47bd5f52c8b35d4fc4.png

2、const修饰指针 

 const修饰指针有两种方式:

  • const放在*的左边    const int* p
  • const放在*的右边    int* const p
3903c334230846528476da1a2c388c8a.png

测试const放在*的左边

b48811f276c64f469d9f73b38e6d0fb2.png

测试const放在*的右边

结论: 

1. const如果放在*的左边,修饰的是指针指向的内容,保证指针指向的内容不能通过指针来改变。但是指针变量本身的内容可变。
2. const如果放在*的右边,修饰的是指针变量本身,保证了指针变量的内容不能修改,但是指针指向的内容,可以通过指针改变。

五、 strcpy库函数

 这是strcpy函数的官方写法,可以看到就是使用了assert与const提高了代码的质量。

/***
*char *strcpy(dst, src) - copy one string over another
*
*Purpose:
*       Copies the string src into the spot specified by
*       dest; assumes enough room.
*
*Entry:
*       char * dst - string over which "src" is to be copied
*       const char * src - string to be copied over "dst"
*
*Exit:
*       The address of "dst"
*
*Exceptions:
*******************************************************************************/
char * strcpy(char * dst, const char * src)
{
       char * cp = dst;
assert(dst && src);
       while( *cp++ = *src++ )
               ;     /* Copy src over dst */
       return( dst );
}

如果觉得作者写的不错,求给作者一个大大的点赞支持一下,你们的支持是我更新的最大动力! 

猜你喜欢

转载自blog.csdn.net/zzzzzhxxx/article/details/132842053