我准备了一个示例程序,将 char 数组的第二个元素移动到第一个位置,将第三个元素移动到第二个位置等。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
int main(void) {
char *str = (char *) malloc(10);
strcpy(str, "123456");
printf("%s\n", str); //123456
str++;
printf("%s\n", str); //23456
str++;
printf("%s\n", str); //3456
str++;
printf("%s\n", str); //456
std::cout << str[0]; //4
}
现在我想重复这个操作,但是用移位操作,但它并没有像我预期的那样真正起作用。
#include<iostream>
int main(void){
char tab[6] = {'1','2', '3', '4', '5', '6'};
char *p = tab;
for(int i = 0; i < 6; i++){
std::cout << tab[i]; //123456
}
std::cout << std::endl;
*p = *p << 8;
std::cout << tab[0] << std::endl; //0 '\0'
std::cout << tab[1] << std::endl; //2
std::cout << std::endl;
return 0;
}
如果数组名是指向第一个元素的指针,我希望对数组名的左移操作会指向数组的第二个元素,但事实并非如此。有什么想法可以用移位操作重复第一个指针操作吗?
最佳答案
If array name is a pointer to first element, I expect that left shift operation on array name would point at the second element of an array
表达式中的数组指示符被隐式地(除了极少数异常(exception))确实被转换为指向它们第一个元素的指针
因此在这个声明中
char *p = tab;
数组指示符 tab
被转换为指向其第一个元素的指针,第一个元素的地址被分配给指针 p
。
然而在这个表达式语句中
*p = *p << 8;
指针 p
指向的第一个字符 *p
的值实际上乘以等于 2 的 8 次方的值,即乘以 256 . 并将字符的值赋值给指针。
因此在此操作之后指针具有无效值,结果程序具有未定义的行为。
您需要的是将数组中从索引 1 开始的所有元素复制到索引 0 对应的位置。
同样在第一个程序中,您使用的是字符串,但在第二个程序中,数组不包含字符串。
如果您想左移包含字符串的字符数组的元素,则代码看起来就像在演示程序中显示的函数中实现的那样。
#include <iostream>
#include <cstring>
char * shift_left(char *s)
{
size_t n = std::strlen(s);
std::memmove(s, s + 1, n);
return s;
}
int main()
{
char s[] = "123456";
std::cout << s << std::endl;
for (size_t i = 0, n = std::strlen(s); i != n; i++ )
{
std::cout << shift_left( s ) << std::endl;
}
return 0;
}
程序输出为
123456
23456
3456
456
56
6
关于c++ - char数组的左移操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47491051/