如何使用C中的指针反转数组

时间:2019-03-21 01:58:27

标签: c arrays

我正在尝试使用例如指针打印数组的反面。输入为4 8 15 7,我想打印7 15 8 4。

当我运行它时,它会反转一些数字,但不是全部吗?有时它不会反转任何数字。我很困惑。

我需要它来处理数组中未知数量的元素,这就是为什么我在'readIntoArray'和'printArray'中使用while循环的原因。我真的只是在为“ reverseArray”和“ swap”而苦苦挣扎。

void reverseArray(double numbers[], int size);
void printArray(double numbers[], int size);
int readIntoArray(double numbers[]);
void swap(double *a, double *b);

int main(void) {
    double numbers[MAX_SIZE];
    int size = readIntoArray(numbers);
    reverseArray(numbers, size);
    printArray(numbers, size);
    return 0;
}

int readIntoArray(double numbers[]) {
    double in;
    int i = 0;
    while (i < MAX_SIZE && scanf("%lf", &in) != 0) {
        numbers[i] = in;
        i++;
    }
    return i;
}

void reverseArray(double numbers[], int size){
    int x = 0;
    double *a = &numbers[x];
    double *b = &numbers[size - x];
    double temp;
    while (x < size){
        swap(a,b);
        x++;
    }
}

void printArray(double numbers[], int size){
    int i = 0;
    while (i<size){
        printf("%lf ", numbers[i]);
        i++;
    }
}

void swap (double *a, double *b){
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

我如何使其工作?我想念什么?

4 个答案:

答案 0 :(得分:2)

您有很多明显的问题,但是主要的问题是您在swap中使用了不同的类型大小,例如

void swap (double *a, double *b){
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

您要提供类型double作为参数(通常为8个字节的值),但随后使用int temp;(通常为4个字节的值)作为临时指针。因此,即使其他所有内容都正确,您也只会将*a的前4个字节存储在temp中。

接下来,如果您在整个范围0 < size内进行反向操作,则最终将交换两次(返回到开始的位置)。相反,您希望在0 < size / 2范围内交换每个结束元素。例如:

void reverseArray(double numbers[], size_t size){
    for (size_t i = 0; i < size / 2; i++)
        swap (&numbers[i], &numbers[size - i - 1]);
}

注意:计数器通常应为size_t而不是int(您的行数不能为负)

此外,您需要修复scanf验证。 scanf() != 0允许scanf() = EOF测试TRUE,这显然不是您想要的。您可以针对转化说明符数量来验证返回值 ,例如

size_t readIntoArray(double numbers[]) {
    double in;
    size_t i = 0;
    while (i < MAX_SIZE && scanf("%lf", &in) == 1) {    /* <== here */
        numbers[i] = in;
        i++;
    }
    return i;
}

将其完全放入并重构代码以避免使用函数原型,您可以:

#include <stdio.h>

#define MAX_SIZE  128

size_t readIntoArray(double numbers[]) {
    double in;
    size_t i = 0;
    while (i < MAX_SIZE && scanf("%lf", &in) == 1) {
        numbers[i] = in;
        i++;
    }
    return i;
}

void swap (double *a, double *b){
    double temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

void reverseArray(double numbers[], size_t size){
    for (size_t i = 0; i < size / 2; i++)
        swap (&numbers[i], &numbers[size - i - 1]);
}

void printArray(double numbers[], size_t size){
    int i = 0;
    while (size--)
        printf("%g ", numbers[i++]);
    putchar ('\n');
}

int main(void) {

    double numbers[MAX_SIZE] = { 0 };
    size_t size = readIntoArray(numbers);
    reverseArray (numbers, size);
    printArray (numbers, size);

    return 0;
}

使用/输出示例

$ echo "4 8 15 7" | ./bin/revarrswap
7 15 8 4

仔细研究一下,如果您有任何疑问,请告诉我。

答案 1 :(得分:1)

此代码:

double *a = &numbers[x];
double *b = &numbers[size - x];
double temp;
while (x < size){
    swap(a,b);
    x++;
}

从不更改a和b的值。即使您正在修改x,也已经将这些变量的第一个和最后一个元素的地址分配给了这些变量,然后将它们交换为所有x值。

一种更好的实现,应该可以实现您的预​​期目标:

for (unsigned i = 0; i != size/2; i++) {
    swap(&numbers[i], &numbers[size-i-1]);
}

答案 2 :(得分:0)

#include <stdio.h>

void swap(double *a, double *b){
    int temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

void reverse(double numbers[], int size) {
    int half = size / 2;

    for (int i = 0; i < half; i++) {
        swap(numbers[i], numbers[size-1-i]);
    }
}

int main() {
    double ns[5] = {1,2,3,4,5};

    reverse(ns, 5);

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

    return 0;
}

答案 3 :(得分:0)

查看reverseArray()函数:

void reverseArray(double numbers[], int size){
    int x = 0;
    double *a = &numbers[x];
    double *b = &numbers[size - x];
    double temp;
    while (x < size){
        swap(a,b);
        x++;
    }
}

首先,在这里

double *b = &numbers[size - x];

您的代码正在访问超出其大小的数组。如果数组的大小为10,则数组的有效索引为09,而size - x会给您10,因为在此时x的值为0。正在访问超出其大小的数组是undefined behavior

reverseArray()函数中,您将numbers数组的特定元素的地址分配给指针ab,而不在{{1}内更改它们}循环。在循环的每次迭代中,while函数最终都会交换相同的两个指针的值,并从这两个指针中换出一个,即指向数组之外。此外,该循环正在迭代swap()次。相反,它应该仅迭代size次。

size / 2应该像这样:

reverseArray()

代码中还有其他问题,例如在void reverseArray(double numbers[], int size){ int x = 0; while (x < size / 2){ swap(&numbers[x], &numbers[(size - 1) - x]); x++; } } 函数中使用temp类型的int变量来交换swap()类型的值,而不处理double返回适当的等。@ David C. Rankin在他的帖子中对此进行了很好的解释。重申它们没有任何意义。