将数组作为参数传递给C中的函数

时间:2022-07-25 18:46:23

I wrote a function containing array as argument, and call it by passing value of array as follows.

我编写了一个包含数组的函数作为参数,并通过传递数组的值来调用它,如下所示。

void arraytest(int a[])
{
    // changed the array a
    a[0]=a[0]+a[1];
    a[1]=a[0]-a[1];
    a[0]=a[0]-a[1];
}

void main()
{
    int arr[]={1,2};
    printf("%d \t %d",arr[0],arr[1]);
    arraytest(arr);
    printf("\n After calling fun arr contains: %d\t %d",arr[0],arr[1]);
}

What I found is though I am calling arraytest() function by passing values, the original copy of int arr[] is changed.

我发现虽然我通过传递值来调用arraytest()函数,但是int arr[]的原始副本被修改了。

Can you please explain why?

你能解释一下原因吗?

8 个解决方案

#1


73  

When passing an array as a parameter, this

当将数组作为参数传递时,如下所示

void arraytest(int a[])

means exactly the same as

意思完全一样。

void arraytest(int *a)

so you are modifying the values in main.

所以你在修改主值。

For historical reasons, arrays are not first class citizens and cannot be passed by value.

由于历史原因,数组不是一级公民,不能通过值传递。

#2


6  

You are not passing the array as copy. It is only a pointer pointing to the adress where the first element is in memory.

您不会将数组作为副本传递。它只是指向第一个元素位于内存中的adress的指针。

#3


6  

You are passing the address of the first element of the array

您正在传递数组的第一个元素的地址

#4


6  

In C, except for a few special cases, an array reference always "decays" to a pointer to the first element of the array. Therefore, it isn't possible to pass an array "by value". An array in a function call will be passed to the function as a pointer, which is analogous to passing the array by reference.

在C语言中,除了一些特殊情况外,数组引用总是“衰减”到指向数组第一个元素的指针。因此,不可能“按值”传递数组。函数调用中的数组将作为指针传递给函数,这类似于按引用传递数组。

EDIT: There are three such special cases where an array does not decay to a pointer to it's first element:

编辑:有三种这样的特殊情况,数组不会衰减到指向它的第一个元素的指针:

  1. sizeof a is not the same as sizeof (&a[0]).
  2. sizeof a并不等同于sizeof (&a[0])。
  3. &a is not the same as &(&a[0]) (and not quite the same as &a[0]).
  4. 与&(& & &[0])不一样(与[0]不太一样)。
  5. char b[] = "foo" is not the same as char b[] = &("foo").
  6. char b[] = "foo"与char b[] = &("foo")不一样。

#5


4  

You are passing the value of the memory location of the first member of the array.

您正在传递数组第一个成员的内存位置的值。

Therefore when you start modifying the array inside the function, you are modifying the original array.

因此,当您开始修改函数中的数组时,您就是在修改原始数组。

Remember that a[1] is *(a+1).

记住[1]是*(a+1)

#6


3  

If you want to pass a single-dimension array as an argument in a function, you would have to declare a formal parameter in one of following three ways and all three declaration methods produce similar results because each tells the compiler that an integer pointer is going to be received.

如果您想要将一个一维数组作为函数中的参数传递,那么您必须在以下三种方法之一中声明一个正式的参数,并且所有三个声明方法都会产生类似的结果,因为每个方法都告诉编译器将接收一个整数指针。

int func(int arr[], ...){
    .
    .
    .
}

int func(int arr[SIZE], ...){
    .
    .
    .
}

int func(int* arr, ...){
    .
    .
    .
}

So, you are modifying the original values.

你在修改原始的值。

Thanks !!!

谢谢! ! !

#7


1  

Arrays in C are converted, in most of the cases, to a pointer to the first element of the array itself. And more in detail arrays passed into functions are always converted into pointers.

在大多数情况下,C中的数组被转换为指向数组本身第一个元素的指针。更详细的是,传递给函数的数组总是被转换成指针。

Here a quote from K&R2nd:

这里引用k&r2的一句话:

When an array name is passed to a function, what is passed is the location of the initial element. Within the called function, this argument is a local variable, and so an array name parameter is a pointer, that is, a variable containing an address.

当数组名传递给函数时,传递的是初始元素的位置。在被调用的函数中,这个参数是一个局部变量,因此数组名参数是一个指针,也就是说,一个包含地址的变量。

Writing:

写作:

void arraytest(int a[])

has the same meaning as writing:

具有与书写相同的含义:

void arraytest(int *a)

So despite you are not writing it explicitly it is as you are passing a pointer and so you are modifying the values in the main.

所以,尽管你没有显式地写它,但它就像你在传递一个指针,所以你在修改main中的值。

For more I really suggest reading this.

更多信息,我真的建议你读一下。

Moreover, you can find other answers on SO here

此外,你可以在这里找到其他答案。

#8


1  

Passing a multidimensional array as argument to a function. Passing an one dim array as argument is more or less trivial. Let's take a look on more interesting case of passing a 2 dim array. In C you can't use a pointer to pointer construct (int **) instead of 2 dim array. Let's make an example:

