在C语言中如何反转数组?

5

您好,我正在尝试实现一个反转数组的代码,但似乎它不起作用,我真的不确定为什么。for循环似乎就是不起作用。我不知道为什么,因为逻辑看起来还是挺正确的。

#include <stdio.h>
#include <string.h>

void reverse(char, int);

int main()
{
    char a[100];
    gets(a);

    reverse(a, strlen(a)-1);

    printf("%s\n",a);
    getchar();
    getchar();
    getchar();
    return 0;
}

void reverse(char ar[], int n)
{
    char c;
    int i = 0;
    printf("n = %d" , n);
    for ( i = 0; i >= n ; i++){
        c = ar[i];
        ar[i] = ar[n];
        ar[n] = c;
        printf("Processed");
        n--;}

}


/*
if (begin >= n)
return;

c          = *(x+begin);
*(x+begin) = *(x+n);
*(x+n)   = c;
offs = x++;
printf("Begin = %d   ,  n = %d, offs = %p  \n", begin, n, offs);
reverse(x, ++begin, --n); */

4
你可能希望从让你的原型与实际功能相匹配开始。 - WhozCraig
1
也许应该是 i<=n ?! - hasanoviz
下面有一段被注释掉的代码,当我传递三个参数时可以正常工作,但我希望将其限制为仅传递两个参数,即字符串和其长度。 - JoC
只是出于好奇,为什么要传递长度。您是否想在部分字符串上调用此函数?还是从reverse()调用strlen()不在这个任务的范围内? - WhozCraig
旁注:有更直接的方法可以做到这一点,如果您对替代方案感兴趣的话 - WhozCraig
显示剩余2条评论
5个回答

5
void reverse(char, int);  //declaration wrong

void reverse(char[], int);
                 ^^^ 

你的循环
for ( i = 0; i >= n ; i++) // this fails i=0, n=some size

应该是

for ( i = 0; i <= n ; i++)

避免使用gets(),改用fgets()

reverse 函数内对该数组所做的更改是否会在之后生效?因为并不是指针作为参数被发送。 - hasanoviz
1
数组在C语言中只是简单的命名地址。该地址作为指针传递给函数。它们是C语言传值惯用语的例外,但并不完全如此。它们的“值”就是它们的地址。大多数工程师称这种地址同义词为“指针衰减”,尽管我发现这个标语通常很烦人,因为“衰减”一词在整个C99标准中只出现了一次,而且它的出现与将数组传递给函数没有任何关系。 - WhozCraig
正如WhozCraig所说,“在C语言中,数组只是具有命名地址的变量。该地址以指针值的形式传递给函数。”我在WhozCriag的解释中添加了这个例子。http://ideone.com/B9e5hG - Gangadhar

1

for循环条件应为“i < n”。原型声明应匹配。


0

for循环条件应该是“i < n”。原型声明也应该匹配。

而“int n”是数组的大小。所以“i<=n”会使得同一个数组从末尾到中间再到顶部反转。因此结果与数组相同。将“n”设为数组大小的一半。


1
他不需要将n除以二,因为在循环中他对其进行了递减,尽管这很容易被忽略。 - Dmitri

0

我认为最好使用宏来完成这个任务。在下面的代码中,有一个名为SWAP的宏。


内容是一个名为 main.c 的文件

#include <string.h>
#include <stdio.h>

// swap values with respect a type it
#ifndef SWAP
    #define SWAP(type, a, b) \
    { \
        type temp = a; \
        a = b; \
        b = temp; \
    }
#endif


/*
    Print an array integer items
 */
void
printIntArray(int array[], size_t length) {
    char ending_charapter[] = ", ";
    putchar('[');
    for (size_t i = 0; i < length; ++i) {
        printf("%d", array[i]);
        if (i < length - 1) {
            printf("%s", ending_charapter);
        }
    }
    puts("]");
}


/*
    Print an array float items
 */
void
printFloatArray(float array[], size_t length) {
    char ending_charapter[] = ", ";
    putchar('[');
    for (size_t i = 0; i < length; ++i) {
        printf("%f", array[i]);
        if (i < length - 1) {
            printf("%s", ending_charapter);
        }
    }
    puts("]");
}


/*
    Reverse an integer array in place
 */
static int
reverseIntArray(int *array, const size_t length) {
    for (int i = 0; i < length / 2; ++i) {
        SWAP(int, array[i], array[length - i - 1]);
    }
    return 0;
}


/*
    Reverse an float array in place
 */
static int
reverseFloatArray(float *array, const size_t length) {
    for (int i = 0; i < length / 2; ++i) {
        SWAP(float, array[i], array[length - i - 1]);
    }
    return 0;
}


/*
    Reverse an string
 */
static int
reverseString(char string[]) {
    size_t str_len = strlen(string);
    for (int i = 0; i < str_len / 2; ++i) {
        SWAP(char, string[i], string[str_len - i - 1]);
    }
    return 0;
}


int
main (const int argc, const char *argv[])
{
    puts("An example reverse for a int array");
    int arrInt[4] = {1, -2, 3, -4};
    printIntArray(arrInt, 4);
    reverseIntArray(arrInt, 4);
    printIntArray(arrInt, 4);

    puts("An example reverse for a float array");
    float arrFloat[4] = {0.1, -2.12, 1.3, -4.2};
    printFloatArray(arrFloat, 4);
    reverseFloatArray(arrFloat, 4);
    printFloatArray(arrFloat, 4);

    puts("An example reverse for a string");
    char str[] = "Simple text";
    puts(str);
    reverseString(str);
    puts(str);

    return 0;
}

编译为:

gcc std=c11 -I /usr/include/ -o main main.c

结果:

An example reverse for a int array
[1, -2, 3, -4]
[-4, 3, -2, 1]
An example reverse for a float array
[0.100000, -2.120000, 1.300000, -4.200000]
[-4.200000, 1.300000, -2.120000, 0.100000]
An example reverse for a string
Simple text
txet elpmiS

注意:

  1. 只适用于工作
  2. 适用于任何内置类型
  3. 测试不充分,仅使用GCC编译器
  4. 基于

    4.1 定义一个预处理宏swap(t,x,y)

    4.2 原地反转数组

    4.3 这个问题的答案


测试环境

$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description:    Debian GNU/Linux 8.6 (jessie)
Release:    8.6
Codename:   jessie
$ uname -a
Linux localhost 3.16.0-4-amd64 #1 SMP Debian 3.16.36-1+deb8u2 (2016-10-19) x86_64 GNU/Linux
$ gcc --version
gcc (Debian 4.9.2-10) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

-1

不得不说,在“反转函数”中,似乎你处理的事情太多了。我个人喜欢尽可能地拆分代码,这样更容易发现错误。

首先,你可能想把交换过程(for循环)放到自己的函数中,称为“swap”。你可以使用char指针'a'和'b'作为参数来做到这一点。


将代码分解为较小的单元是一个好的实践,但这并不能真正回答问题。此外,在 https://dev59.com/t3fZa4cB1Zd3GeqPW9oK#42063309 中通过使用宏来隐含表示这一点。 - Jason Warner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接