将int数组指针作为参数传递给函数的C语言方法

34
我想将B整型数组指针传递到func函数中,并能够在那里更改它,然后在主函数中查看更改。

我希望能将B整型数组指针传入func函数中并修改它,在主函数中查看其修改后的值。

#include <stdio.h>

int func(int *B[10]){

}

int main(void){

    int *B[10];

    func(&B);

    return 0;
}

上述代码给我一些错误:

In function 'main':|
warning: passing argument 1 of 'func' from incompatible pointer type [enabled by default]|
note: expected 'int **' but argument is of type 'int * (*)[10]'|

编辑:新代码:

#include <stdio.h>

int func(int *B){
    *B[0] = 5;
}

int main(void){

    int B[10] = {NULL};
    printf("b[0] = %d\n\n", B[0]);
    func(B);
    printf("b[0] = %d\n\n", B[0]);

    return 0;
}

现在我遇到这些错误:

||In function 'func':|
|4|error: invalid type argument of unary '*' (have 'int')|
||In function 'main':|
|9|warning: initialization makes integer from pointer without a cast [enabled by default]|
|9|warning: (near initialization for 'B[0]') [enabled by default]|
||=== Build finished: 1 errors, 2 warnings ===|

错误信息已经解释了问题所在。你传递了一个指向包含10个int *的数组的指针,但是func期望的是一个int **(它应该是指向一个包含(预计为10个)int *的数组的第一个元素的指针)。如何修复这个问题取决于func的功能。 - Daniel Fischer
func 将简单地编辑 B 值,如 B[0]、B[1] 等。 - stergosz
那么您可能只想传递 B。由于 B 实际上是一个数组,传递 &B 通常没有用,因为 B 不能被更改(但其内容可以被更改,这正是您想要做的)。 - Daniel Fischer
在编程方面的内容中,将以下文本从英语翻译成中文。仅返回已翻译的文本:在func函数中尝试编辑B的值时遇到错误的新代码更新问题。 - stergosz
你原始问题的答案是:func 应该这样声明:int func(int (*B)[10]) - newacct
9个回答

43

在您的新代码中,

int func(int *B){
    *B[0] = 5;
}

B是一个指向int类型的指针,因此B[0]是一个int类型的值,您不能对int进行解引用操作。只需删除*即可。

Translated text:

B是一个指向int类型的指针,因此B[0]是一个int类型的值,您不能对int进行解引用操作。只需删除*即可。

int func(int *B){
    B[0] = 5;
}

而且它可以工作。

在初始化中

int B[10] = {NULL};

你正在使用一个void*NULL)初始化一个int。由于从void*int存在有效的转换,所以这样做是可以的,但这并不太规范,因为这种转换是实现定义的,并且通常表示程序员犯了一个错误,因此编译器会发出警告。

int B[10] = {0};

这是将int [10]正确初始化为0的方法。


12
也许您正在尝试做这个?
#include <stdio.h>

int func(int * B){

    /* B + OFFSET = 5 () You are pointing to the same region as B[OFFSET] */
    *(B + 2) = 5;
}

int main(void) {

    int B[10];

    func(B);

    /* Let's say you edited only 2 and you want to show it. */
    printf("b[0] = %d\n\n", B[2]);

    return 0;
}

如果我尝试在函数中编辑B[2],会出现一些错误... 代码:*B[2] = 5; - stergosz
@fxuser:“我遇到了一些错误”并不是一个有用的问题描述。请像被问问题的人一样寻求帮助。你之所以会出现错误,是因为B是一个指向int的指针,而B[2]返回一个int,而不是一个指针。所以,你只需要写成B[2] = 5;即可。 - Ed S.
2
这就是我在寻找的答案。为什么要使用array + 2而不是array[2] - Iulian Onofrei

8
如果你想传递一个数组指针,可以这样做:
#include <stdio.h>

void func(int (*B)[10]){   // ptr to array of 10 ints.
        (*B)[0] = 5;   // note, *B[0] means *(B[0])
         //B[0][0] = 5;  // same, but could be misleading here; see below.
}

int main(void){

        int B[10] = {0};   // not NULL, which is for pointers.
        printf("b[0] = %d\n\n", B[0]);
        func(&B);            // &B is ptr to arry of 10 ints.
        printf("b[0] = %d\n\n", B[0]);

        return 0;
}

