这可能是一个愚蠢的问题。玩弄C++,发现这行代码让我有点懵
char buffer[7] = {'0', '1', '0', '9', '0', '1'};
// It prints 010901
printf("%s", buffer);
// It prints 0901
printf("%s", buffer+2);
为什么我们可以(+ 2)缓冲区变量,它就像向右移动了 2 个字符?
在这样的上下文中,数组名称buffer
“降级”为只是指向第一个值的指针。由于 C 和 C++ 支持指针运算,并且字符串被表示为指向字符数组的指针,这很好。
请注意终止'\0'
字符,这是隐含的,因为您指定的大小比您提供的初始化数据大。
不过,您的代码可以简化为:
const char buffer[] = "010901";
您可以像这样可视化它:
+-----+-----+-----+-----+-----+-----+-----+
buffer ------> | '0' | '1' | '0' | '9' | '0' | '1' | '\0 |
+-----+-----+-----+-----+-----+-----+-----+
^
|
|
buffer + 2
数组类型的表达式经常进行数组到指针的转换。基本上,buffer
这里的名称可以转换为指向其第一个元素的指针。这就是在这两种情况下发生的情况。该数组被转换为 achar*
然后printf
将其解释为指向 C 样式字符串中的第一个字符。
在第二种情况下,在转换为指针之后,您将该指针加 2。这为您提供了指向第三个元素的指针。printf
再次将其视为 C 样式字符串,但从您创建的数组的第三个字符开始。
起初我以为你的字符串不是以空结尾的有问题。但是,您的代码没问题,因为数组的大小为 7,并且最后一个元素将设置为 0,因为您没有为其指定初始化程序。然而,这令人困惑。我建议你改为这样声明你的数组:
char buffer[] = "010901";
你需要终止那个字符串,兄弟!
char buffer[7] = {'0', '1', '0', '9', '0', '1', '\0'};
// It prints 010901
printf("%s", buffer);
// It prints 0901
printf("%s", buffer+2);
C++ 定义了一个隐式的数组到指针的转换;也就是说,数组可以隐式转换为指向其第一个元素(索引为 0 的元素)的指针。这意味着您的代码基本上是这样解释的:
printf("%s", (&buffer[0]) + 2);
char buffer[7] = {'0', '1', '0', '9', '0', '1' , '\0'};
C中的数组名基本上也是指向数组位置的指针
buffer[i]
被翻译为*(buffer+i)
即添加i
到指针值[跟随指针算术]。因此,它给出了该位置的地址。
printf
将打印 a%s
直到遇到 a \n
。因此,输出。
检查这个以了解指针和数组