利用assert优化代码
一、assert的介绍
声明形式:void assert( int expression );
调用该函数,需引头文件<assert.h>
使用效果:计算表达式,当assert括号内表达式结果为FALSE(假)时,打印诊断消息并中止程序。
当表达式计算为false(0)时,Assert输出诊断消息,并调用abort终止程序执行。如果表达式为真(非零),则不采取任何操作。诊断消息包括失败的表达式、源文件的名称和断言失败的行号。
二、代码的优化
①模拟实现并优化strcpy函数
首先我们简单模拟实现一段字符串拷贝函数。
第一步:
原理是吧arr2中字符持续循环拷贝到arr1中,知道arr1结尾字符为’\0’时停止操作。
void my_strcpy(char* arr1, char* arr2)
{
while (*arr1 != '\0')
{
*arr1 = *arr2;
arr1++;
arr2++;
}
}
第二步:
·接下来,为了加快代码效率,我们可以选择合并循环代码块内的内容。
·由于空指针不能进行解引用操作,否则程序发生错误,我们引入assert断言arr1.arr2的值不为NULL。
#include<assert.h>
void my_strcpy(char* arr1, char* arr2)
{
assert(arr1 && arr2);
while (*arr1++ = *arr2++){;}//这里要是传递了空指针过来,会导致程序崩溃,所以要利用断言规避这种错误
}
第三步:
·我们对该函数进行最后的加工:
·首先:在写函数时,我们一般将不会被修改的参数用const进行常量化,防止错误操作不小心改变其值。
·其次:strcpy函数其实是有返回值的,返回目标字符串的首地址。这里我们模拟实现时也要加上这一步。
#include<assert.h>
char* my_strcpy(char* arr1,const char* arr2)
{ //加const修饰原字符串,防止其由于失误操作被覆盖
char* start = arr1;//保留目的地字符串的起始地址
assert(arr1 && arr2);
while (*arr1++ = *arr2++) { ; }
return start;//返回目的地字符串起始地址,方便以后函数调用
}
以上我们就较为完整的模拟实现并较好的优化了strcpy函数。
②模拟实现并优化strlen函数
计算字符串长度,即字符串中每有一个字符统计一个长度,知道遇’\0’时停止(不计算’\0’)长度。
参考上面代码逐步完善的过程,我们就不多说了,直接上代码!
#include<assert.h>
int my_strlen(const char* arr)
{ //const放在char*前面,保证输入是字符串内容不被修改
assert(arr);//断言,保证指针的有效性
int i = 0;
//判断每次*arr是否为'\0',不是则进入循环i+1;是则条件不成立退出循环
while (*arr++)
{
i++;
}
return i;
}