但是正如其他答案中所提到的,这种做法并不常见。通常只有在想要传递二维数组时才会传递指向数组的指针,这样看起来更加清晰,如下所示。实际上,一个二维数组被传递时,它是作为指向其第一行的指针传递的。

void func( int B[5][10] )  // this func is actually the same as the one above! 
{
         B[0][0] = 5;
}

int main(void){
    int Ar2D[5][10];
    func(Ar2D);   // same as func( &Ar2D[0] )
}

func的参数可以声明为int B[5][10]int B[][10]int (*B)[10],它们都等效于参数类型。

附加说明:你可以从函数中返回指向数组的指针,但声明函数的语法非常笨拙,类型的[10]部分必须放在参数列表之后:

int MyArr[5][10];
int MyRow[10];

int (*select_myarr_row( int i ))[10] { // yes, really
   return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}

通常为了避免眼疲劳,可以按以下方式进行操作:
typedef int (*pa10int)[10];

pa10int select_myarr_row( int i ) {
   return (i>=0 && i<5)? &MyArr[i] : &MyRow;
}

我注意到C++正在获得可模板化的typedefs,因此应该可以编写ptr_to_arr_of<int,10> select_myarr_row...。 - greggo

2

使用*(B)代替*B[0]。 这里,*(B+i)表示B[i]*(B)表示B[0],即
*(B+0)=*(B)=B[0]

#include <stdio.h>

int func(int *B){
    *B = 5;     
    // if you want to modify ith index element in the array just do *(B+i)=<value>
}

int main(void){

    int B[10] = {};
    printf("b[0] = %d\n\n", B[0]);
    func(B);
    printf("b[0] = %d\n\n", B[0]);
    return 0;
}

1

在新的代码分配中应该是:

B[0] = 5

在func(B)中,您只是传递指向数组B的指针的地址。您可以在func()中进行更改,如B[i]或*(B + i),其中i是数组的索引。
在第一段代码中,声明如下:
int *B[10]

表示B是一个包含10个元素的数组,每个元素都是指向int类型的指针。也就是说,B[i]是一个int指针,*B[i]是它所指向的整数,即第i个保存文本行的第一个整数。


0
main()
{
    int *arr[5];
    int i=31, j=5, k=19, l=71, m;

    arr[0]=&i;
    arr[1]=&j;
    arr[2]=&k;
    arr[3]=&l;
    arr[4]=&m;

    for(m=0; m<=4; m++)
    {
        printf("%d",*(arr[m]));
    }
    return 0;
}

0
使用Greggo提供的非常好的示例,我将其作为冒泡排序实现,并通过传递指向数组的指针并进行简单的-1操作使其正常工作。
#include<stdio.h>

void sub_one(int (*arr)[7])
{
     int i; 
     for(i=0;i<7;i++)
    {
        (*arr)[i] -= 1 ; // subtract 1 from each point
        printf("%i\n", (*arr)[i]);

    }

}   

int main()
{
    int a[]= { 180, 185, 190, 175, 200, 180, 181};
    int pos, j, i;
    int n=7;
    int temp;
    for (pos =0; pos < 7; pos ++){
        printf("\nPosition=%i Value=%i", pos, a[pos]);
    }
    for(i=1;i<=n-1;i++){
        temp=a[i];
        j=i-1;
        while((temp<a[j])&&(j>=0)) // while selected # less than a[j] and not j isn't 0
        {
            a[j+1]=a[j];    //moves element forward
            j=j-1;
        }
         a[j+1]=temp;    //insert element in proper place
    }

    printf("\nSorted list is as follows:\n");
    for(i=0;i<n;i++)
    {
        printf("%d\n",a[i]);
    }
    printf("\nmedian = %d\n", a[3]);
    sub_one(&a);

    return 0;
}

我需要学习如何封装指针,因为这让我感到困惑。


0

func的参数接受双指针变量。 希望这可以帮到你...

#include <stdio.h>

int func(int **B){

}

int main(void){

    int *B[10];

    func(B);

    return 0;
}

-2
在函数声明中,您必须键入以下内容。
VOID FUN(INT *a[]);
/*HERE YOU CAN TAKE ANY FUNCTION RETURN TYPE HERE I CAN TAKE VOID AS THE FUNCTION RETURN  TYPE FOR THE FUNCTION FUN*/
//IN THE FUNCTION HEADER WE CAN WRITE AS FOLLOWS
void fun(int *a[])
//in the function body we can use as
a[i]=var

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