繁体   English   中英

C:反向字符串功能不影响指针

[英]C: reverse string function not affecting pointer

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

int reverse(char *, int);

main()
{
    char *word = "Thanks for your help";

    reverse(word, strlen(word));
    printf("%s", word);     

    getchar();

}

int reverse(char *line, int len)
{
    int i, j;
    char *newline = malloc(strlen(line));

    for (i = len - 1, j = 0 ; i >= 0; i--, j++)
    {
        newline[j] = line[i];
    }
    newline[j] = '\0';
    line = &newline;
}

嘿伙计。 我有一个似乎无法解决的简单C问题。

上面的程序用于接收字符串并向后打印。 反向是完成此功能的功能。

具体地说,问题是当我在main()中打印单词时,字符串看起来没有变化。 我试图将line的地址设置为newline的地址,但是它没有任何作用。

int reverse(char *line, int len)
{
    int i, j;
    char *newline = malloc(strlen(line));

    for (i = len - 1, j = 0 ; i >= 0; i--, j++)
    {
        newline[j] = line[i];
    }
    newline[j] = '\0';
    line = &newline;             // Your problem is here
}

您只是分配给本地line指针。 这对调用函数没有任何影响。

考虑改为:

char *reverse(char *line, int len)
{
    // ...
    return newline;
}

其他建议:

  • 打开编译器警告, 并注意它们 您有很多小错误(例如, reverse目前未返回任何内容,但被声明为return int )。
  • 鉴于reverse的第一个参数是一个指向C字符串(以NUL终止)的指针,因此也不需要采用length参数。
  • reverse函数不一定需要定义为返回字符串的副本reversed 相反,它可以就地反转字符串。 请注意,您不能将字符串文字传递给此类函数,因为它们是只读的。

这是我的写法:

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

void reverse(char *str)
{
    size_t i, j;
    for (i = strlen(str) - 1, j = 0 ; i > j; i--, j++)
    {
        // Swap characters
        char c = str[i];
        str[i] = str[j];
        str[j] = c;
    }
}

int main(void)
{
    // Mutable string allocated on the stack;
    // we cannot just pass a string literal to reverse().
    char str[] = "Here is a test string";

    reverse(str);

    printf("Result: \"%s\"\n", str);
    return 0;
}

请注意, for循环条件是i > j ,因为我们希望每个循环仅遍历数组的一半,而不要交换每个字符两次。

结果:

$ ./a.exe
Result: "gnirts tset a si ereH"

看一下下面的代码:

void addOne(int a) {
   int newA = a + 1;
   a = newA;
}

int main() {
  int num = 5;
  addOne(num);
  printf("%d\n", num);
}

您知道为什么会打印5,而不是6吗? 这是因为当您将num传递给addOne ,实际上是制作了num的副本。 addOnea更改为newA ,它将更改副本(称为a ),而不是原始变量num C具有按值传递的语义。

您的代码也遇到相同的问题(以及其他一些问题)。 当您调用reverse ,将生成word的副本(不是字符串的副本,而是指向字符串的字符指针的副本)。 当您将line更改为指向新字符串newLine ,您实际上并没有更改传入的指针。 您正在更改指针的副本。

那么,您应该如何实施逆向? 这取决于:有两种选择。

  1. reverse可以返回包含原始字符串的新分配的字符串,即为反向。 在这种情况下,您的函数签名应为char *reverse ,而不是int reverse。
  2. reverse可以修改原始字符串。 也就是说,您永远不会分配新的字符串,而只需移动原始字符串的字符即可。 通常,这是可行的,但不适用于您的情况,因为用字符串文字初始化的char指针不一定指向可写内存。
  3. reverse实际上可以更改传入的指针以指向新字符串(您在当前代码中尝试执行的操作)。 为此,您必须编写一个函数void reverse(char **pointerToString) 然后,您可以分配*pointerToString = newLine; 但这不是一个好习惯。 现在无法访问原始传入的参数,并且如果已对其进行了malloc分配,则无法将其释放。

暂无
暂无

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

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