好吧 strcpy有点疑问

wudaijun 2012-11-18 08:32:41

#include<stdio.h>
#include <string.h>

int main()
{
char str[7] = "aabbcc";
strcpy(str+2, str);
printf("%s\n", str);
return 0;
}
输出 aaaabbbb
大家解释一下吧....
...全文
186 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
firendlys 2012-11-18
  • 打赏
  • 举报
回复
具体情况类似与这个吧,不过这个是 memcpy 版本的,原理差不多..

void *memcopy_dword(void *dest, void *src, int n) 
{ 
_asm { 
mov esi, src 
mov edi, dest

mov ecx, n 
mov ebx, ecx // ebx, ecx 都是4个字节的,一次过复制4个字节..
and ecx, 3 //所以,原始字符串的改变也是,一次就改变4个字节...
rep movsb 
mov ecx, ebx 
shr ecx, 2 
rep movsd 
}

return dest; 
}
至于实际上,你的程序里面到底是调用那个版本的 strcpy ,这个是由编译器和系统函数库决定的.由不得你决定,有些程序安装的是最慢的(如1楼所说)的版本,也有些程序安装的是优化后的4个字节为单位复制的版本(貌似vs基本上都是).... 所以,你的这个程序的运行结果,在不同的系统函数库下(比如vc/vs/tc等),可能是不同的...注意:可能而已.. 仅供参考..
newtee 2012-11-18
  • 打赏
  • 举报
回复
VS输出结果和楼主的一样 还是画内存图(VS里面strcp函数实现方式估计不一样) 所以也没函数源代码可以带 两个指针一个指向数组第一位 另一个第三位 然后第三位的值被赋值成第一位的值
wudaijun 2012-11-18
  • 打赏
  • 举报
回复
引用 10 楼 zhuankeshumo 的回复:
嗯 这个是用的你说的版本 刚才friendly说的有道理 可能用得strcpy版本不一样
wudaijun 2012-11-18
  • 打赏
  • 举报
