就地vs返回C中的新设计模式

jon*_*ohn 2 c arrays design-patterns memory-management

来自更高级别的语言,我试图通过学习c来改变自己.我正在尝试理解指针和内存分配(我之前从未考虑过的事情).

我正在尝试的代码

#include <stdio.h>

int main()
{

    int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52 };

    printf("\nShuffling...\n\n");
    shuffle(array, sizeof(array)/sizeof(int));

    int i;
    for(i = 0; i < sizeof(array)/sizeof(int); i++)
    {
        printf("%d\n", array[i]);
    }

}

int shuffle(int *shuffle_array, int length)
{
    int i, j, newArray[length];
    for(i = 0, j = length; i < length; j--, i++)
    {
        newArray[i] = shuffle_array[j];
    }

    shuffle_array = newArray;
}
Run Code Online (Sandbox Code Playgroud)

首先,这不起作用,我试图弄清楚为什么阵列在打印时不会反转.

其次,比较就地编辑的概念与使用malloc()和返回c中的新项目free().

Set*_*gie 7

在里面shuffle,你正在创建一个newArray在堆栈上调用的数组(这意味着它将在函数结束时被释放).

然后,您将每个项目shuffle_array放入newArray后退.

然后你正在制作指针shuffle_array,一个局部变量(这意味着它的变化不会反映在函数之外),指向第一个元素newArray.这不会改变任何外部shuffle因为shuffle_array是局部变量.

函数返回后,函数外部的任何内容都没有发生.这是因为您只是在修改本地数据shuffle.

要对阵列进行洗牌(或对其进行反转,或对其执行任何操作),您必须直接修改它而不是修改副本.所以它应该是

int tmp = shuffle_array[i];
shuffle_array[i] = shuffle_array[j];
shuffle_array[j] = tmp;
Run Code Online (Sandbox Code Playgroud)

这样你就可以交换你所在的数组元素的两个值.即使它shuffle_array是一个临时变量,它指向内存块main,因此即使在函数返回后修改该内存也是可见的.

你可以像这样形象化它:

main:

array  - - - - 
               \
                \
                 1, 2, 3, 4, 5, ...,  52 };
Run Code Online (Sandbox Code Playgroud)

何时shuffle被召唤:

array  - - - - 
               \
                \
                 1, 2, 3, 4, 5, ...,  52
                /
               /
              /
shuffle_array

newArray - - -
              \
               52, ..., 5, 4, 3, 2, 1
Run Code Online (Sandbox Code Playgroud)

然后当你这样做

shuffle_array = newArray;
Run Code Online (Sandbox Code Playgroud)

看起来像

array  - - - - 
               \
                \
                 1, 2, 3, 4, 5, ...,  52



shuffle_array -
               \
newArray - - -  |
              \ /
               52, ..., 5, 4, 3, 2, 1
Run Code Online (Sandbox Code Playgroud)

然后shuffle返回,一切都回归正义

array  - - - - 
               \
                \
                 1, 2, 3, 4, 5, ...,  52
Run Code Online (Sandbox Code Playgroud)