理解C指针

时间:2017-01-16 21:17:32

标签: c pointers

#include <stdio.h>
#include <string.h>

int main(){


// char* is a pointer
    char str_a[20];
    char *pointer;
    char *pointer2;

    strcpy(str_a, "Hello, world\n");
    pointer = str_a;
    printf(pointer);

    pointer2 = pointer + 2;
    printf(pointer2);
    strcpy(pointer2, "y you guys!\n");
    printf(pointer);
}

嗨,我正在读一本书并且遇到了一个程序,解释了我无法理解的指针。这本书似乎没有提到为什么会这样,这意味着我必须在其他地方进行咨询以获得更好的理解。上面的代码生成以下输出:

Hello, world! (pointer)
llo, world!   (pointer2)
Hey you guys! (pointer)

我无法理解的是变量pointer的最后一次更改是在第8行。但是pointer的值可以清楚地看到在最后一行输出中发生变化。

我希望第二行输出中pointer2的值为He而不是llo, world!。我唯一能想到的是 - 在第14行,当指定+ 2时,指针的前两个字节被斩波(或者其余字节被截断,前两个字节在{{1}中保持不变}}?)

但情况并非如此 - 因为当我在pointer下方添加printf(pointer)时 - 输出为“Hello,world!”再次而不是“他”

4 个答案:

答案 0 :(得分:2)

首先,指针 pointer2 未被声明为指针,应该有一个&#39; *&#39;在那些变量之前将它们声明为指针。即使这是出自本书,这也是不正确的。

  

我无法理解的是变量的最后一次更改   指针在第8行。但指针的值可以清楚地看到   改变最后一行产出。

是的!这是指针的重点! pointer2 指针具有相同的地址,但加上2个元素(记住数组变量包含该数组的第一个变量的地址),如&#34;中指定的那样; pointer2 =指针+ 2;&#34;因此,&#34; strcpy(指针2,&#34;你们!\ n&#34;);&#34;说明将开始复制之后&#34; He&#34;因为 pointer2 指向第一个&#39; l&#39;。

答案 1 :(得分:1)

现在,c中的字符串是零字节(\0)终止,因此当您将str_a分配给pointer并打印pointer时,打印机将从第一个开始地址pointer指向终止\0,因此会打印所有文字。

但是,在pointer2分配pointer加上2的值时,您可以在pointer点之后指向两个地址,并在打印时从l开始Hello的{​​{1}},直到终止\0

对于第三个,你用pointer2"y you guys!\n"替换内存中的内容,所以从两个地址(其中pointer点)开始的总字符串将是是"Hey you guys!\n",导致你得到的结果。

H e       l l o ,  w o r l d \n      // start from pointer
^ pointer

H e       l l o ,  w o r l d \n      // start from pointer2
^ pointer ^ pointer2

H e       y   y o u   g u y s ! \n   // start from pointer
^ pointer ^ pointer2

答案 2 :(得分:1)

pointerpointer2基本上指向同一块内存。也就是说,初始状态是这样的:

p     p2
H  e  l  l  o  ,  w  o  r  l  d  \n  \0 

然后你覆盖p2下的块,它变为:

p     p2
H  e  y   y  o  u    g u y s \n \0

希望这些图表有意义。当您打印出指针时,它将始终到达数组的末尾,即\0

答案 3 :(得分:0)

在C中,指向字符串(或任何内容)的指针指向字符串的 start ,而不是结尾。

对于字符串,结尾由空('\0')字符的存在标识。

所以,如果你有一个指向字符串的指针,比如*p指向"Hello",这就是字符串在内存中的布局方式:

&lt; * p指向1000&gt;

| 1000 | 1001 | 1002 | 1003 | 1004 | 1005 |
   H       e      l      l     o      \0   

现在,如果您向p添加2,p现在指向1002:

| 1002 | 1003 | 1004 | 1005 |
    l      l     o      \0   

所以,很明显,访问p作为字符串指针会给你&#34; llo&#34;。如果您想提前生成字符串 end ,则应将目标字符设置为'\0'

char mystr[10] = "Hello";
char *p = mystr;
*(p+2)='\0';

天啊,你甚至不需要指针来做那件事。你可以mystr[2] = '\0';