简体   繁体   中英

How to reverse an array using pointers in c

I'm trying to print the reverse of an array using pointers eg. input is 4 8 15 7, I want to print 7 15 8 4.

When I run it, it reverses some numbers but not all? Sometimes it doesn't reverse any numbers. I am very confused.

I need it to work for an unknown number of elements in the array, which is why I used the while loops in 'readIntoArray' and 'printArray'. I'm really just struggling with 'reverseArray' and '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;
}

How do I make it work? What am I missing?

You have a number of glaring issues, but the primary problem is your use of differing type sizes in swap , eg

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

You are providing type double as a parameter (generally an 8-byte value), but then using int temp; (generally a 4-byte value) as your temporary pointer. So even if you have everything else correct, you are only storing the first 4-bytes of *a in temp .

Next, you will end up swapping twice (ending up back where you started) if you reverse over the full range 0 < size . Instead, you on want to swap each end element over the range 0 < size / 2 . For example:

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

( note: counters should generally be size_t instead of int (you cannot have a negative line count))

Further, you need to fix you scanf validation. scanf() != 0 allows scanf() = EOF to test TRUE which is obviously not what you want. You validate the return against the number of conversion specifiers , eg

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

Putting it altogether, and refactoring your code to avoid the need for function prototypes, you could do:

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

Example Use/Output

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

Look things over and let me know if you have questions.

This code:

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

Never changes the values of a and b. Even though you are modifying x, you have already assigned the addresses of the first and one-after-the-last elements to these variables and proceed swapping them for all values of x.

A somewhat better implementation which should achieve what you intended:

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

Look at the reverseArray() function:

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

First of all, here

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

your code is accessing array beyond its size. If the size of array is, lets say, 10 then the valid indexes of array are from 0 to 9 and size - x will give you 10 because at this point the value of x is 0 . Accessing array beyond its size is undefined behavior .

In reverseArray() function, you are assigning the address of specific elements of numbers array to the pointers a and b and not changing them within the while loop. In every iteration of loop the swap() function end up swapping the value of same two pointers and out of those two pointers, one is pointing beyond array. Moreover, the loop is iterating size times. Instead, it should iterate only for size / 2 times.

The reverseArray() should be like this:

void reverseArray(double numbers[], int size){
    int x = 0;
    while (x < size / 2){
        swap(&numbers[x], &numbers[(size - 1) - x]);
        x++;
    }
}

There are other problems in the code like use of temp variable of type int in swap() function to swap double type values, not handling scanf() return appropriately etc. which has been very well explained by @David C. Rankin in his post. It doesn't make any sense to reiterate them.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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