繁体   English   中英

在C中传递数组指针

[英]Passing pointers of arrays in C

所以我有一些看起来像这样的代码:

int a[10];
a = arrayGen(a,9);

并且arrayGen函数如下所示:

int* arrayGen(int arrAddr[], int maxNum)
{
    int counter=0;
    while(arrAddr[counter] != '\0') {
        arrAddr[counter] = gen(maxNum);
        counter++;
    }
    return arrAddr;
}

现在compilier告诉我“警告:传递'arrayGen'的参数1从指针生成整数而没有强制转换”

我的想法是我传递'a',一个指向[0]的指针,然后由于数组已经创建,我可以只填写[n]的值,直到我a [n] =='\\ 0'。 我认为我的错误是arrayGen被写入接收数组,而不是指向一个数组。 如果这是真的我不知道如何继续,我会写地址值,直到一个地址的内容是'\\ 0'?

这里的基本魔法是C中的这个身份:

*(a+i) == a[i]

好的,现在我会把它变成可读的英文。

这是问题:数组名称不是左值; 它不能分配给。 所以你有这条线

a = arrayGen(...)

是问题。 看这个例子:

int main() {
    int a[10];

    a = arrayGen(a,9);

    return 0;
}

这给出了编译错误:

gcc -o foo foo.c
foo.c: In function 'main':
foo.c:21: error: incompatible types in assignment

Compilation exited abnormally with code 1 at Sun Feb  1 20:05:37

你需要有一个指针,它一个左值,分配结果。

这段代码,例如:

int main() {
    int a[10];
    int * ip;

    /* a = arrayGen(a,9);  */
    ip = a ; /* or &a[0] */
    ip = arrayGen(ip,9);

    return 0;
}

编译好:

gcc -o foo foo.c

Compilation finished at Sun Feb  1 20:09:28

请注意,由于顶部的标识,您可以将ip视为数组,如下所示:

int main() {
    int a[10];
    int * ip;
    int ix ;

    /* a = arrayGen(a,9);  */
    ip = a ; /* or &a[0] */
    ip = arrayGen(ip,9);

    for(ix=0; ix < 9; ix++)
        ip[ix] = 42 ;

    return 0;
}

完整的示例代码

为了完整起见,这是我的完整例子:

int gen(int max){
    return 42;
}

int* arrayGen(int arrAddr[], int maxNum)
{
    int counter=0;
    while(arrAddr[counter] != '\0') {
        arrAddr[counter] = gen(maxNum);
        counter++;
    }
    return arrAddr;
}

int main() {
    int a[10];
    int * ip;
    int ix ;

    /* a = arrayGen(a,9);  */
    ip = a ; /* or &a[0] */
    ip = arrayGen(ip,9);

    for(ix=0; ix < 9; ix++)
        ip[ix] = 42 ;

    return 0;
}

为什么甚至返回arrAddr? 您通过引用传递[10],因此将修改数组的内容。 reference to the array then charlies suggestion is correct. 除非你需要对数组的引用,否则charlies建议是正确的。

嗯,我知道你的问题已得到解答,但是关于代码的其他问题让我烦恼。 为什么使用针对'\\ 0'的测试来确定数组的结尾? 我很确定只适用于C字符串。 代码确实在修复建议后编译,但是如果你循环遍历数组,我很想知道你是否得到了正确的值。

我不确定你要做什么,但是指向数组的指针值正如Charlie所提到的那样困扰编译器。 我很好奇检查NUL字符常量'\\0' 您的示例数组是未初始化的内存,因此arrayGen的比较不会按照您希望的方式执行。

您使用的参数列表最终与以下内容相同:

int* arrayGen(int *arrAddr, int maxNum)

对于大多数目的。 标准中的实际陈述是:

参数声明为“ 类型数组”应调整为“限定类型的指针”,其中类型限定符(如果有)是在数组类型派生的[和]内指定的那些。 如果关键字static也出现在数组类型派生的[和]中,那么对于每次对函数的调用,相应的实际参数的值应提供对数组的第一个元素的访问,其中元素的数量至少与指定的元素一样多。按大小表达式。

如果您确实想强制调用者使用数组,请使用以下语法:

void accepts_pointer_to_array (int (*ary)[10]) {
    int i;
    for (i=0; i<10; ++i) {
        (*ary)[i] = 0; /* note the funky syntax is necessary */
    }
}

void some_caller (void) {
    int ary1[10];
    int ary2[20];
    int *ptr = &ary1[0];
    accepts_pointer_to_array(&ary1); /* passing address is necessary */
    accepts_pointer_to_array(&ary2); /* fails */
    accepts_pointer_to_array(ptr);   /* also fails */
}

如果你用任何不是指向10个整数数组的指针调用它,你的编译器应该会抱怨。 我可以诚实地说,虽然我从未在各种书籍之外的任何地方看过这本书( C书专家C编程 )......至少在C编程中没有。 但是,在C ++中,我有理由在一种情况下使用此语法:

template <typename T, std::size_t N>
std::size_t array_size (T (&ary)[N]) {
    return N;
}

您的里程可能会有所不同。 如果你真的想深入研究这样的东西,我不能推荐专家C编程 您也可以在gbdirect在线查找The C Book

尝试调用参数int* arrAddr ,而不是int arrAddr[] 虽然当我考虑它时, main方法的参数是相似的但仍然有效。 所以不确定解释部分。

编辑:我可以在互联网上找到的所有资源说它应该有效。 我不确定,我自己总是把数组作为指针传递给所以从来没有遇到过这个障碍,所以我对解决方案非常感兴趣。

使用它的方式arrayGen()不需要返回值。 您还需要在最后一个元素中放置'\\ 0',它不会自动完成,或者传递要填充的最后一个元素的索引。

@jeffD传递索引将是首选方式,因为不能保证你不会在最后一个之前击中其他'\\ 0'(我当然是在测试它时)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM