C语言 在 C 中更改函数内部的数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34844003/
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
Changing array inside function in C
提问by Victor Ferreira
I am learning C and confused why a array created in the main wont change inside the function, i am assuming the array passed is a pointer, and changing the pointer should've change the array , right ? can someone explain what is happening in this case?
我正在学习 C 并困惑为什么在 main 中创建的数组不会在函数内部更改,我假设传递的数组是一个指针,并且更改指针应该更改数组,对吗?有人可以解释在这种情况下发生了什么吗?
thx for the help.
谢谢你的帮助。
int main(){
int i, length = 10;
int array[length];
for (i = 0 ; i < length ; i++)
array[i] = i * 10;
printf("Before:");
print(array, length);
change(array, length);
printf("After:");
print(array, length);
return 0;
}
// Print on console the array of int
void print(int *array,int length)
{
int i;
for(i = 0 ; i < length ; i++)
printf("%d ", array[i]);
printf("\n");
}
// Change the pointer of the array
void change(int *array,int length)
{
int *new = (int *) malloc(length * sizeof(int));
int i;
for(i = 0 ; i < length ; i++)
new[i] = 1;
array = new;
}
I expected to see the following output:
我希望看到以下输出:
Before:0 10 20 30 40 50 60 70 80 90
After:1 1 1 1 1 1 1 1 1 1
What i get:
我得到了什么:
Before:0 10 20 30 40 50 60 70 80 90
After:0 10 20 30 40 50 60 70 80 90
回答by Iharob Al Asimi
In cyou can't pass a variable by reference, the arrayvariable that you assign inside the function contains initially the same address as the passed pointer, but it's a copy of it so modifying it will not alter the passed pointer.
在c 中,您不能通过引用传递array变量,您在函数内部分配的变量最初包含与传递的指针相同的地址,但它是它的副本,因此修改它不会改变传递的指针。
You need to pass the address of the pointer in order to be able to alter it, like this
您需要传递指针的地址才能更改它,就像这样
// Change the pointer of the array
void change(int **array, int length)
{
*array = malloc(length * sizeof(int));
if (*array == NULL)
return;
for (int i = 0 ; i < length ; i++)
(*array)[i] = 1;
}
Then in main()you cannot assign to an array, doing so through this kind of function is surely undefined behavior. The array defined in main()is allocated on the stack and you cannot assign anything to an array since they are non-writeable lvaluesso you cannot make it point to a heap memory location obtained with malloc(), you need to pass a pointer like this
那么在main()你不能分配给一个数组时,通过这种函数这样做肯定是未定义的行为。中定义的数组main()被分配在栈上,你不能分配到任何一个数组,因为它们是无-writeable左值,所以你不能让它指向与所获得的堆内存的位置malloc(),你需要通过这样的指针
int *array;
change(&array, length);
free(array);
If you want the function to replace the previous array, it will have to free()the malloc()ed data (note that passing NULLto free()is well defined), so
如果您希望该函数替换之前的数组,则必须将free()其传递给malloc()ed 数据(请注意,传递NULLtofree()是明确定义的),因此
// Change the pointer of the array
void change(int **array, int length)
{
free(*array);
*array = malloc(length * sizeof(int));
if (*array == NULL)
return;
for (int i = 0 ; i < length ; i++)
(*array)[i] = 1;
}
then in main()
然后在 main()
int *array;
array = NULL;
change(&array, length);
change(&array, length);
change(&array, length);
change(&array, length);
free(array);
will do what you apparently want.
会做你显然想要的。
回答by Kandy
Ok, i will make the answer short.
好的,我会让答案简短。
- Arrays are always passed by reference in C
- 数组在 C 中总是通过引用传递
change(array, length); In this line, it means reference to the first element of the array variable is passed to the function.
改变(数组,长度);在这一行中,它意味着对数组变量的第一个元素的引用被传递给函数。
Now the function needs a pointer to catch the reference, it can be a pointer or it can be an array. Note that the pointer or the array is local to the function.
现在函数需要一个指针来捕捉引用,它可以是一个指针,也可以是一个数组。请注意,指针或数组对于函数来说是局部的。
You received it in a pointer named array. Which is definitely a pointer but it is not the same as array in main function. It is local to the change function.
You declared a new array dynamically, and assigned a pointer named new with it. And all the changes you did were to new pointer.
您在名为数组的指针中收到它。这绝对是一个指针,但它与主函数中的数组不同。它是更改函数的局部变量。
您动态声明了一个新数组,并为其分配了一个名为 new 的指针。您所做的所有更改都是针对新指针的。
Everything is ok till now.
到目前为止一切都很好。
- Now you assigned the new pointer to the array pointer which is local to the change function.
- 现在您将新指针分配给更改函数本地的数组指针。
This is the real issue. As even though the array is in heap section, and it will remain in the memory, but the *array and *new are local pointer variables.
这是真正的问题。即使数组在堆中,它也会留在内存中,但 *array 和 *new 是局部指针变量。
Also array pointer in change function is different from array pointer in main function.
更改函数中的数组指针也不同于主函数中的数组指针。
The solution to this problem is Manipulate the data of array pointer directly.
void change(int *array,int length) { int i; for(i = 0 ; i < length ; i++) array[i] = 1; }
这个问题的解决方法是直接操作数组指针的数据。
void change(int *array,int length) { int i; for(i = 0 ; i < 长度 ; i++) 数组[i] = 1; }
In this way you are directly overwriting values of array in main function. Everything else is correct.
通过这种方式,您可以直接覆盖 main 函数中数组的值。其他一切都是正确的。
Summerization: array pointer in change function is local to change function. array in main function is local to main function. Making change function's local array pointer point to array in heap section won't change data in actual array. You changed pointer's position, Not the array's data.
总结:更改函数中的数组指针是更改函数的本地指针。main 函数中的数组是 main 函数的局部数组。使更改函数的本地数组指针指向堆部分中的数组不会更改实际数组中的数据。您更改了指针的位置,而不是数组的数据。
回答by nsilent22
You pass a pointer to the array arrayto the function change. In this function you create another array called new(using newas a name is a bad idea) and then assign it to the locally created function parameter array. You do notmodify pointer in your mainfunction. If you would like to do so, you should use
您将指向数组的指针传递array给函数change。在此函数中,您创建另一个名为的数组new(new用作名称是一个坏主意),然后将其分配给本地创建的函数参数array。您不会修改main函数中的指针。如果你想这样做,你应该使用
array = change(array,length);
in your main function and
在您的主要功能和
int *change(int *array, int length) {
int *variable_called_new =(int *)malloc(length*sizeof(int));
[...]
return variable_called_new
}
in your changefunction.
在你的change函数中。
回答by ryyker
To use pass by value:
Make the following change:
In function change(...), replace:
要使用按值传递:
进行以下更改:
在函数中change(...),替换:
int i;for(i=0;i<length;i++)new[i] = 1;
To:
到:
int i;for(i=0;i<length;i++)array[i] = 1;
^^^^^
EDIT:
But to use pass by reference:
编辑:
但要使用按引用传递:
//To change the contents of a variable via a function call
//the address of that variable has to be passed. So, if you
//want to change the contents of an array of int, i.e. int *array, you
//need to pass its address, not the variable itself, using the
//address of operator, it would look like this &array (read _the address of
// pointer to int "array")
//This requires you to change the prototype of your function:
void change2(int **a, int len)
{
int i;
for(i=0;i<len;i++) (*a)[i] = 1;//parenthesis bind * to a to assure
//array of pointers to int ( *[] )is populated
//
}
Then in main, make the following changes, and it will work as you purposed:
然后在 main 中进行以下更改,它将按您的目的工作:
int main(){
int i,length=10;
int *array;
array = calloc(length, sizeof(int));
if(!array) return 0;
//or malloc if preferred. But note, in C,
//casting the output is not required on either.
//array = malloc(length*sizeof(int));
//if(!array) return 0;
for(i=0;i<length;i++)array[i]=i*10;
printf("Before:");print(array,length);
change2(&array,length);
printf("After:");print(array,length);
free(array);
return 0;
}
回答by kfsone
Your array in main is an array. It will decay to a pointer, to produce the behavior you expect, but it is nota pointer.
您在 main 中的数组是一个array。它会衰减为一个指针,以产生您期望的行为,但它不是一个指针。
int a[10];
int* p = a; // equivalent to &a[0]; create a pointer to the first element
a = p; // illegal, a is NOT a pointer.
What your code is doing is copying the address of a into a function-local variable. Modifying it will have no more difference outside than changing length.
您的代码正在做的是将 a 的地址复制到函数局部变量中。修改它不会比改变长度有更多的区别。
void change(int* local_ptr, size_t length)
{
local_ptr = 0;
length = 0;
}
int main()
{
int a[10];
int length = 10;
printf("before a=%p, length=%d\n", a, length);
change(a, length); // we copied 'a' into 'local_ptr'.
printf("after a=%p, length=%d\n", a, length);
}
If you wish to modify a pointer from the caller, you will need to use pointer-to-pointer syntax:
如果您希望修改来自调用者的指针,则需要使用指针到指针语法:
void change(int** ptr, size_t length)
{
// change the first element:
**ptr = 0;
// change the pointer:
*ptr = 0;
// but ptr itself is a function-local variable
ptr = 0; // local effect
}
However: There is a problem with what you are trying to do that goes deeper than this.
但是:您尝试做的事情存在一个比这更深层次的问题。
In your code, "int a" is an array on the stack, not an allocated pointer; you cannot free it and you should avoid mixing heap/stack pointers this way because eventually you'll free the wrong thing.
在您的代码中,“int a”是堆栈上的一个数组,而不是分配的指针;你不能释放它,你应该避免以这种方式混合堆/堆栈指针,因为最终你会释放错误的东西。
回答by rustypaper
so when you pass the array you get the address of it's beginning:
所以当你传递数组时,你会得到它开始的地址:
memoryaddress
内存地址
|-junk-| 1000
|-垃圾-| 1000
|---0---| 1008 <- start of your array
|---0---| 1008 <- 数组的开始
|---10--| 1012
|---10--| 1012
. . . .
. . . .
when you get the pointer in your function its value is 1008(example) so changing that will only mean you now point to another place. that is not what you want.
you can change the integers pointed at directly via the * operator, so
*array = 99;will change the first element,
*(array+1) = 98;the second and so on.
you can also, more naturally use the [] operator.
so in your function
array[0] = 99;will actually change the original array.
当您在函数中获取指针时,其值为 1008(示例),因此更改它只会意味着您现在指向另一个位置。那不是你想要的。您可以通过 * 运算符直接更改指向的整数,因此
*array = 99;将更改第一个元素、*(array+1) = 98;第二个元素,
依此类推。您还可以更自然地使用 [] 运算符。所以在你的函数中
array[0] = 99;实际上会改变原始数组。
回答by yogesh
#include<stdio.h>
#include<stdlib.h>
// Print on console the array of int
void print(int *array,int length)
{
int i;
for(i = 0 ; i < length ; i++)
printf("%d ", array[i]);
printf("\n");
}
// Change the pointer of the array
void change(int **array,int length)
{
int i;
int *ar;
ar = (int *)malloc(sizeof(int *) * length);
for(i = 0 ; i < length ; i++)
ar[i] = 1;
(*array) = ar;
}
int main(){
int i, length = 10;
int *array;
array = (int *)malloc(sizeof(int *) * length);
for (i = 0 ; i < length ; i++)
array[i] = i * 10;
printf("Before:");
print(array, length);
change(&array, length);
printf("After:");
print(array, length);
return 0;
}

