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

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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值