我发现了一些有趣的东西,但无法解释。 我正在编写一个简单的例程来反转字符串。这很好,没有抱怨。
我的问题出在printf
。当我单独打印原始字符串时,它打印正确,但是当我打印原始字符串作为第一个arg,而函数调用reverse作为第二个时,都显示为反转。
输出:
|| abcdthelgko ||
Orig Str:| okglehtdcba |,Rev Str | okglehtdcba |
代码:
char* ReverseStr(char* str, int len)
{
char *start = &str[0], *end = &str[len-1];
char temp;
while(start < end)
{
temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
return str;
}
int main()
{
char str_unique[] = "abcdthelgko";
int str_unique_len = sizeof(str_unique)/sizeof(str_unique[0]);
printf("\n || %s || \n", str_unique);
printf("Orig Str: | %s |, Rev Str | %s |\n", str_unique, ReverseStr(str_unique, str_unique_len-1));
return 0;
}
*反馈后的修改:* 测试2个理论 1. Printf从右到左处理注释 2.如果函数调用是其中一个参数,则在printf之前调用该函数, 我做了另一个示例代码,只是更改引用传递的变量的值。我看到的是,在变量值中,它可以正常工作: ==================输出======================
i = 5, changed i = 2, again i= 2
changed i = 2, i= 2
i = 5, changed i = 2
==================代码======================
int* change (int* addr);
int main()
{
int i;
i=5;
printf("\n i = %d, changed i = %d, again i= %d \n ", i, *change(&i), i);
i=5;
printf("\n changed i = %d, i= %d \n", *change(&i), i);
i=5;
printf("\n i = %d, changed i = %d \n", i, *change(&i));
return 0;
}
int* change (int* addr)
{
*addr = 2;
return (addr);
}
答案 0 :(得分:6)
由于ReverseStr
操作就地(称为变异输入),&#34;原始&#34;字符串不再可用。
当您使用另一个函数调用作为其参数之一调用函数时,将首先执行内部调用。考虑:
printf("%lf", pow(2, 2));
在pow
之前调用幂(printf
)函数。您的代码也是如此,并且会改变原始字符串,因此当调用printf
时,它会获取已经被尊重的字符串的地址&#34;在这两个参数中#34;
解决此问题的一种方法是分配原始字符串的副本,将其传递给ReverseStr
,然后您同时提供这两个版本:
int main()
{
char str_unique[] = "abcdthelgko";
char *str_dup = strdup(str_unique);
int str_unique_len = sizeof(str_unique)/sizeof(str_unique[0]);
printf("\n || %s || \n", str_unique);
printf("Orig Str: | %s |, Rev Str | %s |\n", str_unique,
ReverseStr(str_dup, str_unique_len - 1));
free(str_dup); // Don't forget to free the memory allocated by strdup!
return 0;
}
答案 1 :(得分:0)
它在printf完成之前运行ReverseStr,
存储在str_unique中的字符串在ReverseStr之后发生了变化
然后每件事都改变了:)
答案 2 :(得分:0)
您可以在ReverseStr中复制传递的字符串,并在不进行任何修改的情况下返回它,同时传递的字符串将被反转。 (返回通过引用传递的内容通常是多余的,但通过返回原始副本,您的函数将证明值得返回而不是返回void)。
或者分配内存来保存反向字符串并且永远不会改变原始字符串:
char* ReverseStr(char* str, int len) {
char *reversed = malloc(len * sizeof(char));
int i, j = len - 1;
for (i = 0; j >= 0; i++) {
reversed[i] = str[j--];
}
return reversed;
}
返回原文但反转传递的str,以便您可能想要反转主
中的print语句char* ReverseStr(char* str, int len) {
char *start = &str[0], *end = &str[len-1];
char temp;
int i;
char *original = malloc(len * sizeof(char));
for (i = 0; str[i] != '\0'; i++) {
original[i] = str[i];
}
while (start < end) {
temp = *start;
*start = *end;
*end = temp;
start++;
end--;
}
return original;
}
答案 3 :(得分:-1)
函数ReverseStr()正在原位修改提供的字符串,而不是将其复制到新字符串。
在C中,参数从右向左推入堆栈。在调用printf()时,ReverseStr()返回的结果首先被推送(同时原始字符串str_unique被反转),然后推送指向str_unique的指针,但其内容被ReversStr()反转
您应该通过将原始字符串复制到新目标来保持原始字符串不变。这个新目的地可以在ReverseStr中的运行时(malloc)中分配(一旦你完成使用它就不要忘记释放它),或者由调用者提供。