指向字符的指针传递给函数。为什么不指针指针?

时间:2014-03-20 17:49:55

标签: c pointers

为什么这样的功能:

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)

3 个答案:

答案 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), &copystr))
    strcpy(copystr, string);
else    fprintf(stderr, "out of memory\n");

正如您在上面的示例中所看到的,提供的copystr已被修改但未从函数显式返回,因为我们传入了一个双指针,这允许我们修改与copystr关联的内存。如果你需要传入双指针,这取决于你的实现。