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[][]todict **的隐式转换,因此没有错误。当您将数组传递给函数时,它会衰减为指向其第一个元素的指针。在二维数组的情况下,第一个元素本身就是一个单维数组,因此您需要一个指向数组的指针而不是双指针。

灵魂:

您需要修改函数原型以匹配您传递的类型。

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

是的,你的类型完全关闭了。

“最小更改次数”修复只是替换一行:

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 回答