1

私はこの質問に出くわしました:

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

の意味を説明できる人はい&str+2ますか? これはどのように作動しますか?

4

4 に答える 4

5

&str型のポインタを返しますchar (*)[25]。つまり、このポインタが指すメモリのサイズはsizeof(str)、つまり 25 になります。通常のポインタ演算では、この値に 2 を加算すると、配列char (*)[25]の末尾から 25 バイト先を指すタイプのポインタになります。strそれを印刷することは、おそらく未定義の動作です。

于 2012-11-30T18:33:32.330 に答える
4

str型が「25文字の配列」の式です。ほとんどの場合、配列は最初の要素へのポインターに自動的に変換されます。したがって、 instr+2は配列strの最初のポインタに変換され、char2 を加算すると、結果はchar配列の 3 番目のポインタになります。

ただし、C 2011 6.3.2.1 3 によると、配列型の式が単項演算子sizeof,のオペランドである場合、または配列の初期化に使用される文字列リテラルである場合、この自動変換は行われません。したがって、 inはポインターに変換されません。25 文字の配列のままです。次に、25 文字の配列へのポインターです。これに 2 を加算すると、概念的には、結果は 25 文字の配列の配列の 3 番目の要素へのポインターになります。_Alignof&&str+2str&str

ただし、ポインター演算は、配列の末尾にある架空の要素まで、配列内でのみ定義されます。(さらに、ポインター演算の目的で、単一のオブジェクトは 1 つの要素を持つ配列として扱われます。) 25 文字の配列の配列ではなく、25 文字の配列が 1 つしかないため、ポイントする 3 番目の要素はありません。であり、&str+2未定義です。

于 2012-11-30T18:52:01.467 に答える
1

まず第一に、あなたがそこで行っていることは、せいぜい未定義の動作になります。

str文字列が始まるスタック上のメモリアドレスに関連するシンボルです。&strはスタック シンボルでは無効であり、これを使用すると未定義の動作が発生します。おそらく必要なのはstr + 2、これが文字列の 3 番目のバイトへのポインタであることです。

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

印刷します"tch me, if u can!\n"

于 2012-11-30T18:36:08.447 に答える
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);

0xbfa7fc13、が表示されます0xbfa7fc13。配列はそのアドレスから始まるため、同じ値です。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);

文字列をもう少し下にダンプします。ただし、 のアドレスに 2 を追加すると、追加するstrもののサイズによって自動的に * それが行われます。

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

ご覧のとおり、アドレスは配列がスタック上にある場所をはるかに超えているため、次のように出力します。

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

'\0'運が良ければ、a が見つかるまで、配列を 50 バイト過ぎたゴミを吐き出します。これは未定義の動作なので、ほとんど何でもできます。

于 2012-11-30T19:11:39.293 に答える