首页 > 解决方案 > C中字符串指针的增加值

问题描述

我正在做一个任务。我有正确的工作代码,但是,我无法理解一行的作用。

一个函数的描述是:

这个函数会 malloc 5 个字节的内存,使用 strcpy 将“bird”存储在这 5 个字节(4 个字母加上 '\0')中,并将字符串指针指向的值增加字符串的长度(使用 strlen 计算)它指向(所以它最终指向句子末尾的'\0')。然后它将返回分配的内存。

这是执行上述操作的代码

char *get_word( char **string_ptr ){

    char *word; 

    word = malloc( 5 ); 

    strcpy( word, "bird" ); 

    *string_ptr += strlen( *string_ptr );

    return word;

}

我不明白“*string_ptr += strlen(*string_ptr);”这行是什么 确实如此,即使有上面​​的描述。有人可以更详细地解释那里发生的事情吗?

标签: cmemory

解决方案


传递给的参数get_wordchar **(大概是由于调用者传递的是字符串的地址而不是指针的集合)。

由于 C 中的所有参数都是按值传递的,因此要更改作为参数传递的指针的地址,必须传递指针的地址。否则,该函数将简单地接收指针的副本(具有它自己且非常不同的地址),并且在函数内对指针所做的任何更改都不会在调用函数中可见。

虽然您没有提供A Minimal, Complete, and Verifiable Example (MCVE),但我们可以从您的函数中推断出字符串的地址正在传递给get_word,例如:

#define MAXC 1024
...
char buffer[MAXC] = "word_one";
char *p = buffer;
char *new_word = NULL;
...
new_word = get_word (&p);

然后稍后会在该指针的末尾附加文本(这是*string_ptr += strlen( *string_ptr );in的目的get_word),例如:

strcpy (p, new_word);

结果是,缓冲区现在将包含:

"word_onebird"

因此,实际上,通过将指针的地址传递给,指针前进到byget_word中当前字的末尾,并且对指向位置的更改反映在调用函数中。string_ptr*string_ptr += strlen( *string_ptr );string_ptr

如果您只通过get_word(string_ptr),则在调用函数中所做的更改get_word将不可见,并且那里的指针将保持不变。但是,通过传递with的地址, ( 对原始指针本身进行操作的更改会反映在调用函数中的原始指针中。string_ptrget_word(&string_ptr)get_word*string_ptr = ...


通过示例了解指针

指针只是一个普通变量,它保存其他东西的地址作为它的值。换句话说,一个指针指向可以找到其他东西的地址。您通常会想到一个保存立即值的变量,例如int a = 5;,一个指针只会保存5存储在内存中的地址,例如int *b = &a;。无论指针指向什么类型的对象,它的工作方式都是相同的。(一个指针,只是一个指针......)

如果需要在函数内更改指针指向的地址而不返回新指针,则必须将原始指针的地址作为参数传递,以便函数可以对原始指针本身进行操作,而不是复制如果参数采用指针本身,则该指针将出现在函数中。

一个例子可能会有所帮助。花点时间研究代码并了解原始指针如何在 中可用get_word,但下面仅提供原始指针的副本get_word_single

#include <stdio.h>
#include <string.h>

#define MAXC 256

/* parameter passes only the pointer p in main() */
void get_word_single (char *string_ptr)
{
    printf ("in get_word_single()\n"
            " address of string_ptr: %p  <-- a new pointer\n"
            "   value in string_ptr: %p  <-- changes only seen locally\n\n",
            (void*)&string_ptr, (void*)string_ptr);

    string_ptr += strlen (string_ptr);
}

/* parameter passes address of p in main() */
void get_word (char **string_ptr)
{
    printf ("in get_word()\n"
            "address of  string_ptr: %p  <-- a new pointer\n"
            "  value in  string_ptr: %p  <-- holding original address\n\n"
            "address of *string_ptr: %p  <-- dereference to expose address\n"
            "  value in *string_ptr: %p  <-- modify to change original\n\n",
            (void*)&string_ptr, (void*)string_ptr, 
            (void*)&(*string_ptr), (void*)*string_ptr);

    *string_ptr += strlen (*string_ptr);
}

int main (void) {

    char buf[MAXC] = "one",     /* a 3-character word in buf */
        *p = buf;

    printf ("in main()\n"
            "address of p: %p  <-- address of the pointer itself\n"
            "  value in p: %p  <-- address held by the pointer\n\n", 
            (void*)&p, (void*)p);

    get_word_single (p);

    printf ("in main()\n"
            "address of p: %p  <-- address of pointer itself unchanged\n"
            "  value in p: %p  <-- no change in address held\n\n", 
            (void*)&p, (void*)p);

    get_word (&p);

    printf ("in main()\n"
            "address of p: %p  <-- address of pointer itself unchanged\n"
            "  value in p: %p  <-- address held incremented by 3\n\n", 
            (void*)&p, (void*)p);

    return 0;
}

示例使用/输出

$ ./bin/passaddrex
in main()
address of p: 0x7ffc8594f370  <-- address of the pointer itself
  value in p: 0x7ffc8594f380  <-- address held by the pointer

in get_word_single()
 address of string_ptr: 0x7ffc8594f378  <-- a new pointer
   value in string_ptr: 0x7ffc8594f380  <-- changes only seen locally

in main()
address of p: 0x7ffc8594f370  <-- address of pointer itself unchanged
  value in p: 0x7ffc8594f380  <-- no change in address held

in get_word()
address of  string_ptr: 0x7ffc8594f348  <-- a new pointer
  value in  string_ptr: 0x7ffc8594f370  <-- holding original address

address of *string_ptr: 0x7ffc8594f370  <-- dereference to expose address
  value in *string_ptr: 0x7ffc8594f380  <-- modify to change original

in main()
address of p: 0x7ffc8594f370  <-- address of pointer itself unchanged
  value in p: 0x7ffc8594f383  <-- address held incremented by 3

推荐阅读