13

カーニハンとリッチーのThe C Programming Languageの配列とポインターに関する章を読んでいます。

彼らは例を挙げます:

/* strlen:  return length of string s */
int strlen(char *s)
{
    int n;

    for (n = 0; *s != '\0'; s++)
        n++;
    return n;
}

そして次のように言います。

はポインタであるためs、インクリメントは完全に合法です。s++を呼び出した関数内の文字列には何の影響も与えませんstrlenが、ポインタの strlen のプライベート コピーをインクリメントするだけです。つまり、次のように呼び出します

strlen("hello, world");  /* string constant */
strlen(array);           /* char array[100]; */
strlen(ptr);             /* char *ptr; */

すべてうまくいきます。」</p>

最初の呼び出しの例を除いて、これらすべてを理解しているように感じます: なぜ、またはどのように、文字列リテラル"hello, world"char *s? これはどのようにポインターですか?関数はこの文字列リテラルをローカル変数の値として割り当て、配列名/ポインタとして*s使用しますか?s

4

6 に答える 6

15

「HelloWorld」のような文字列がどのようにポインタに変換されるかを理解するには、文字列が実際にはアドレスから始まり、NULL

つまり、「Hello World」などのすべての文字列定数は、メモリのどこかに格納されます。

可能性は次のとおりです。

0x10203040 : 0x48 [H]
0x10203041 : 0x65 [e]
0x10203042 : 0x6C [l]
0x10203043 : 0x6C [l]
0x10203044 : 0x6F [o]
0x10203045 : 0x20 [' ']
0x10203046 : 0x57 [W]
0x10203047 : 0x6F [o]
0x10203048 : 0x72 [r]
0x10203049 : 0x6C [l]
0x1020304A : 0x64 [d]
0x1020304B : 0x00 [\0]

したがって、メモリ内の上記の値を使用してこの関数を呼び出すと、[左側はアドレスの後に':'が続き、右側は文字のASCII値です]

int strlen(const char *s)
{
    int n;

    for (n = 0; *s != ′\0′; s++)
        n++;
    return n;
}

strlen("Hello World");

そのとき、渡されるのは文字配列の最初の要素のアドレスであるstrlen値です。0x10203040

アドレスは値で渡されることに注意してください。したがって、strlen「HelloWorld」のアドレスの独自のコピーがあります。から始まり、メモリ内でn = 0見つかるまで、インクリメントします。また、アドレスを見つけて文字列の長さを返すまで、 (次にインクリメントされます)というようにインクリメントします。\0ns0x10203041\00x1020304B

于 2013-01-21T19:38:37.127 に答える
3

"hello, world"

char(型は)の配列ですchar[13]char式内の の配列の値は、へのポインタcharです。"hello, world"ポインターは、配列の最初の要素 (つまり、 isの値) を指します&"hello, world"[0]

于 2013-01-21T19:24:40.107 に答える
1

ご了承ください:

  • ポインタは(基本的に)メモリアドレスを指す値です。
  • のような静的文字列"hello, word"がメモリのどこかに保存されます

したがって、ポインターは、メモリに格納されている他の (動的な) 構造 (文字の配列など) を指すのと同じくらい簡単に静的文字列を指すことができます。提供されている他の例と実際に違いはありません。

于 2013-01-21T19:25:59.960 に答える
1

関数は、この文字列リテラルをローカル変数 *s の値として割り当て、s を配列名/ポインタとして使用しますか?

はい

于 2013-01-21T19:27:37.477 に答える