strcat函数在c中string.h的头文件中,是连接字符串的函数,看看源码
char *strcat(char *strDest, const char *strScr)
//将源字符串加const,表明其为输入参数
{
char * address = strDest;
//该语句若放在assert之后,编译出错
assert((strDest != NULL) && (strScr != NULL));
//对源地址和目的地址加非0断言
while(*strDest)
//是while(*strDest!=’/0’)的简化形式
{
strDest++;
//约束的。所以要在循环体内++;因为要是
//*strDest最后指向该字符串的结束标志’/0’
}
while(*strDest++ = *strScr++)
{
NULL; //该循环条件内可以用++,
}
//此处可以加语句*strDest=’/0’;有无必要?
return address; //为了实现链式操作,将目的地址返回
}
assert函数的源码也给出吧,以后有时间分析
/* Allow this file to be included multiple times
with different settings of NDEBUG. */
//assert 为C库提供的一种断言机制
//断言用来在标准错误输出流输出信息,并且使程序异常终止
/*
断言的机制:
*/
//首先取消 assert 宏的定义,
//这样做的目的是为了防止宏重复被定义
#undef assert
#undef __assert
//通过判断是否定义宏 NDEBUG 来判断在源代码中是否需要宏assert
/*
如果定义了 NDEBUG 宏,就表示不需要在程序中引用 assert 宏
NDEBUG: do not debug
否则就在程序中,assert 宏将被执行
可以发现assert宏在定义 NDEBUG时,定义很特别,宏参数并没有引用
*/
#ifdef NDEBUG
//定义了NDEBUG宏,assert 宏定义为不做任何提示输出
#define assert(ignore) ((void)0)
#else
void __eprintf (); /* Defined in gnulib */
#ifdef __STDC__ //定义了__STDC__宏
#define assert(expression) \
((void) ((expression) ? 0 : __assert (#expression, __FILE__, __LINE__)))
#define __assert(expression, file, lineno) \
(__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", \
expression, lineno, file), 0)
#else /* no __STDC__; i.e. -traditional. */
#define assert(expression) \
((void) ((expression) ? 0 : __assert (expression, __FILE__, __LINE__)))
#define __assert(expression, file, lineno) \
(__eprintf ("Failed assertion `%s' at line %d of `%s'.\n", \
"expression", lineno, file), 0)
#endif /* no __STDC__; i.e. -traditional. */
#endif
还是研究strcat,基本思想就是首先寻找字符串结束符‘\0’,然后将要连接的连接起来,自己的实现
#include <iostream>
#include <assert.h>
using namespace std;
char * my_strcat(char * dst,const char* src)
{
char * head = dst;
assert((dst!=NULL)&&(src!=NULL));
while(*dst++!='\0');
dst--;
while(*src!='\0')
{
*dst++=*src++;
}
*dst='\0';
return head;
}
int main()
{
char buff[50]="gff";
char * b;
b=my_strcat(buff,"hello");
return 0;
}
为了防止野指针,所以需要检测传进来的指针是否有效
对比源码有下面一句
while(*strDest) //是while(*strDest!=’/0’)的简化形式
因为一直以为while是在0时退出,而‘\0’和 0 是否一致?
做实验吧
在谷歌中这样解释
‘\0’是c/c++语言中的字符串结束符,在ASCII字符集中对应数字0。
果然如此,这是其ascii码,0的码是40d,这样就可以理解了
while(*strDest++ = *strScr++)
{
NULL; //该循环条件内可以用++,
}
这里没有在末尾特别加结束符,其实是没有必要,
这个while的执行顺序是,首先scr赋值给dest,然后dest再送给while判定,这就包含了结束符
在调试中,由于buff没有初始化,导致里面乱码,检测不到结束符,也许这也是一个使用trap吧