将字符数组的集合传递给函数

5

我想将一个字符字符串数组(C风格的字符串)传递给一个函数。但是,我不想在函数中限制每个字符串的最大长度,也不想动态分配数组。这是我首先编写的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void fun(char *s[])
{
    printf("Entering Fun\n");
    printf("s[1]=%s\n",(char *)s[1]);
}

int main(void)
{
    char myStrings[2][12];

    strcpy(myStrings[0],"7/2/2010");
    strcpy(myStrings[1],"hello");
    fun(myStrings);

    return(0);
}

当我运行时,出现了段错误,并且编译器发出以下警告:

stackov.c: 在函数 ‘main’ 中:

stackov.c:17: 警告:从不兼容的指针类型传递参数 1 给函数 ‘fun’

stackov.c:5: 注意:期望类型 ‘char **’,但参数的类型为 ‘char (*)[12]’

然而,当我将 main() 改为以下代码时,它可以正常工作:

int main(void)
{
    char myStrings[2][12];
    char *newStrings[2];

    strcpy(myStrings[0],"7/2/2010");
    strcpy(myStrings[1],"hello");
    newStrings[0]=myStrings[0];
    newStrings[1]=myStrings[1];
    fun(newStrings);

    return(0);
}

当将array[2][12]传递给函数时,它与字符指针数组相同吗?
5个回答

7
不,char array[2][12] 是一个二维数组(数组的数组)。char *array[2] 是一个指针数组。 char array[2][12] 的样子是这样的:
7/2/2010\0\x\x\xhello\0\x\x\x\x\x\x

\0代表空字符,\x代表不确定的字符。

char *array[2]是:

0x CAFEBABEDEADBEEF

(假设是32位)
第一个有24个连续的字符,第二个有两个指针(指向其他地方字符串的开头)。


2

当它传递到函数中时,array[2][12]和字符指针数组是相同的吗?

不,它是一个二维数组。区别在于指针数组包含指针,但array[2][12]实际上是一个数组的数组-没有涉及指针。

顺便说一下,你可以这样做:

char* mystrings[2]={"aha", "haha"};
fun(mystrings);

这样做的好处是仅存储字符串所需的实际字符数。缺点是每个字符串还需要(额外)分配一个指针。但指针的易用性是主要优势。 - David R Tribble
是的,我知道这个可以工作,但对于实际应用程序,我无法在编译时初始化数组。 - Mike
@Mike:当你在函数中使用它时,数组实际上是在运行时初始化的。 - jpalecek

1

char myStrings [2] [12];将myStrings 声明为字符数组的数组。这意味着myStrings 存储为24字节

<code><code><code>7/2/2010.???hello.??????
‘——————————’‘——————————’
myStrings[0]myStrings[1]
</code></code></code>

.代表空字符,?代表未初始化的字节。

char *newStrings[2];声明newStrings为一个指向字符的指针数组。这意味着newStrings存储为2×sizeof(char*)字节。

[..][..]

[..]代表一个指针对象(尚未初始化)。

如果您想将不同长度的字符串传递给函数,您必须传递指针数组,而不是数组的数组。如上所示,这些是不同的布局。

一般建议:每当您涉及到指针时,请画出图表(如果可以,在白板或黑板上,否则在纸上),显示内存中的各种对象,并用箭头指示指向何处。有两种C程序员:遇到指针时会画这样的图表的人,以及在脑海中画出这些图表的经验丰富的程序员。


我对你的陈述感到困惑:“请注意,您后续调用strcpy尝试写入未初始化的指针。程序给出了您想要的结果而不是崩溃,这纯粹是巧合。” 你的意思是什么?另外,“未初始化的指针”是什么意思? - Mike
@Mike:抱歉,这部分是我的失误(我误读了你的代码)。 - Gilles 'SO- stop being evil'
没问题。我只是想确保我没有漏掉什么。 - Mike

0

你的数组被声明为一个二维数组,但是你想按照一维字符串指针数组的方式传递给函数。

Tom 的答案是正确的,你可以在函数参数的多维数组声明中省略第一个维度的大小。

你的第二个解决方案有效是因为它明确地向函数传递了一个一维字符串指针数组。当然,除了原始的二维字符串数组之外,它还需要额外的指针数组开销。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接