繁体   English   中英

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

[英]How to reverse an array using pointers in c

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

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

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

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

我该如何运作? 我想念什么?

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

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

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

接下来,如果您在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

仔细检查一下,如果您有任何问题,请告诉我。

这段代码:

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]);
}
#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;
}

看一下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];

您的代码正在访问超出其大小的数组。 如果array的大小为10那么array的有效索引为09并且size - x将为您提供10因为此时x值为0 访问数组超出其大小是未定义的行为

reverseArray()函数中,您正在将numbers数组的特定元素的地址分配给指针ab而不是在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++;
    }
}

代码中还有其他问题,例如在swap()函数中使用int类型的temp变量来交换double精度类型值,不适当处理scanf()返回等。@ David C. Rankin在其帖子中对此进行了很好的解释。 。 重申它们没有任何意义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM