由strcat源码重新考虑‘\0’的问题

来源:互联网 发布:知金科技投资 编辑:程序博客网 时间:2024/06/09 08:32

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吧

0 0
原创粉丝点击