9

次のコード行について混乱しています。

char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };

私が理解している方法では、各単語が最初に格納され、次に配列の各位置がwords各単語の最初の文字を指します。これらの文字列はどのように保存されますか? ここで動的割り当てが行われていますか、それともこれらの単語がスタックに格納されていますか?

それらがスタックに格納される場合、それらはどのように格納されますか? たとえば、次のようにコンテンツの一部を印刷するとwordsします。

#include <stdio.h>
int main () {
    char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };
    printf("\n\n(*words)[0] = %s", words[0]);
    printf("\n\n(*words)[0]+1 = %s", words[0]+1);
    return 0;
}

aaaandを印刷する代わりにbbbb、私が得るのはaaaandaaです。私が見る方法では、 の 2 番目の文字ではなくwords[0]+1、文字列を指す必要があるため、この理由が何であるかはよくわかりません。ここで何が起こっているのですか?bbbbaaa

4

8 に答える 8

15

これはまるで..

ここに画像の説明を入力

単語はポインターの文字の配列であるため、単語の各配列インデックスは文字列リテラルのアドレス、つまり文字列リテラルのベースアドレスを保持します。

 printf("%s",words[0])// index 0 will print aaa.
于 2012-09-01T04:29:00.857 に答える
6

違いは とwords[0]+1同じではないためですwords[0+1]

前者は の 2 番目の文字をwords[0]指し、後者は 2 番目の単語を指します。

于 2012-08-31T22:05:38.817 に答える
3

words[0] は、「aaa」の最初の「a」を指します。

words[0]+1 は、そのポインターを 1 文字分移動するため、2 番目の 'a' を指すようになります。

words[1] は「bbbb」を指す

words[1]+1 ポイント "bbb"、たとえば "bbbb" の 2 番目の 'b'。

于 2012-08-31T22:05:15.323 に答える
2

私の見方では、words[0]+1 は aaa の 2 番目の文字ではなく、文字列 bbbb を指す必要があります。

No.words[0]は char ポインターそのものです。"aaa" の 2 番目の文字に 1 を追加して取得してもまったく問題ありません。あなたが望むのはwords + 1、または&words[0] + 1正しく「bbbb」になるものです。

また、文字列自体は実行可能ファイルの起動時に割り当てられ、おそらくリンカーによってバイナリの data または bss セクションに配置されます。また、 を宣言して初期化するとwords、他の自動配列と同様にスタックに割り当てられ、その項目は各文字列定数の先頭へのポインターに割り当てられます。

于 2012-08-31T22:05:59.310 に答える
1

スタック スペースとヒープ スペースはどちらも動的に割り当てられます。つまり、実行時に割り当てられます。コンパイルされたコードは、ヒープまたはスタックに動的に割り当てられていますか? 明らかにどちらでもありません。定数のストレージは、コードのストレージに似ています...それらはディスク上の実行可能ファイルに保存され、読み取り専用メモリにロードされます。(衒学者への注意: これは典型的な実装で行われる方法であり、言語標準によって義務付けられているわけではありません。)

words[0]「aaaa」の最初の「a」のアドレスです。そのアドレスに 1 を加えると、きっと「aaaa」の 2 番目の「a」のアドレスになるはずです。「bbbb」のアドレスはwords[1].

printf の形式には「(*words)[0]」がありますが、それは異なります。*wordsと同じwords[0]です。は、 「aaaa」の最初の「a」(アドレスではない) と(*words)[0]同じです。ではなくで**words印刷(*words)[0]します。%c%s

于 2012-08-31T22:29:41.250 に答える
1

リテラル文字列は静的メモリに格納されます。それらの実際の場所は実装に依存しますが、リテラル文字列は通常、実行可能ファイルのデータ部分のどこかに保存されます - これは動的でもスタック割り当てでもありません。配列には、これらの場所へのポインターが含まれます。

words[0]+1 は、aaa の 2 番目の文字ではなく、文字列 bbbb を指す必要があります。

これは、配列のインデックス付けの仕組みではありません。を使用して文字列の配列にインデックスwords[0]を付けると、文字列が作成され、すべての操作がその文字列に適用されます。添え字の外側の配列インデックスで算術演算を行うことはできません。文字列に到達するには"bbbb"、 を使用しますwords[1]

于 2012-08-31T22:05:32.453 に答える
0

words[0] は aaa のアドレスを返します。これに 1 を追加すると、アドレスが 2 番目の a を指すようにインクリメントされます。

単語[0+1]ということですか?

それはあなたが期待しているものをあなたに与えるはずです。

于 2012-08-31T22:05:19.803 に答える
0
char* words[] = { "aaa", "bbbb", "ccccc", "dddddd" };

4 つの文字列はすべて静的ストレージ期間を持ち、プログラムの起動前に割り当てられます。

初期化子では、配列はへのポインターに変換されcharwords配列はポインター値で初期化されます。

于 2012-08-31T22:05:26.047 に答える