web-dev-qa-db-ja.com

Cのポインターへの文字列の割り当て

私の質問はCのポインターについてです。私が学習して検索した限り、ポインターは他の変数のアドレスのみを格納できますが、実際の値(整数や文字など)を格納できません。しかし、以下のコードでは、charポインタcが実際に文字列を格納しています。エラーなしで実行され、「名前」として出力されます。

#include <stdio.h>
main()
{
  char *c;
  c="name";
  puts(c);
}

誰かがメモリなしでポインタが文字列をどのように格納しているのか、それが作成された場所にメモリが作成されているのか、それがどのくらいのサイズで作成できるのか誰でも説明できますか?

整数型ポインタで使ってみた

#include <stdio.h>
main()
{
  int *c;
  c=10;
  printf("%d",c);
}

エラーが発生しました

cc     test.c   -o test
test.c: In function ‘main’:
test.c:5:3: warning: assignment makes pointer from integer without a cast   [enabled by default]
c=10;
^
test.c:6:2: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("%d",c);
^

ポインタは変数のアドレスを格納しますが、なぜ整数ポインタが文字ポインタと異なるのですか?

何か足りないものはありますか?

3
Sudheer

これは、Cでの文字列リテラルの動作方法です。"name"のような文字列リテラルは、文字の配列であり、5つの要素の配列{'n', 'a', 'm', 'e', '\0'}と同等です。コードについて

char *c;
c="name";

プログラムがディスクからメモリに読み込まれるとき、環境は初期化時にすでに上記の配列のメモリを予約します。実行時に、その配列の先頭のアドレスがcに割り当てられます。

最初の部分ではstring literal( 'のような文字ではない)を割り当てるので、最初の部分は2番目の部分と同じではないことに注意してくださいn ')をchar*変数に。 2番目では、int arrayintint*ではなく)を割り当てようとします。

ここに、Cの文字列とポインタに関するチュートリアルと詳細な説明があります

11
Doc Brown

"name"のような文字列リテラルは、char(C++ではconst char)の配列として格納され、プログラムの起動時に割り当てられ、プログラムが終了するまで保持されます。

"name"typeは、「charの5要素配列」(0ターミネーターの5番目の要素)です。 sizeof演算子または単項*演算子のオペランドである場合、または宣言内の配列を初期化するために使用される文字列リテラルである場合を除き、「N要素配列T "は、タイプ" pointer to T "の式に変換(「減衰」)され、式の値は配列の最初の要素のアドレスになります。

だから、あなたが書くとき

c="name";

"name"sizeofまたは単項*演算子のオペランドではなく、宣言で配列を初期化するために使用されていないため、文字列の最初の要素のアドレスがポインタ変数cに割り当てられています。基本的に、メモリにあるのは次のようなものです。

            +-----+
"name"[0] : | 'n' |  <-------+
            +-----+          |
"name"[1] : | 'a' |          |
            +-----+          |
"name"[2] : | 'm' |          |
            +-----+          |
"name"[3] : | 'e' |          |
            +-----+          |
"name"[4] : |  0  |          |
            +-----+          |
              ...            |
            +-----+          |
        c : |     | ---------+
            +-----+
3
John Bode