首页 > 解决方案 > 在 C 中通过引用传递数组

问题描述

我正在尝试通过引用传递数组来修改来自 GeekstoGeeks 的合并排序代码。

/* C program for Merge Sort */
#include <stdio.h> 
#include <stdlib.h> 

// Merges two subarrays of arr[]. 
// First subarray is arr[l..m] 
// Second subarray is arr[m+1..r] 
void merge(int arr[], int l, int m, int r) 
{ 
    int i, j, k; 
    int n1 = m - l + 1; 
    int n2 = r - m; 

    /* create temp arrays */
    int L[n1], R[n2]; 

    /* Copy data to temp arrays L[] and R[] */
    for (i = 0; i < n1; i++) 
        L[i] = arr[l + i]; 
    for (j = 0; j < n2; j++) 
        R[j] = arr[m + 1 + j]; 

    /* Merge the temp arrays back into arr[l..r]*/
    i = 0; // Initial index of first subarray 
    j = 0; // Initial index of second subarray 
    k = l; // Initial index of merged subarray 
    while (i < n1 && j < n2) { 
        if (L[i] <= R[j]) { 
            arr[k] = L[i]; 
            i++; 
        } 
        else { 
            arr[k] = R[j]; 
            j++; 
        } 
        k++; 
    } 

    /* Copy the remaining elements of L[], if there 
    are any */
    while (i < n1) { 
        arr[k] = L[i]; 
        i++; 
        k++; 
    } 

    /* Copy the remaining elements of R[], if there 
    are any */
    while (j < n2) { 
        arr[k] = R[j]; 
        j++; 
        k++; 
    } 
} 

/* l is for left index and r is right index of the 
sub-array of arr to be sorted */
void mergeSort(int arr[], int l, int r) 
{ 
    if (l < r) { 
        // Same as (l+r)/2, but avoids overflow for 
        // large l and h 
        int m = l + (r - l) / 2; 

        // Sort first and second halves 
        mergeSort(arr, l, m); 
        mergeSort(arr, m + 1, r); 

        merge(arr, l, m, r); 
    } 
} 

/* UTILITY FUNCTIONS */
/* Function to print an array */
void printArray(int A[], int size) 
{ 
    int i; 
    for (i = 0; i < size; i++) 
        printf("%d ", A[i]); 
    printf("\n"); 
} 

/* Driver program to test above functions */
int main() 
{ 
    int arr[] = { 12, 11, 13, 5, 6, 7 }; 
    int arr_size = sizeof(arr) / sizeof(arr[0]); 

    printf("Given array is \n"); 
    printArray(arr, arr_size); 

    mergeSort(arr, 0, arr_size - 1); 

    printf("\nSorted array is \n"); 
    printArray(arr, arr_size); 
    return 0; 
} 

对于这样的事情:

void mergeSort(int* arr[], int l, int r);
void merge(int* arr[], int l, int m, int r);

我认为这是一项简单的任务,因为我可以简单地将函数中的每个 arr 更改为 *arr 以取消引用它们。该程序仍然可以运行,但给了我一堆未知数字。

然后我搜索了堆栈溢出,直到看到这篇文章: https ://stackoverflow.com/questions/49751409/swapping-2-arrays-in-c#:~:text=Since%20pointer%20is%2064%20bit,two% 20int%20which%20get%20swapped.&text=In%20C%20an%20array%20is,他们%20are%20pointers%20to%20arrays

它还通过引用传递一个数组。(int* a 和 int* b)

void swapArray( int *a, int *b, size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        int tmp = a[i];
        a[i] = b[i];
        b[i] = tmp;
    }
}

但反过来,当我将其更改为

void swapArray( int a, int b, size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        int tmp = a[i];
        a[i] = b[i];
        b[i] = tmp;
    }
}

又不行了 有人可以向我解释为什么以及如何正确修改我的合并排序代码吗?或者我应该去哪里寻找?我对此很困惑。任何帮助表示赞赏。

标签: arrayscfunctionreference

解决方案


int *arr[]是一个指针数组。或者更确切地说,它是指向指针的指针(实际上是int **arr)。

要将指针传递给数组(几乎从不需要),您需要例如int (*arr) [6]. 是的,数组的大小是强制性的(可变长度数组是有效的)。

但正如我所说,几乎不需要将指针传递给数组,因为数组自然会衰减为指针(指向它们的第一个元素)。

并且作为参数声明int arr[]等于int *arr.

也就是说,与

void merge(int arr[], int l, int m, int r) 

您已经通过“引用”传递了数组。


推荐阅读