2

这可能是一个愚蠢的问题。玩弄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 个字符?

4

5 回答 5

6

在这样的上下文中,数组名称buffer“降级”为只是指向第一个值的指针。由于 C 和 C++ 支持指针运算,并且字符串被表示为指向字符数组的指针,这很好。

请注意终止'\0'字符,这是隐含的,因为您指定的大小比您提供的初始化数据大。

不过,您的代码可以简化为:

const char buffer[] = "010901";

您可以像这样可视化它:

               +-----+-----+-----+-----+-----+-----+-----+
buffer ------> | '0' | '1' | '0' | '9' | '0' | '1' | '\0 |
               +-----+-----+-----+-----+-----+-----+-----+
                              ^
                              |
                              |
                         buffer + 2
于 2013-04-18T11:57:20.330 回答
1

数组类型的表达式经常进行数组到指针的转换。基本上,buffer这里的名称可以转换为指向其第一个元素的指针。这就是在这两种情况下发生的情况。该数组被转换为 achar*然后printf将其解释为指向 C 样式字符串中的第一个字符。

在第二种情况下,在转换为指针之后,您将该指针加 2。这为您提供了指向第三个元素的指针。printf再次将其视为 C 样式字符串,但从您创建的数组的第三个字符开始。

起初我以为你的字符串不是以空结尾的有问题。但是,您的代码没问题,因为数组的大小为 7,并且最后一个元素将设置为 0,因为您没有为其指定初始化程序。然而,这令人困惑。我建议你改为这样声明你的数组:

char buffer[] = "010901";
于 2013-04-18T11:57:56.010 回答
0

你需要终止那个字符串,兄弟!

char buffer[7] = {'0', '1', '0', '9', '0', '1', '\0'};

// It prints 010901
printf("%s", buffer);

// It prints 0901
printf("%s", buffer+2);
于 2013-04-18T12:01:46.227 回答
0

C++ 定义了一个隐式的数组到指针的转换;也就是说,数组可以隐式转换为指向其第一个元素(索引为 0 的元素)的指针。这意味着您的代码基本上是这样解释的:

printf("%s", (&buffer[0]) + 2);
于 2013-04-18T11:58:18.060 回答
0
char buffer[7] = {'0', '1', '0', '9', '0', '1' , '\0'};

C中的数组名基本上也是指向数组位置的指针

buffer[i]被翻译为*(buffer+i)即添加i到指针值[跟随指针算术]。因此,它给出了该位置的地址。 printf将打印 a%s直到遇到 a \n。因此,输出。

检查这个以了解指针和数组

于 2013-04-18T12:00:21.583 回答