将多维数组作为参数传递给函数。将一个dim数组作为参数传递,这多少有些琐碎。让我们看一下传递2个dim数组的更有趣的情况。在C语言中,不能使用指向指针结构(int **)的指针,而使用2个dim数组。让我们做一个例子:

void assignZeros(int(*arr)[5], const int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 5; j++) {
            *(*(arr + i) + j) = 0;
            // or equivalent assignment
            arr[i][j] = 0;
        }
    }

Here I have specified a function that takes as first argument a pointer to an array of 5 ints. I can pass as argument any 2 dim array that has 5 columns:

在这里,我指定了一个函数,它以一个指向一个5英寸数组的指针作为第一个参数。我可以作为参数传递任何有5列的2个dim数组:

int arr1[1][5]
int arr1[2][5]
...
int arr1[20][5]
...

You may come to an idea to define a more general function that can accept any 2 dim array and change the function signature as follows:

您可能会想要定义一个更通用的函数,它可以接受任何2个dim数组并更改函数签名如下所示:

void assignZeros(int ** arr, const int rows, const int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            *(*(arr + i) + j) = 0;
        }
    }
}

This code would compile but you will get a runtime error when trying to assign the values in the same way as in the first function. So in C a multidimensional arrays are not the same as pointers to pointers ... to pointers. An int(*arr)[5] is a pointer to array of 5 elements, an int(*arr)[6] is a pointer to array of 6 elements, and they are a pointers to different types!

这段代码将被编译,但是当您试图以与第一个函数相同的方式分配值时,您将会得到一个运行时错误。所以在C中多维数组与指针的指针不同。指针。一个int(*arr)[5]是一个指向5个元素的数组的指针,一个int(*arr)[6]是指向6个元素的数组的指针,它们是指向不同类型的指针!

Well, how to define functions arguments for higher dimensions? Simple, we just follow the pattern! Hier ist the same function adjusted to take an array of 3 dimensions:

那么,如何定义更高维度的函数参数呢?很简单,我们只是遵循这个模式!Hier ist相同的功能调整为以3个维度的数组:

void assignZeros2(int(*arr)[4][5], const int dim1, const int dim2, const int dim3) {
    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            for (int k = 0; k < dim3; k++) {
                *(*(*(arr + i) + j) + k) = 0;
                // or equivalent assignment
                arr[i][j][k] = 0;
            }
        }
    }
}

How you would expect, it can take as argument any 3 dim arrays that have in the second dimensions 4 elements and in the third dimension 5 elements. Anything like this would be ok:

你会怎么想,它可以作为参数任何3个暗数组,在二维4元素和三维5元素中。像这样的事情就可以了:

arr[1][4][5]
arr[2][4][5]
...
arr[10][4][5]
...

But we have to specify all dimensions sizes up to the first one.

但是我们必须指定到第一个的所有尺寸。

#1


73  

When passing an array as a parameter, this

当将数组作为参数传递时,如下所示

void arraytest(int a[])

means exactly the same as

意思完全一样。

void arraytest(int *a)

so you are modifying the values in main.

所以你在修改主值。

For historical reasons, arrays are not first class citizens and cannot be passed by value.

由于历史原因,数组不是一级公民,不能通过值传递。

#2


6  

You are not passing the array as copy. It is only a pointer pointing to the adress where the first element is in memory.

您不会将数组作为副本传递。它只是指向第一个元素位于内存中的adress的指针。

#3


6  

You are passing the address of the first element of the array

您正在传递数组的第一个元素的地址

#4


6  

In C, except for a few special cases, an array reference always "decays" to a pointer to the first element of the array. Therefore, it isn't possible to pass an array "by value". An array in a function call will be passed to the function as a pointer, which is analogous to passing the array by reference.

在C语言中,除了一些特殊情况外,数组引用总是“衰减”到指向数组第一个元素的指针。因此,不可能“按值”传递数组。函数调用中的数组将作为指针传递给函数,这类似于按引用传递数组。

EDIT: There are three such special cases where an array does not decay to a pointer to it's first element:

编辑:有三种这样的特殊情况,数组不会衰减到指向它的第一个元素的指针:

  1. sizeof a is not the same as sizeof (&a[0]).
  2. sizeof a并不等同于sizeof (&a[0])。
  3. &a is not the same as &(&a[0]) (and not quite the same as &a[0]).
  4. 与&(& & &[0])不一样(与[0]不太一样)。
  5. char b[] = "foo" is not the same as char b[] = &("foo").
  6. char b[] = "foo"与char b[] = &("foo")不一样。

#5


4  

You are passing the value of the memory location of the first member of the array.

您正在传递数组第一个成员的内存位置的值。

Therefore when you start modifying the array inside the function, you are modifying the original array.

因此,当您开始修改函数中的数组时,您就是在修改原始数组。

Remember that a[1] is *(a+1).

记住[1]是*(a+1)

#6


3  

If you want to pass a single-dimension array as an argument in a function, you would have to declare a formal parameter in one of following three ways and all three declaration methods produce similar results because each tells the compiler that an integer pointer is going to be received.

