为什么这样的功能:
void inplace_reverse(char * str)
{
if (str)
{
char * end = str + strlen(str) - 1;
// swap the values in the two given variables
// XXX: fails when a and b refer to same memory location
# define XOR_SWAP(a,b) do\
{\
a ^= b;\
b ^= a;\
a ^= b;\
} while (0)
// walk inwards from both ends of the string,
// swapping until we get to the middle
while (str < end)
{
XOR_SWAP(*str, *end);
str++;
end--;
}
# undef XOR_SWAP
}
}
是否需要传递指针指针才能更改字符串?
为避免修改函数的本地副本,是否必须传递指向要修改的对象的指针?因此,如果我们要修改int
对象,我们会传递int*
?
所以,我的问题是,为什么声明不会像:
inplace_revserse( char **str)
?
答案 0 :(得分:1)
char *
就是那个 - 指向char
的指针。 inplace_reverse
函数取消引用传递给操纵char *
指向的内存的指针。
while (str < end)
{
XOR_SWAP(*str, *end);
str++;
end--;
}
因此,虽然复制了参数,但底层内存(实际字符串)已被修改。
答案 1 :(得分:1)
如果要更改指针指向的位置,则需要使用指针指针。
void func( char** str )
{
// this reassigns where in memory the string is located.
// Generally not what you want to do
*str = some_other_char_ptr;
}
但是,如果您只想更改字符串指向的实际内存,那么您只需要一个指针。
int main()
{
char* string = "He";
char** str_ptr = &string;
func(str_ptr);
func2(string);
}
Code MemoryLocation Value
----------------------------------------
string 0x100 0x200
str_ptr 0x104 0x100
...
0x200 'H'
0x201 'e'
0x202 '\0'
因此,当我们调用func()
时,复制并传入的值为0x100
。因此,当我们取消引用它时,我们可以访问它存储的值,在本例中为0x200
。但通过解除引用,我们也可以设置该值:
*str = "a";
Code MemoryLocation Value
----------------------------------------
string 0x100 0x300 <--- note the change
str_ptr 0x104 0x100
...
0x200 'H'
0x201 'e'
0x202 '\0'
0x300 'a'
0x301 '\0'
但是,对于func2()
,复制并传递的值为0x300
,并且无法更改该值,因为它已被复制,并且对str
的任何更改都将保留在本地。但是,可以访问和更改0x300
处的内存。
答案 2 :(得分:0)
**
只是指向指针的指针。因此,char*
包含char
的地址时,char**
包含char*
的地址,其中包含char
的地址。
你可以像这样形象化它:
char* ----> char
char** ----> char* ----> char
如何使用它的示例如下:
#include <stdlib.h>
int allocstr(int len, char **retptr)
{
char *p = malloc(len + 1); /* +1 for \0 */
if(p == NULL)
return 0;
*retptr = p;
return 1;
}
然后调用者可以执行类似
的操作char *string = "Hello, world!";
char *copystr;
if(allocstr(strlen(string), ©str))
strcpy(copystr, string);
else fprintf(stderr, "out of memory\n");
正如您在上面的示例中所看到的,提供的copystr
已被修改但未从函数显式返回,因为我们传入了一个双指针,这允许我们修改与copystr
关联的内存。如果你需要传入双指针,这取决于你的实现。