如何把char字符串循环右移N位

C语言实现:输入一个字符串,将其循环右移N位。


1.利用strcpy()函数实现:


如何把char字符串循环右移N位_第1张图片

即将输入pStr的后N位放入temp的前N位,再将pStr所有(到‘\o’结束)放入temp的后面。

假如pStr="12345678",N(nbits)=3,则这时候,temp=“67812345678”,

所以再把temp后面多余部分截掉,最后复制回pStr即完成。


2.利用memcpy()函数实现:


如何把char字符串循环右移N位_第2张图片

这是在网上看到的另外一种思路。

第一步还是同样将pStr的后N位放入temp的前N位,

但是后面的代码就让人看不懂了。。

第二步它的目的是将pStr的前面部分(length-N)后移N位,就是直接把pStr的前面N个位置“让”出来。但是————

可以这样做?不是有重叠部分吗?拷贝到第N位后会出错吧?还没拷贝出去就被覆盖了呀?


带着这样的疑问,在我的Windows电脑上测试运行:

(方法1和方法2对比结果)

如何把char字符串循环右移N位_第3张图片

运行结果:

如何把char字符串循环右移N位_第4张图片


居然是一样的!!!也就是说方法2也是正确的。不敢相信我的眼睛。。。。。。


为什么会这样?

查阅了memcpy()的实现:


不同操作系统下对memcpy()的实现有所差别。


Windows实现:

void * __cdecl memcpy (

        void * dst,
        const void * src,
        size_t count
        )
{
        void * ret = dst;

#if defined (_M_IA64)//64位
        {
        extern void RtlMoveMemory( void *, const void *, size_t count );

        RtlMoveMemory( dst, src, count );
        }
#else 
       
        while (count--) {
                *(char *)dst = *(char *)src;
                dst = (char *)dst 1;
                src = (char *)src 1;
        }
#endif 

        return(ret);
}


而Linux实现:

void *memcpy(void *dest, const void *src, size_t count)
{
 char *tmp = dest;
 const char *s = src;

 while (count--)
  *tmp = *s ;
 return dest;
}


所以在我自己的Windows_64bits系统,是调用RtlMoveMemory( void *, const void *, size_t count )实现。


再查到RtlMoveMemory函数是支持重叠复制的,那么当然memcpy()也支持重叠复制

这让人想起memcpy()的“兄弟”memmove(),它是支持重叠复制的。


所以得出结论:

       在Linux和Win32环境下,用memcpy()实现的方法2是错误的。

      而只有, 在Win64环境下正确。


下面是在Linux下的对memcpy()的验证:

如何把char字符串循环右移N位_第5张图片

方法2的结果错误

如何把char字符串循环右移N位_第6张图片


最后:慎用memcpy()!!!注意检查是否有重叠!





你可能感兴趣的:(如何把char字符串循环右移N位)