C语言 将数组作为参数传递给 C 中的函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6567742/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Passing an array as an argument to a function in C
提问by Mohan Mahajan
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?
你能解释一下为什么吗?
回答by Bo Persson
When passing an array as a parameter, this
当将数组作为参数传递时,这
void arraytest(int a[])
means exactly the same as
意思完全一样
void arraytest(int *a)
so you aremodifying the values in main.
所以你正在修改 main 中的值。
For historical reasons, arrays are not first class citizens and cannot be passed by value.
由于历史原因,数组不是一等公民,不能按值传递。
回答by fyr
You are not passing the array as copy. It is only a pointer pointing to the adress where the first element is in memory.
您没有将数组作为副本传递。它只是一个指向第一个元素在内存中的地址的指针。
回答by ob_dev
You are passing the address of the first element of the array
您正在传递数组第一个元素的地址
回答by Monirul Islam Milon
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 !!!
谢谢 !!!
回答by granmirupa
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&R2nd 的引述:
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.js 中的值。
For more I really suggest reading this.
对于更多,我真的建议阅读此内容。
Moreover, you can find other answers on SO here
此外,您可以在此处找到有关 SO 的其他答案
回答by Thom Smith
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:
编辑:有三个这样的特殊情况,其中数组不会衰减到指向它的第一个元素的指针:
sizeof ais not the same assizeof (&a[0]).&ais not the same as&(&a[0])(and not quite the same as&a[0]).char b[] = "foo"is not the same aschar b[] = &("foo").
sizeof a不一样sizeof (&a[0])。&a不一样&(&a[0])(也不完全一样&a[0])。char b[] = "foo"不一样char b[] = &("foo")。
回答by alex
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).
记住那a[1]是*(a+1)。
回答by Andrushenko Alexander
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:
将多维数组作为参数传递给函数。传递一个暗数组作为参数或多或少是微不足道的。让我们来看看传递一个 2dim 数组的更有趣的案例。在 C 中,您不能使用指向指针构造 (int **) 的指针而不是 2 个暗淡数组。让我们举个例子:
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 个暗淡数组作为参数传递:
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:
您可能会想到定义一个更通用的函数,该函数可以接受任何 2dim 数组并按如下方式更改函数签名:
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.
但是我们必须指定直到第一个尺寸的所有尺寸。
回答by Gabriel Staples
@Bo Persson correctly states in his great answer here:
@Bo佩尔松正确他的伟大的回答指出这里:
=================================================
==================================================
When passing an array as a parameter, this
当将数组作为参数传递时,这
void arraytest(int a[])
means exactly the same as
意思完全一样
void arraytest(int *a)
=================================================
==================================================
However, let me add also that it:
但是,让我补充一点:
means exactly the same as
意思完全一样
void arraytest(int a[0])
which means exactly the same as
这意味着完全相同
void arraytest(int a[1])
which means exactly the same as
这意味着完全相同
void arraytest(int a[2])
which means exactly the same as
这意味着完全相同
void arraytest(int a[1000])
etc.
等等。
As a matter of fact, the "size" value inside the array parameter here is apparently just for aesthetic/self-documentation purposes, and can be any positive integer (size_ttype I think) you want!
事实上,这里数组参数中的“大小”值显然只是为了美观/自我记录的目的,并且可以是size_t您想要的任何正整数(我认为是类型)!
In practice, however, you should use it to specify the minimum size of the array you expect the function to receive, so that when writing code it's easy for you to track and verify.The MISRA-C-2012standard (buy/download the 236-pg 2012-version PDF of the standard for £15.00 here) goes so far as to state:
然而,在实践中,您应该使用它来指定您期望函数接收的数组的最小大小,以便在编写代码时很容易跟踪和验证。在MISRA-C-2012标准(购买/下载标准的236-PG 2012版本的PDF为£15.00这里)去那么远,状态:
Rule 17.5 The function argument corresponding to a parameter declared to have an array type shall have an appropriate number of elements.
规则 17.5 与声明为数组类型的参数对应的函数参数应具有适当数量的元素。
...
...
If a parameter is declared as an array with a specified size, the corresponding argument in each function call should point into an object that has at least as many elements as the array.
如果参数被声明为具有指定大小的数组,则每个函数调用中的相应参数应指向一个对象,该对象至少具有与数组一样多的元素。
...
...
The use of an array declarator for a function parameter specifies the function interface more clearly than using a pointer. The minimum number of elements expected by the function is explicitly stated, whereas this is not possible with a pointer.[emphasis added]
对函数参数使用数组声明符比使用指针更清楚地指定函数接口。函数所期望的最小元素数是明确规定的,而这对于指针是不可能的。[强调]
In other words, they recommend using the explicit size format, even though the C standard technically doesn't enforce it--it at least helps clarify to you as a developer, and to others using the code, what size array the function is expecting you to pass in.
换句话说,他们建议使用显式大小格式,即使 C 标准在技术上没有强制执行它 -它至少有助于向您作为开发人员以及使用代码的其他人澄清函数期望的数组大小你传入。
回答by anil karikatti
//array always pass reference if you use a[] or *a
int* printsquares(int a[],int size,int e[]){
for(int i=0;i<size;i++){
e[i]=i*i;
}
return e;
}
int* printsquares(int *a,int size,int e[]){
for(int i=0;i<size;i++){
e[i]=i*i;
}
return e;
}

