c语言左旋字符串里面的问题

问题遇到的现象和发生背景

一下两种左旋字符串,为什么结果不一样?

问题相关代码,请勿粘贴截图
void leftmove(char arr[], int k)
{
    int i = 0;
    int len = strlen(arr);
    for (i = 0; i < k; i++)    
    {
        char* tmp = arr;    
        int j = 0;
        for (j = 0; j < len - 1; j++)
        {
            arr[j] = arr[j+1];
        }
        arr[len-1] = *tmp;
    }
}
int main()
{
    char arr[] = "abcdef";
    leftmove(arr, 2);
    printf("%s", arr);

    return 0;
}

void leftmove(char arr[], int k)
{
    int i = 0;
    int len = strlen(arr);
    for (i = 0; i < k; i++)    
    {
        char tmp = arr[0];
        int j = 0;
        for (j = 0; j < len - 1; j++)
        {
            arr[j] = arr[j+1];
        }
        arr[len-1] = tmp;
    }
}
int main()
{
    char arr[] = "abcdef";
    leftmove(arr, 2);
    printf("%s", arr);

    return 0;
}

运行结果及报错内容

第一个结果是cdefbc
第二个结果是cdefab(这个是正确的)

输出一下*tmp你就知道了,你指向的是数组内存地址,数组值变了,地址指向的值不就变了吗

第一份代码,把字符数组最后一个元素赋为tmp指针当时指向的字符,即每次循环移动数组元素前的数组的当时的首元素,执行k次,即指向数组的前k个元素,而当循环结束,数组的当时的首元素因为移动操作,发生了变化,变为了cd,所以移动操作完成后,数组最右边k个的值就跟着移动操作后前k个元素的值的变化而发生变化,因为arr[len-1] 赋值为*tmp的原因,所以他的结果就不准确了。

而第二份代码,是把数组最后一个元素赋值为每次循环移动数组元素前的数组当时的首元素的值,执行k次,就把数组前k个元素移动到了数组右边,所以循环结束,数组里的值还是移动操作后的值,所以他是正确的。