使用指针c反转数组

时间:2017-06-06 12:22:00

标签: c arrays algorithm pointers reverse

我正在尝试编写一个接收输入数字和整数的代码,然后反转这些顺序并打印出来。当我运行此代码时,它会从input_integer函数中的for循环中冻结。我做错了什么?

# include <stdio.h>
# include <stdlib.h>

void input_integer (int *arr, int *arrSize);
void inverse_reorder (int *arr, int *arrSize);

int main (void){
    int* arrSize;
    int* arr;
    int i;

    input_integer(arr, arrSize);
    printf("inputted data : ");
    for ( i = 0; i < *arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }
    inverse_reorder(arr, arrSize);
    printf("reversed data : ");
    for ( i = 0; i < *arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }

    return 0;
}

void input_integer (int* arr, int *arrSize){
    printf("Array size = ? ");
    scanf("%d", arrSize);
    int i;
    for( i = 0; i < *arrSize ; i++ ){
        scanf("%d", *(arr + i));
    }   
}

void inverse_reorder (int * arr, int *arrSize){
    int i;
    int temp = 0;
    for ( i = 0; i < *arrSize ; i++ ){
        temp = *(arr+i);
        *(arr+i) = *(arr + *arrSize - i);
        *(arr + *arrSize - i) = temp;
    }
}

5 个答案:

答案 0 :(得分:1)

%d中的scanf格式说明符需要int*作为参数。但是,在执行此操作时,您将取消引用指针:*(arr + i)。您不需要*

但是,在main函数中,您声明了两个指向不指向任何位置的指针。你需要分配一些存储空间,例如。

int main (void){
    int arrSize;
    int i;

    int* arr = input_integer(&arrSize);

我更改了input_integer以返回数组的int指针。

input_integer将根据输入数组大小分配存储空间:

int* input_integer (int *arrSize){
    printf("Array size = ? ");
    scanf("%d", arrSize);
    // Should really validate the size here
    int *arr = calloc(*arrSize, sizof *arr); 
    int i;
    for( i = 0; i < *arrSize ; i++ ){
        scanf("%d", arr + i);
    } 
    return arr;  
}

然后你的main函数应该总是使用arrSize而不取消引用它,并且最后释放指针。

答案 1 :(得分:1)

您将arrSize声明为int *,但您从未为该指针指定值,因此它的值是不确定的。当您稍后将该指针的值传递给scanf时,它会读取该垃圾值并尝试写入该无效地址。这会调用未定义的行为。您也永远不会为arr分配空间。此外,当您读入每个数组元素时,您传入的是数组值而不是数组元素的地址。

您应在arrSize函数中将int声明为main,然后将其地址传递给input_integer以填充它。然后在input_integer中,您需要使用malloc为数组分配空间。您还需要传递arr的地址才能写入。

int main (void){
    int arrSize;
    int *arr;
    int i;

    input_integer(&arr, &arrSize);
    printf("inputted data : ");
    for ( i = 0; i < arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }
    inverse_reorder(arr, arrSize);
    printf("reversed data : ");
    for ( i = 0; i < arrSize ; i++ ){
        printf("%d, ", *(arr + i));
    }

    return 0;
}

void input_integer (int **arr, int *arrSize){
    printf("Array size = ? ");
    scanf("%d", arrSize);
    *arr = malloc(*arrSize * sizeof(int));
    if (*arr == NULL) {
        perror("malloc failed");
        exit(1);
    }
    int i;
    for( i = 0; i < *arrSize ; i++ ){
        scanf("%d", *arr + i);
    }   
}

void inverse_reorder (int *arr, int arrSize){
    int i;
    int temp = 0;
    for ( i = 0; i < arrSize ; i++ ){
        temp = *(arr+i);
        *(arr+i) = *(arr + arrSize - i);
        *(arr + arrSize - i) = temp;
    }
}

答案 2 :(得分:0)

arrSize不是指针,它应该是程序运行的值。 您不能将循环中的递增i与arrSize的参考值进行比较,否则它将循环长和长,因为循环的限制将是指针地址。 你应该只在写作时才能访问指针,而不是在阅读时(除非它是预期的)。

答案 3 :(得分:0)

变量arrSizearr未初始化且具有不确定的值

int* arrSize;
int* arr;

但是在内部例如函数input_integer中使用了它们的不确定值。

结果整个程序有不确定的行为。

无需将变量arrSize声明为指针。

必须通过引用将变量arr传递给函数input_integer。否则该函数将处理变量值的副本,并且不会更改变量的原始值。

因此该函数应至少声明为

void input_integer (int **arr, int *arrSize);
                        ^^^^^

函数inverse_reorder实际上并没有颠倒数组元素的顺序。也就是说,它会将原始订单作为结果反转两次。

您还需要释放已分配的数组。

程序和功能可以按以下方式查看

#include <stdio.h>
#include <stdlib.h>

void input_integer( int **a, size_t *n );
void inverse_reorder( int *a, size_t n );

int main(void) 
{
    int *a;
    size_t n;

    input_integer( &a, &n );

    if ( n )
    {
        printf( "inputted data : " );

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

        inverse_reorder( a, n );

        printf( "reversed data : " );

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

        free( a );
    }

    return 0;
}

void input_integer( int **a, size_t *n )
{
    *a = NULL;
    *n = 0;

    printf( "Array size = ? " );

    if ( scanf( "%zu", n ) == 1 && *n != 0 )
    {
        *a = malloc( *n * sizeof( int ) );

        printf( "enter %zu integers: ", *n );
        for ( size_t i = 0; i < *n; i++ ) scanf( "%d", *a + i );
    }
}

void inverse_reorder( int *a, size_t n )
{
    for ( size_t i = 0; i < n / 2; i++ )
    {
        int tmp = *( a + i );
        *( a + i ) = *( a + n - i - 1 );
        *( a + n - i - 1 ) = tmp;
    }
}

程序输出

Array size = ? 10
enter 10 integers: 0 1 2 3 4 5 6 7 8 9
inputted data : 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 
reversed data : 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, 

您可以自行添加检查内存是否已成功分配。

答案 4 :(得分:0)

使用gcc -Wall编译程序。

reversing.c: In function ‘input_integer’:
reversing.c:31:13: warning: format ‘%d’ expects argument of type ‘int *’, but argument 2 has type ‘int’ [-Wformat=]
     scanf("%d", *(arr + i));
            ~^   ~~~~~~~~~~
reversing.c: In function ‘main’:
reversing.c:12:3: warning: ‘arr’ is used uninitialized in this function [-Wuninitialized]
   input_integer(arr, arrSize);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~
reversing.c:12:3: warning: ‘arrSize’ is used uninitialized in this function [-Wuninitialized]