C中字符串数组和函数的问题

C中字符串数组和函数的问题,c,arrays,function,c-strings,C,Arrays,Function,C Strings,我刚从C开始,我试图让一个由3个字符串组成的数组通过一个函数。但是,在该函数中,只剩下1个字符串,看起来甚至没有数组。我已经尝试了很多方法,但似乎无法解决它 #include <stdio.h> #define NUM_WORDS 3 #define MAX_WORD_SIZE 64 void printStrings(char words[]) { //But now 'words' looks like this: "one" for (int i = 0;

我刚从C开始,我试图让一个由3个字符串组成的数组通过一个函数。但是,在该函数中,只剩下1个字符串,看起来甚至没有数组。我已经尝试了很多方法,但似乎无法解决它

#include <stdio.h>
#define NUM_WORDS 3
#define MAX_WORD_SIZE 64

void printStrings(char words[])
{
    //But now 'words' looks like this: "one"  
    for (int i = 0; i < NUM_WORDS; ++i)
        printf("%s", words[i]);
}

void main()
{
    char words[NUM_WORDS][MAX_WORD_SIZE] = { "one", "two", "three" };
    //At this point the array 'words' looks like this:  
    //{ "one", "two", "three" }
    printStrings(words);
}
#包括
#定义NUM_单词3
#定义最大单词大小64
无效打印字符串(字符字[])
{
//但现在“文字”看起来像这样:“一”
for(int i=0;i
您在
main
中对
单词的声明是正确的,但是要将二维数组传递给函数,您需要在函数中声明它。您当前的
printWords
声明仅将其参数声明为一维字符数组,这解释了为什么它不能正常工作

正确声明的最低要求如下:

void printStrings(char words[][MAX_WORD_SIZE])
但是,在这种情况下,您可以选择这样做:

void printStrings(char words[NUM_WORDS][MAX_WORD_SIZE])
这样做的好处(也有缺点)是意味着对可以/应该交给印刷文字的内容有更大的限制。这有点类似于:

void function(char foo[])
它接受任意大小的字符数组

void function(char foo[FOO_SIZE])
这表明它期望的数组是
FOO_SIZE
,既不大也不小

请注意,您只能省略最外层(最左侧)维度,内部维度是必需的,因此编译器知道每个外部元素的最终大小。

您需要:

#include <stdio.h>
#define NUM_WORDS 3
#define MAX_WORD_SIZE 64

static void printStrings(char words[][MAX_WORD_SIZE])
{
    for (int i = 0; i < NUM_WORDS; ++i)
        printf("%s\n", words[i]);
}

int main(void)
{
    char words[NUM_WORDS][MAX_WORD_SIZE] = { "one", "two", "three" };
    printStrings(words);
    return 0;
}
#包括
#定义NUM_单词3
#定义最大单词大小64
静态无效打印字符串(字符字[][最大字大小])
{
for(int i=0;i
你有一个完整的二维数组;必须指定除第一个尺寸标注以外的所有尺寸标注的尺寸,如图所示。这与指针数组完全不同(
char*words[]={“四”、“五”、“六”、NULL};
)。然后参数类型将是
char**words
,当它接受参数时有点像
argv
main()

请注意,标准C表示。使用
void
仅在Windows上有效;在其他任何地方,这都是错误的


(我使用
static
,因为函数不会在这个源文件之外被引用。很多(大多数)人都不会这么做。我使用编译器选项使其成为必要。)

只需将函数参数更改为char
char words[][MAX\u WORD\u SIZE]

#include <stdio.h>
#define NUM_WORDS 3
#define MAX_WORD_SIZE 64

void printStrings(char words[][MAX_WORD_SIZE])
{
    //But now 'words' looks like this: "one"  
    for (int i = 0; i < NUM_WORDS; ++i)
        printf("%s", words[i]);
}

void main()
{
    char words[NUM_WORDS][MAX_WORD_SIZE] = { "one", "two", "three" };
    //At this point the array 'words' looks like this:  
    //{ "one", "two", "three" }
    printStrings(words);
}
#包括
#定义NUM_单词3
#定义最大单词大小64
无效打印字符串(字符字[][最大字大小])
{
//但现在“文字”看起来像这样:“一”
for(int i=0;i
printStrings(words)中的类型不兼容问题,编译器应该向您发出警告提示:您正在将
char**
传递到一个接受
char*
的函数中。数组与数组数组。将
void printStrings(char-words[])
更改为
void printStrings(char*words[])
。另请阅读以了解有关C中数组和指针之间关系的更多信息。
words
=
=
=
=
@torstenvl否,函数应为
void printStrings(char words[][MAX\u WORD\u SIZE])
。正在传递的是一个2D数组,而不是指针数组。@WeatherVane:很公平。与OP的问题没有直接关系,但是哪个编译器和什么选项使其“标记”出于作用域原因应该是静态的函数?我同意这听起来是一件有用的事情。@dgnuff:我在GCC中使用
-Wmissing prototype-Wstrict prototype
。缺少原型会触发有关自由函数的警告,如
printStrings()
,前提是在定义之前的作用域中没有原型。如果函数将在这个源文件之外使用,那么应该有一个声明它的头(该头应该包括在定义它的地方和使用它的地方)。如果它不在源文件之外使用,则应定义为
静态
。您可以选择在文件顶部有一个
static
声明,并在文件下面有函数定义。@dgnuff:strict prototype拒绝
int main()
和任何其他未使用正式原型定义的函数,包括未使用原型定义的函数指针。是,但是包含最外层的维度可能会误导读者,让他们认为
NUM_WORDS
是对函数的某种限制,或者是传递给函数的内容。是的,但是仍然
void函数(char foo[foo_SIZE])
对传递的数组长度或函数对数组的索引方式没有任何限制。实际上我以前已经尝试过了,但我没有意识到它是有效的。我还应该提到,这不是我的代码,它只是我尝试做的一个例子。然而,你确实帮助我意识到我以前已经用正确的方法做了,非常感谢@WeatherVane同意-以这种方式添加维度不会对编译器施加任何约束。这是为了代码考古学家的利益,他们可能会在四年后,在我进入另一个项目(或另一家公司)后遇到这个函数,因为它试图解释我写它时的意图。是的,就像所有的样式选择一样,是否使用它取决于程序员。