Swapping 2 arrays in C

生来就可爱ヽ(ⅴ<●) 提交于 2021-02-10 12:01:19

问题


I need to swap the values of 2 arrays in a function. The problem is I can change anything in the main, just the function itself. It should recive 2 integer arrays, and swap those. The problem is, that I don't know the size of the arrays, and for my understading they can even be in diffrent sizes. Trying this code:

    int main()
{
    int size = 4;  //Please notice that I'm using this only to print the array
    int a[] = {1,2,3,4};
    int b[] = {5,6,7,8};
    printArr(a,"a",size);
    printArr(b,"b",size);
    swapArray(a,b);
    printf("Swapped:\n");
    printArr(a,"a",size);
    printArr(b,"b",size);
}

and this function:

 void swapArray(int **a,int **b)
{
    int *p = *a;
    *a = *b;
    *b = p;
}

while printArr simply prints the array:

void printArr(int arr[],char name[],int size)
{
    printf("%s:\t",name);
    for(int i=0;i<size;i++){
        printf("%d\t",arr[i]);
    }
    printf("\n");
}

I got a really weird result:

a:   1    2    3   4
b:   5    6    7   8
Swapped:
a:   5    6    3   4
b:   1    2    7   8

I would like to understand why it happens, and not only a working solution. Thank you :)


回答1:


In this call

swapArray(a,b);

the argument expressions have the type int * while the function parameters have the type int **. There is no implicit conversion from the type int * to the type int **. So the compiler shall issue a diagnostic message.

In any case the swap function as it is implemented does not make sense. Your program has undefined behavior at least because it tries to swap pointers instead of the arrays themselves.

Take into account that arrays are not pointers though in expressions with rare exceptions they indeed are implicitly converted to pointers to their first elements.

To swap elements of two arrays you have to swap each pair of elemenets separatly. And you have to supply the number of elements in the arrays. Otherwise the arrays need to have a sentinel value.

Here is a demonstrative program that shows how the function swap can be defined.

#include <stdio.h>

void printArr( const int a[], size_t n, const char *s )
{
    printf( "%s:\t", s );

    for ( size_t i = 0; i < n; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

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;
    }
}

int main(void) 
{
    enum { N = 4 };
    int a[N] = { 1, 2, 3, 4 };
    int b[N] = { 5, 6, 7, 8 };

    printArr( a, N, "a" );
    printArr( b, N, "b" );
    putchar( '\n' );

    swapArray( a, b, N );


    printArr( a, N, "a" );
    printArr( b, N, "b" );
    putchar( '\n' );

    return 0;
}

Its output is

a:  1 2 3 4 
b:  5 6 7 8 

a:  5 6 7 8 
b:  1 2 3 4 

You could swap visual representations of original arrays using pointers. But in this case the arrays themselves will not be swapped.

Consider the following program.

#include <stdio.h>

void printArr( const int a[], size_t n, const char *s )
{
    printf( "%s:\t", s );

    for ( size_t i = 0; i < n; i++ )
    {
        printf( "%d ", a[i] );
    }
    putchar( '\n' );
}

void swapArray( int **a, int **b )
{
    int *tmp = *a;
    *a = *b;
    *b = tmp;
}

int main(void) 
{
    enum { N = 4 };
    int a[N] = { 1, 2, 3, 4 };
    int b[N] = { 5, 6, 7, 8 };

    printArr( a, N, "a" );
    printArr( b, N, "b" );
    putchar( '\n' );

    int *pa = a;
    int *pb = b;

    swapArray( &pa, &pb );

    printArr( pa, N, "pa" );
    printArr( pb, N, "pb" );
    putchar( '\n' );

    printArr( a, N, "a" );
    printArr( b, N, "b" );
    putchar( '\n' );

    return 0;
}

Its output is

a:  1 2 3 4 
b:  5 6 7 8 

pa: 5 6 7 8 
pb: 1 2 3 4 

a:  1 2 3 4 
b:  5 6 7 8 

As you see the arrays were not swapped. However the pointers that point to first elements of the arrays were swapped. Using the pointers you can simulate swapping of arrays.

Opposite to C C++ has a template function std::swap for arrays that can be called indeed simply like

std::swap( a, b );



回答2:


I guess on your platform the size of the pointer is 64 bit, and the size of an in is 32 bit.

When calling swapArray, the compiler implicitly reinterprets your arrays of int as an array of pointers. (These are pointers to int but this is irrelevant here). swapArray then just swaps the first element of these pointer arrays.

Luckily your original int arrays are large enough so that no illegal access happens.

Since pointer is 64 bit is corresponds to two int which get swapped.




回答3:


In C an array is not a single "thing" you can swap. You will need to swap it element-by-element.

The only case in which you can swap these array "things" in one time is if they are pointers to arrays.

int *a = malloc(n*sizeof(int));
int *b = malloc(n*sizeof(int));
int *tmp;
tmp=a; a=b; b=tmp;


来源:https://stackoverflow.com/questions/49751409/swapping-2-arrays-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!