字符串在C,& str

时间:2012-11-30 18:30:32

标签: c pointers

我遇到了这个问题:

#include<stdio.h>
int main()
{
 char str[25]="Catch me, if u can!";
 printf("%s\n",&str+2);
 return 0;
}

任何人都可以向我解释&str+2的含义吗?这是如何运作的?

4 个答案:

答案 0 :(得分:5)

&str返回类型为char (*)[25]的指针。这意味着,该指针指向的内存大小为sizeof(str),i。即25.根据正常的指针算法,向此值添加2将产生类型为char (*)[25]的指针,该指针将指向str数组末尾之后的25个字节。打印它很可能是未定义的行为。

答案 1 :(得分:4)

str是一个类型为“25 char”的表达式。在大多数情况下,数组会自动转换为指向其第一个元素的指针。因此,在str+2中,str被转换为指向数组中第一个char的指针,并且,当添加2时,结果是指向第三个char的指针在数组中。

但是,根据C 2011 6.3.2.1 3,当数组类型的表达式是sizeof_Alignof,一元&运算符的操作数时,或者是字符串文字用于初始化数组,不会发生此自动转换。因此,在&str+2中,str不会转换为指针;它仍然是25个字符的数组。然后&str是一个指向25个字符的数组的指针。当向它添加2时,结果是概念上指向25 char数组数组的第三个元素的指针。

但是,指针算法仅在数组内定义,直到数组末尾的虚构元素。 (另外,出于指针运算的目的,单个对象被视为具有一个元素的数组。)因为我们只有一个25个char的数组而不是25个char的数组,所以没有第三个要指向的元素,并且&str+2未定义。

答案 2 :(得分:1)

首先,你在那里做的事情最多会导致未定义的行为。

str是一个符号,它与堆栈中字符串开头的内存地址相关。 &str在堆栈符号上无效,使用该符号将导致未定义的行为。您可能想要的是str + 2,它是指向字符串中第3个字节的指针,因此

printf("%s\n",str+2);

将打印"tch me, if u can!\n"

答案 3 :(得分:0)

定义数组时:

char str[25] = "Catch me, if you can!";

你得到的是在堆栈上保留25个字节的间隔,并放入以下内容:

@Address                                                                @Address 
0xbfa7fc13                                                             0xbfa7fc2C
 |                                                                          | 
 V                                                                          V
[C][a][t][c][h][ ][m][e][,][ ][i][f][ ][y][o][u][ ][c][a][n][!][\0][\0][\0][\0]

查看str的地址:

printf("%#x, %#x\n", str, &str);

您将看到0xbfa7fc130xbfa7fc13。相同的值,因为数组从它的地址开始。当你向str添加2时,你将指向字符串的下方:

0xbfa7fc13 + 2 = 
    0xbfa7fc15
        |
        V
       [t][c][h][ ][m][e][,][ ][i][f][ ][y][o][u][ ][c][a][n][!][\0][\0][\0][\0]

所以打印:

printf("%s\n", str+2);

只是将字符串向下倾斜一点。但是,如果你在str的地址中添加2,那么它会自动地*为你提供你所添加的任何大小:

&str + 2 ==> &str + 2 * sizeof(str) ==> &str + 50 ==> 0xbfa7fc45

正如您所看到的那样,地址已经超出了数组在堆栈中的位置,因此打印:

printf("%s\n",&str+2);

如果幸运的话,只要吐出50个字节的数据,直到发现'\0'为止。它是未定义的行为,所以它几乎可以做任何事情。