如果您想要将一个一维数组作为函数中的参数传递,那么您必须在以下三种方法之一中声明一个正式的参数,并且所有三个声明方法都会产生类似的结果,因为每个方法都告诉编译器将接收一个整数指针。

int func(int arr[], ...){
    .
    .
    .
}

int func(int arr[SIZE], ...){
    .
    .
    .
}

int func(int* arr, ...){
    .
    .
    .
}

So, you are modifying the original values.

你在修改原始的值。

Thanks !!!

谢谢! ! !

#7


1  

Arrays in C are converted, in most of the cases, to a pointer to the first element of the array itself. And more in detail arrays passed into functions are always converted into pointers.

在大多数情况下,C中的数组被转换为指向数组本身第一个元素的指针。更详细的是,传递给函数的数组总是被转换成指针。

Here a quote from K&R2nd:

这里引用k&r2的一句话:

When an array name is passed to a function, what is passed is the location of the initial element. Within the called function, this argument is a local variable, and so an array name parameter is a pointer, that is, a variable containing an address.

当数组名传递给函数时,传递的是初始元素的位置。在被调用的函数中,这个参数是一个局部变量,因此数组名参数是一个指针,也就是说,一个包含地址的变量。

Writing:

写作:

void arraytest(int a[])

has the same meaning as writing:

具有与书写相同的含义:

void arraytest(int *a)

So despite you are not writing it explicitly it is as you are passing a pointer and so you are modifying the values in the main.

所以,尽管你没有显式地写它,但它就像你在传递一个指针,所以你在修改main中的值。

For more I really suggest reading this.

更多信息,我真的建议你读一下。

Moreover, you can find other answers on SO here

此外,你可以在这里找到其他答案。

#8


1  

Passing a multidimensional array as argument to a function. Passing an one dim array as argument is more or less trivial. Let's take a look on more interesting case of passing a 2 dim array. In C you can't use a pointer to pointer construct (int **) instead of 2 dim array. Let's make an example:

将多维数组作为参数传递给函数。将一个dim数组作为参数传递,这多少有些琐碎。让我们看一下传递2个dim数组的更有趣的情况。在C语言中,不能使用指向指针结构(int **)的指针,而使用2个dim数组。让我们做一个例子:

void assignZeros(int(*arr)[5], const int rows) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < 5; j++) {
            *(*(arr + i) + j) = 0;
            // or equivalent assignment
            arr[i][j] = 0;
        }
    }

Here I have specified a function that takes as first argument a pointer to an array of 5 ints. I can pass as argument any 2 dim array that has 5 columns:

在这里,我指定了一个函数,它以一个指向一个5英寸数组的指针作为第一个参数。我可以作为参数传递任何有5列的2个dim数组:

int arr1[1][5]
int arr1[2][5]
...
int arr1[20][5]
...

You may come to an idea to define a more general function that can accept any 2 dim array and change the function signature as follows:

您可能会想要定义一个更通用的函数,它可以接受任何2个dim数组并更改函数签名如下所示:

void assignZeros(int ** arr, const int rows, const int cols) {
    for (int i = 0; i < rows; i++) {
        for (int j = 0; j < cols; j++) {
            *(*(arr + i) + j) = 0;
        }
    }
}

This code would compile but you will get a runtime error when trying to assign the values in the same way as in the first function. So in C a multidimensional arrays are not the same as pointers to pointers ... to pointers. An int(*arr)[5] is a pointer to array of 5 elements, an int(*arr)[6] is a pointer to array of 6 elements, and they are a pointers to different types!

这段代码将被编译,但是当您试图以与第一个函数相同的方式分配值时,您将会得到一个运行时错误。所以在C中多维数组与指针的指针不同。指针。一个int(*arr)[5]是一个指向5个元素的数组的指针,一个int(*arr)[6]是指向6个元素的数组的指针,它们是指向不同类型的指针!

Well, how to define functions arguments for higher dimensions? Simple, we just follow the pattern! Hier ist the same function adjusted to take an array of 3 dimensions:

那么,如何定义更高维度的函数参数呢?很简单,我们只是遵循这个模式!Hier ist相同的功能调整为以3个维度的数组:

void assignZeros2(int(*arr)[4][5], const int dim1, const int dim2, const int dim3) {
    for (int i = 0; i < dim1; i++) {
        for (int j = 0; j < dim2; j++) {
            for (int k = 0; k < dim3; k++) {
                *(*(*(arr + i) + j) + k) = 0;
                // or equivalent assignment
                arr[i][j][k] = 0;
            }
        }
    }
}

How you would expect, it can take as argument any 3 dim arrays that have in the second dimensions 4 elements and in the third dimension 5 elements. Anything like this would be ok:

你会怎么想,它可以作为参数任何3个暗数组,在二维4元素和三维5元素中。像这样的事情就可以了:

arr[1][4][5]
arr[2][4][5]
...
arr[10][4][5]
...

But we have to specify all dimensions sizes up to the first one.

但是我们必须指定到第一个的所有尺寸。