在C语言中改变函数内部的数组

在C语言中改变函数内部的数组,c,arrays,function,pointers,C,Arrays,Function,Pointers,我正在学习C,不明白为什么在main中创建的数组在函数内部不会改变,我假设传递的数组是指针,改变指针应该会改变数组,对吗?有人能解释一下这种情况下发生了什么吗 谢谢你的帮助 intmain(){ int i,长度=10; 整数数组[长度]; 对于(i=0;i

我正在学习C,不明白为什么在main中创建的数组在函数内部不会改变,我假设传递的数组是指针,改变指针应该会改变数组,对吗?有人能解释一下这种情况下发生了什么吗

谢谢你的帮助

intmain(){
int i,长度=10;
整数数组[长度];
对于(i=0;i
我希望看到以下输出:

Before:0 10 20 30 40 50 60 70 80 90 
After:1 1 1 1 1 1 1 1 1 1 
我得到的是:

Before:0 10 20 30 40 50 60 70 80 90 
After:0 10 20 30 40 50 60 70 80 90 
在无法通过引用传递变量的情况下,在函数中指定的
数组
变量最初包含与传递的指针相同的地址,但它是它的副本,因此修改它不会改变传递的指针

您需要传递指针的地址才能更改它,如下所示

// 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;
}
int *array;
change(&array, length);
free(array);
如果您希望函数替换以前的数组,它必须
free()
malloc()
ed数据(请注意,将
NULL
传递给
free()
是定义良好的),因此


将执行您显然想要的操作。

您将指向数组的指针
数组
传递给函数
更改
。在此函数中,创建另一个名为
new
的数组(使用
new
作为名称是个坏主意),然后将其分配给本地创建的函数参数
array。不修改
main
函数中的指针。如果您想这样做,您应该使用

array = change(array,length);
在您的主要功能和

int *change(int *array, int length) {
    int *variable_called_new =(int *)malloc(length*sizeof(int));
    [...]
    return variable_called_new
}
中更改
函数。

使用传递值:
进行以下更改:
在功能
更改(…)
中,替换:

int i;for(i=0;i<length;i++)new[i] = 1;
inti;对于(i=0;i您的主数组是一个数组。它将衰减为指针,以产生您期望的行为,但它不是指针

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.
您的代码所做的是将函数的地址复制到函数局部变量中。修改它除了更改长度外没有其他区别

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);
}
如果希望修改调用者的指针,则需要使用指针到指针语法:

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
}
然而,你试图做的事情有一个问题,这个问题比这更深刻


在您的代码中,“int a”是堆栈上的一个数组,而不是分配的指针;您不能释放它,您应该避免以这种方式混合堆/堆栈指针,因为最终您将释放错误的东西。

因此,当您传递数组时,您会得到它的起始地址:

存储器地址

|-垃圾-1000

|---0---| 1008
#包括
#包括
//在控制台上打印int数组
无效打印(整数*数组,整数长度)
{
int i;
对于(i=0;i
好的,我会简短地回答

  • 数组在C中总是通过引用传递
  • 更改(数组、长度); 在这一行中,它意味着数组变量的第一个元素的引用被传递给函数

    现在,函数需要一个指针来捕获引用,它可以是指针,也可以是数组。请注意,指针或数组是函数的本地对象

  • 您在名为array的指针中收到它。array肯定是指针,但它与主函数中的数组不同。它是change函数的本地指针

  • 您动态声明了一个新数组,并分配了一个名为new的指针。您所做的所有更改都是对新指针进行的

  • 到目前为止一切都很好

  • 现在,您将新指针指定给change函数的本地数组指针
  • 这才是真正的问题。即使数组在heap部分,它也会保留在内存中,但是*array和*new是本地指针变量

    此外,change函数中的数组指针与main函数中的数组指针不同

  • 这个问题的解决办法是 直接操作数组指针的数据

    无效更改(整数*数组,整数长度) { int i; 对于(i=0;i
  • 这样,您就可以直接覆盖main函数中数组的值。其他所有内容都是正确的

    总结: change函数中的数组指针是change函数的本地指针。 主函数中的数组是主函数的局部数组。 使change函数的本地数组指针指向堆部分中的数组不会更改实际数组中的数据。您更改了指针的位置,而不是数组的数据。

    一个简单的示例: 永远不会,永远不会
    //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
                                       //
    }
    
    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;
    }
    
    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.
    
    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);
    }
    
    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
    }
    
                #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;
                }
    
    #include <stdio.h>
    
    void print_array(const int arr[], const int n){
        int i;
        for(i=0; i < n; i++)
            printf("%d ", arr[i]);
        printf("\n");
    }
    
    void change_array(int arr[]){
        arr[0] = 239;
        arr[1] = 234234;
    }
    
    int main(){
        int arr[10] = {};
        print_array(arr,10);
        change_array(arr);
        print_array(arr,10);
        return 0;
    }
    
    0 0 0 0 0 0 0 0 0 0 
    239 234234 0 0 0 0 0 0 0 0