C:反向字符串函数不影响指针
Posted
技术标签:
【中文标题】C:反向字符串函数不影响指针【英文标题】:C: reverse string function not affecting pointer 【发布时间】:2015-11-15 23:15:07 【问题描述】:#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() 中打印 word 时,字符串看起来没有改变。我试图将 line 的地址作为换行符的地址,但它没有任何效果。
【问题讨论】:
参数按值传递;更改reverse
中的 line
指向的内容并不会在其调用者中执行相同的操作。如果你想生成一个新字符串,你应该只返回一个char*
;如果意图是反转字符串,您可以这样做(并且根据定义必须这样做)而不分配额外的空间。
line = &newline;
是非法的 - 注意编译器消息
【参考方案1】:
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
目前没有返回任何内容,但被声明为返回 int
)。
鉴于 reverse
的第一个参数是指向 C 字符串(以 NUL 结尾)的指针,因此也无需使用长度参数。
reverse
函数不一定需要定义为返回字符串的副本,反转。相反,它可以反转字符串就地。请注意,您不能将字符串文字传递给这样的函数,因为它们是只读的。
我会这样写:
#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"
【讨论】:
【参考方案2】:看看下面的代码:
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
。当addOne
将a
更改为newA
时,它正在更改副本(称为a
),而不是原始变量num
。 C 具有按值传递的语义。
您的代码遇到了同样的问题(以及其他一些问题)。当您调用reverse
时,会生成word
的副本(不是字符串的副本,而是指向字符串的字符指针的副本)。当您更改line
以指向您的新字符串newLine
时,您实际上并没有更改传入的指针;您正在更改指针的副本。
那么,你应该如何实现反向呢?这取决于:有几个选项。
reverse
可以返回一个新分配的包含原始字符串的字符串,反转。在这种情况下,您的函数签名将是 char *reverse
,而不是 int reverse。
reverse
可以就地修改原始字符串。也就是说,您永远不会分配新字符串,而只是移动原始字符串的字符。这通常有效,但不适用于您的情况,因为使用字符串文字初始化的 char 指针不一定指向可写内存。
reverse 实际上可以将传入的指针更改为指向新字符串(您在当前代码中尝试执行的操作)。为此,您必须编写一个函数void reverse(char **pointerToString)
。然后你可以分配*pointerToString = newLine;
。但这不是很好的做法。原始传入的参数现在无法访问,如果它是 malloc 的,则无法释放它。
【讨论】:
以上是关于C:反向字符串函数不影响指针的主要内容,如果未能解决你的问题,请参考以下文章
编写一个函数 reverse_string(char * string)实现:将参数字符串中的字符反向排列 。(递归实现)