strcpy与memcpy区别:
1、复制的内容不同。strcpy只能复制字符串,包括结束符,而memcpy可以复制任意内容,例如字符数组、整型、结构体、类等。
2、复制的方法不同。strcpy不需要指定长度,它遇到被复制字符的串结束符"\0"才结束,所以容易溢出。memcpy则是根据其第3个参数决定复制的长度。
3、用途不同。通常在复制字符串时用strcpy,而需要复制其他类型数据时则一般用memcpy
以下情况使用memcpy会导致bug出现:
char recvBuffer[20] = {0};
memcpy(recvBuffer, "1.00", sizeof(recvBuffer)); //拷贝长度超过了"1.00"的长度,有可能会拷贝其它内容到recvBuffer中
printf("recvBuffer=%s\n",recvBuffer); //多线程、多进程环境下,打印内容可能会有乱码,当然前5个字符是"1.00"加上'\0'
以上打印内容中,前5个字符是确定的,但是从第6个字符到第20个字符的内容是不确定的。
所以,这种情况最好使用strcpy:
strcpy(recvBuffer, "1.00");
或者:
memcpy(recvBuffer, "1.00", strlen("1.00")); //strlen("1.00")=4,不包括结束字符
strcpy实现:
char *strcpy_de(char *dest, const char *src){
if(dest == NULL && src == NULL)
return NULL;
char *tempDest = dest;
while((*tempDest++ = *src++) != '\0');//赋值后,先判断*tempDest的值是否是'\0',再自加1
return dest;
}
while((*strDest++ = *strSrc++) != '\0'); 的分析:(参考 https://blog.csdn.net/qiqisunshine/article/details/77185019)
1. 很明显,上面的表达式是一个组合表达式。组合表达式由子表达式组成,子表达式又可能是组合表达式,这样就形成了一个树状的数据结构。对表达式的评估就类似于对树结点的遍历。首先我们应该注意到"()"操作符,它具有最高的优先级,所以从整体来看,整个表达式应该是个"!="操作。"!="左边又是一个组合表达式,而右边是一个常量"\0',很明显下面的工作就是评估(*strDest++=*strSrc++)。
2.在这一步,我们要对表达式(*strDest++=*strSrc++)进行评估。由于赋值表达式具有较低的优先级,所以表达式 又可以写成:(*strDest++) = (*strSrc++),所以整个表达式是个"="操作,"="左边又是一个组合表达式,右边也是一个组合表达式,这里就需要从关联性来判断左边还是右边也被评估。由于"="的关联性是从右到左,所以(*strSrc++)先被评估,(*strDest++)后被评估。
2.1 在这一步,我们要对表达式(*strSrc++)进行评估。由于"++"的优先级大于"*",所以表达式又可以写成:*(strSrc++)。我们要先对表达式strSrc++进行评估,然后用表达式的值再去评估*(strSrc++)的值。对于表达式strSrc++,这里要需要注意区分变量的值和表达式的值。对于"后增1"表达式,表达式的值是变量strSrc的值,然后变量strSrc的值会"加1",也就是说表达式的值是strSrc变化前的值,而strSrc的值会发生变化。值得注意的是,我们知道strSrc的值会发生变化,但是我们却不知道strSrc的值发生变化的具体时间,这个变化具体的执行时间由编译器决定了,这就决定了任何依赖strSrc的表达式的值是不确定的,具体的值依赖编译器的实现。完成了对strSrc++的评估后,取值操作符就对表达式的值所对应的内存空间进行取值操作。
2.2 在这一步,我们要对表达式(*strDest++)进行评估。具体的评估的分析完全和2.1中的分析一致。
2.3 在这一步,我们要对表达式(*strDest++) = (*strSrc++)进行评估,这是个赋值表达式,将右表达式的值赋给左边表达式的值。值得注意的是,对于赋值表达式,表达式本身的值等于左边子表达式的值。
3.由于"!="表达式左边的子表达式的值已经被评估出来了,下面就执行"!="操作。"!="表达式的是一个布尔值。
通过以上深入的分析,我们知道这个表达式完成了以下多个功能:
1.对于指针strDest, strSrc,将strSrc所指的内存空间的值赋给由strDest所指的内存空间。
2.判断赋值后的strDest所指的内存空间的指是否等于0。
3.对于指针strest,strSrc,他们的值分别加1,即指向下一个元素。