3

Cで文字列の配列を試しています。文字列の辞書配列があり、それに単語を追加してから配列を出力して、それが機能するかどうかを確認します。私が思うように、出力は機能し、配列内の単語を出力します。しかし、修正できない警告が多数表示されます。

// 20 word dictionary
#define ROWS 20
#define WORD_LENGTH 10

char dictionary[ROWS][WORD_LENGTH];

void add_word(char **dict, int index, char *word) {
    dict[index] = word;
}

char *get_word(char **dict, int index) {
    return dict[index];
}

void print_dictionary(char **dict) {
    int i;
    for (i = 0; i < 20; i++) {
        printf("%d: %s\n", i, get_word(dict, i));
    }
}

void test_dictionary() {
    add_word(dictionary, 0, "lorem");
    add_word(dictionary, 1, "ipsum");

    print_dictionary(dictionary);
}

int main() {
    test_dictionary();
}

これをコンパイルした結果は、

p5.c: In function ‘test_dictionary’:
p5.c:54:2: warning: passing argument 1 of ‘add_word’ from incompatible pointer type [enabled by default]
p5.c:38:6: note: expected ‘char **’ but argument is of type ‘char (*)[10]’
p5.c:55:2: warning: passing argument 1 of ‘add_word’ from incompatible pointer type [enabled by default]
p5.c:38:6: note: expected ‘char **’ but argument is of type ‘char (*)[10]’
p5.c:57:2: warning: passing argument 1 of ‘print_dictionary’ from incompatible pointer type [enabled by default]
p5.c:46:6: note: expected ‘char **’ but argument is of type ‘char (*)[10]’

**dict を dict[ROWS][WORD_LENGTH] に変更してみましたが、大きな違いはありませんでした。この辞書パラメータを宣言する方法を説明してください。ありがとう。

編集: 私のコンパイラ フラグは、CFLAGS = -Wall -g です。

Edit2: 宣言を次のように変更しました。

void add_word(char dict[][WORD_LENGTH], int index, char *word) {
    dict[index] = word;
}

char *get_word(char dict[][WORD_LENGTH], int index) {
    return dict[index];
}

void print_dictionary(char dict[][WORD_LENGTH]) {
    int i;
    for (i = 0; i < 20; i++) {
        printf("%d: %s\n", i, get_word(dict, i));
    }
}

これにより、コンパイルエラーが発生します。

p5.c: In function ‘add_word’:
p5.c:42:14: error: incompatible types when assigning to type ‘char[10]’ from type ‘char *’
make[1]: *** [p5] Error 1

いつもお世話になっております。

ああ!理解した!。これはポインターなので、@Jack の提案に従って strcpy を使用する必要があります。

void add_word(char dict[][WORD_LENGTH], int index, char *word) {
    /*dict[index] = word;*/
    strcpy(dict[index], word);
}

みんな、ありがとう!

4

4 に答える 4

6

根本的な原因:

配列はポインタではありません!

dict[][]からへの暗黙の変換がないdict **ため、エラーが発生することに注意してください。配列を関数に渡すと、最初の要素へのポインターとして減衰します.2次元配列の場合、最初の要素は1次元自体の配列であるため、二重ポインターではなく、配列へのポインターが必要です。

ソウルション:

渡すタイプに一致するように関数プロトタイプを変更する必要があります。

void add_word(char dict[][WORD_LENGTH], int index, char *word);
void print_dictionary(char dict[][WORD_LENGTH]);
于 2012-09-12T08:57:21.883 に答える
2

実際には、ポインターをポインターに渡すのではなく、配列の配列を渡します。違いは、メモリが既に割り当てられており、add_word() で代入演算子「=」を使用できないことです。

正しい署名は

void add_word(char dict[][WORD_LENGTH], int index, char *word)

strcpy や strncpy などのメソッドを使用する必要があります

于 2012-09-12T08:59:26.717 に答える
1

内部配列を逆参照するときに、内部配列のサイズを指定する必要があります。したがって、代わりに:

void add_word(char **dict, int index, char *word)

必要なもの:

void add_word(char dict[][WORD_LENGTH], int index, char *word)

についても同様ですprint_dictionary

主な混乱は、char配列の配列が charポインターの配列と同じではないことです。

于 2012-09-12T08:58:54.840 に答える
1

ええ、あなたのタイプは完全にオフです。

「変更の最小数」の修正は、1 行を置き換えるだけです。

char* dictionary[ROWS];

基本的に、次のようにレイアウトされたメモリブロックを作成しました

c1  c2  c3  c4  ... c20
c21 c22 c23 c24 ... c40
c41 c42 ...
...

ただし、メモリブロックのように使用しました

charpointer1
charpointer2
charpointer3
...

それは機能しているように見え、実際に割り当てられたメモリブロックはとにかく大きかったので、何も悪いことが起こらなかったという意味で「安全」でさえありました。

編集:「辞書」を直接使用しようとしたことがある場合、コードは「爆発」します。たとえば、"dictionary[n]" にアクセスして n 番目の単語を取得すると、間違った結果が得られます。

于 2012-09-12T09:01:15.123 に答える