回复
引用 9 楼 firendlys 的回复:
貌似,strcpy是有几个版本的,其中一个是ls说的情况,另外一个是经过优化的版本. 这个优化的版本的复制不再是一个字节一个字节地复制,而是4个字节4个字节地复制..(因为32位系统的字长是4个字节,所以,4个字节4个字节复制的话,效率可以提高3倍...) 具体代码我就忘了,可以自己百度,参考 memcpy的优化版本 即可. (具体网址我一时之间也找不到...找……
嗯 这样解释的话就没问题了 大概就是这个原因了。
wudaijun 2012-11-18
  • 打赏
  • 举报
回复
引用 3 楼 breakfisher 的回复:
C/C++ code?12345678910#include<stdio.h>#include <string.h> int main(){char str[7] = "aabbcc";strcpy(str+2, str);printf("%s\n", str);return 0;} 你定义的是str[7] = "aabbcc", str[6]的值并不会是'\0', 但……
我要问的是结果怎么来的 我知道溢出了 将str声明为12也是一样的结果
newtee 2012-11-18
  • 打赏
  • 举报
回复
firendlys 2012-11-18
  • 打赏
  • 举报
回复
貌似,strcpy是有几个版本的,其中一个是ls说的情况,另外一个是经过优化的版本. 这个优化的版本的复制不再是一个字节一个字节地复制,而是4个字节4个字节地复制..(因为32位系统的字长是4个字节,所以,4个字节4个字节复制的话,效率可以提高3倍...) 具体代码我就忘了,可以自己百度,参考 memcpy的优化版本 即可. (具体网址我一时之间也找不到...找到之后再附上吧..) 如果是4个字节4个字节复制的话: 准备复制的数据 目标位置数据 最终字符串 原始: aabbcc 第一次: [0-3] aabb [2-5] bbcc aaaabb 第二次: [4-8] bb\0\0 [6-9] \0\0\0\0 aaaabbbb\0\0 所以,结果就是 aaaabbbb 了...
newtee 2012-11-18
  • 打赏
  • 举报
回复
画内存图吧! TC输出结果不一样 可以用内存图解释
我再用VS试下
breakfisher 2012-11-18
  • 打赏
  • 举报
回复
感觉刚刚的回复没说清楚: 你定义的是str[7] = "aabbcc", str[6]的值是'\0', 但是你在strcpy的时候,很明显str+2在复制时会溢出,你定义的是char型数组,所以系统并不会检查你的溢出,而是按顺序将str的值赋给str+2, 所以str+2的值会是"aabbcc", 所以我觉得printf(str)时,其值应该是"aaaabbcc", 而printf(str+2)的值是"aabbcc"
breakfisher 2012-11-18
  • 打赏
  • 举报
回复
上面有个错误"str[6]的值并不会是'\0'", str[6]的值是'\0'
linxren 2012-11-18
  • 打赏
  • 举报
回复
这代码写得就有问题。没这么用的。 char str[7] = "aabbcc"; strcpy(str+2, str); <- 空间才7, 拷过去越界了 printf("%s\n", str); return 0;
breakfisher 2012-11-18
  • 打赏
  • 举报
回复
#include<stdio.h>
#include <string.h>

int main()
{
char str[7] = "aabbcc";
strcpy(str+2, str);
printf("%s\n", str);
return 0;
}
你定义的是str[7] = "aabbcc", str[6]的值并不会是'\0', 但是你在strcpy的时候,很明显str+2在复制时会溢出,因此str+2的值会是"aabbcc", 所以我觉得printf(str)时,其值应该是"aaaabbcc", 而printf(str+2)的值是"aabbcc"
wudaijun 2012-11-18
  • 打赏
  • 举报
回复
引用 1 楼 zhuankeshumo 的回复:
C/C++ code?1234567char * strcpy( char *strDest, const char *strSrc ){ assert( (strDest != NULL) && (strSrc != NULL) ); char *address = strDest; while( (*strDest++ = * strSrc++) !=……
这我知道 但是不能解释这个输出
newtee 2012-11-18
  • 打赏
  • 举报
回复
char * strcpy( char *strDest, const char *strSrc )
{
 assert( (strDest != NULL) && (strSrc != NULL) );
 char *address = strDest;
 while( (*strDest++ = * strSrc++) != ‘\0’ );
  return address;
}
c++面试题53个问题 1.C++的三大特性 2.C和C++的区别 3.全局变量和局部变量在内存分配上有何不同 4.static的作用 5.const解释其作用 6.指针和引用的区别 7.智能指针 8.简述深拷贝和浅拷贝的区别 9.编写my_strcpy函数,实现与库函数strcpy类似的功能,不能使用任何库函数 10.请讲述堆和栈的区别 11.全局变量和局部变量有什么区别?实怎么实现的?操作系统和编译器是怎么知道的 12.new、delete、malloc、free之间的关系 13. 头文件种的ifndef/define/endif 是干什么用的 14.TCP和UDP有什么区别 15.STL库用过吗?常见的STL容器有哪些?算法用过哪几个 16.同步IO和异步IO的区别 17.说下你对内存的了解 18.C++文件编译与执行的四个阶段 19.extern关键字的作用 20.#define和const的区别 21.结构体struct和共同体union(联合)的区别 22.C++中vector和list的区别 23.结构体和类的区别 24.STL中map和set的原理(关联式容器) 25.MFC的消息机制 26.消息映射 27.列举几种进程的同步机制,并比较其优缺点 28.数组和链表的区别 29.MFC主要要用到哪几个类?及其各个类的作用 30.MFC六大核心机制 31.OnDraw和OnPaint 32.win32程序的消息响应机制是如何实现的 33.MFC中的消息响应机制是如何实现的 34.WM_COMMAND命令消息处理顺序 35.MFC序列化的概念 36.PeekMessage和GetMessage的主要区别 37.WIN32创建窗口程序基本函数 38.Windows中的系统消息循环占用CPU的疑问 39.队列消息与非队列消息 40.GDI对象绘图步骤 41.设备上下文DC 42.GDI位图绘制步骤 43.当模态对话框点开后,主窗口还能响应处理消息吗 44.MFC的消息分类 45.CListCtrl 虚拟列表技术 46.虚函数是怎么实现的 47.什么是内存泄漏?面对内存泄漏和指针越界,你有哪些方法? 48.变量的声明和定义有什么区别 49.sizeof是一个操作符,strlen是库函数 50.写一个“标准”宏MIN 51.简述strcpy sprintf与mencpy的区别 52.链表与数组的区别 53.简述队列和栈的异同

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