#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()中打印单词时,字符串看起来没有变化。我试图将换行地址作为换行符的地址,但它没有任何效果。
答案 0 :(得分:3)
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"
答案 1 :(得分:0)
看看下面的代码:
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指针不一定指向可写内存。void reverse(char **pointerToString)
。然后你可以分配*pointerToString = newLine;
。但这不是很好的做法。原来的传入参数现在无法访问,如果它是malloc,则无法释放。