交换两个字符串指针
我必须在C中使用char []并且我想在它们之间进行交换,只需将指针交换到数组而不是一次只有一个char,所以我编写了这段代码:
#include void fastSwap (char **i, char **d) { char *t = *d; *d = *i; *i = t; } int main () { char num1[] = "012345678910"; char num2[] = "abcdefghujk"; fastSwap ((char**)&num1,(char**)&num2); printf ("%s\n",num1); printf ("%s\n",num2); return 0; }
我得到这个输出(注意最后4个字符)
abcdefgh8910 01234567ujk
当我期待:
abcdefghujk 012345678910
注意:我正在使用64位Linux系统。
您无法修改num1
和num2
的地址,如果您的测试是相反的,您的代码应该有效:
int main () { char num1[] = "012345678910"; char num2[] = "abcdefghujk"; char *test1 = num1; char *test2 = num2; fastSwap (&test1,&test2); printf ("%s\n",test1); printf ("%s\n",test2); return 0; }
数组不是指针。 当你调用fastSwap()
时它们会衰减到指针,这些指针不是实际的数组。 你需要演员表的事实应该给你一个错误的暗示。
这可行:
void fastSwap (const char **i, const char **d) { const char *t = *d; *d = *i; *i = t; } const char* num1 = "012345678910"; const char* num2 = "abcdefghujk"; fastSwap (&num1,&num2); printf ("%s\n",num1); printf ("%s\n",num2);
这将有效:
int main () { char *num1 = "012345678910"; char *num2 = "abcdefghujk"; fastSwap (&num1,&num2); printf ("%s\n",num1); printf ("%s\n",num2); return 0; }
num1
是一个数组, &num1
是数组本身的地址 – 它不是指针的地址。
数组本身的地址与内存中的第一个元素的地址相同,但它具有不同的类型。 当你将该地址转换为char **
,你声称它指向char *
值 – 但它没有。 它指向一个13个字符的块。 然后你的交换函数访问13个字符的数组,好像它是一个char *
– 因为后者与平台上的8个char
大小相同,你最终交换每个数组的前8个字符。
你的fastSwap似乎只能工作。 您通过将’&num1’和’&num2’(指向num1和num2的字符的指针)转换为指向字符指针(char **)的指针来调用未定义的行为。
char *t = *d
t将指向任何内容指向的内容,但是d指向num2的实际字符(“abcdefghujk”或0x61 0x62 0x63 0x64 0x65 0x66 0x67 0x68 0x75 0x6B 0x00)。 这意味着’* d’实际上正在复制’num2’的内容,而不是像你预期的那样复制指向num2的指针。
然后’t’是一个糟糕的指针,因为它永远不会被解除引用,你可以避免崩溃/段错误。
因为你在64位机器上/ OS指针是8字节,’t’的值现在是’num2’的前8个字节,这是在被放入num1后的内容
*i = t
如果你打算交换指针,你必须首先像马克那样创建指针变量
char *test1 = num1; char *test2 = num2; fastSwap (&test1,&test2);
或者将num1和num2更改为指针(char *)而不是数组(char []),如sb1 / Karl所做的那样
char *num1 = "012345678910"; char *num2 = "abcdefghujk"; fastSwap (&num1,&num2);
我有同样的情况,并通过以下技巧解决了它:
ps windows平台,vs-2012
void FastSwap (void **var1, void **var2) { void *pTmp = *var1; *var1 = *var2; *var2 = pTmp; } int main () { char *s1 = "1234567890123456"; char *s2 = "abcdefghij"; printf ("s1 before swap: \"%s\"\n", s1); printf ("s2 before swap: \"%s\"\n", s2); // if you change arguments in the FastSwap definition as (char **) // then you can erase the (void **) part on the line below. FastSwap ((void **) &s1, (void **) &s2); printf ("s1 after swap : \"%s\"\n", s1); printf ("s2 after swap : \"%s\"\n", s2); return (0); }
将fastSwap更改为:
void fastSwap (char *i, char *d) { while ((*i) && (*d)) { char t = *d; *d = *i; *i = t; i ++; d ++; } }
然后调用fastSwap(num1,num2);