简体   繁体   English

C中字符串指针的值增加

[英]Increasing Value of String Pointer in C

I am working on an assignment. 我正在做作业。 I have the proper working code, however, I am having trouble understanding what one line does. 我有正确的工作代码,但是,我很难理解一行代码的作用。

The description for a function is: 功能描述为:

This function will malloc 5 bytes of memory, store "bird" in those 5 bytes (4 letters plus '\\0') using strcpy, and increase the value pointed to by the string pointer by the length of the string (calculated using strlen) that it points to (so it ends up pointing to the '\\0' at the end of the sentence). 此函数将分配5个字节的内存,使用strcpy将“ bird”存储在这5个字节(4个字母加'\\ 0')中,并将字符串指针指向的值增加字符串的长度(使用strlen计算)它指向的位置(因此最终指向句子末尾的“ \\ 0”)。 Then it will return the malloced memory. 然后它将返回分配的内存。

Here is the code to do what is described above 这是执行上述操作的代码

char *get_word( char **string_ptr ){

    char *word; 

    word = malloc( 5 ); 

    strcpy( word, "bird" ); 

    *string_ptr += strlen( *string_ptr );

    return word;

}

I do not understand what the line "*string_ptr += strlen( *string_ptr );" 我不明白“ * string_ptr + = strlen(* string_ptr);”​​这行是什么 does, even with the description above. 即使有以上描述也是如此。 Could someone give me a more detailed explanation of what happening there? 有人可以给我更详细的解释那里发生了什么吗?

The parameter passed to get_word is char ** (presumably due to the caller passing the address of the string rather than a collection of pointers). 传递给get_word的参数是char ** (大概是由于调用者传递了字符串地址而不是指针的集合)。

Since all parameters in C are passed-by-value, in order to change the address of a pointer passed as a parameter, you must pass the address of the pointer. 由于C中的所有参数都是按值传递的,因此,为了更改作为参数传递的指针的地址,必须传递指针的地址 Otherwise, the function will simply receive a copy of the pointer (with its very own and very different address) and any changes made to the pointer within the function will not be visible back in the calling function. 否则,该函数将仅接收指针的副本(具有其自身的地址和完全不同的地址),并且对该函数内指针所做的任何更改在调用函数中都将不可见。

While you have not provided a A Minimal, Complete, and Verifiable Example (MCVE) , we can deduce from your function that the address of a string is being passed to get_word , something like: 虽然您没有提供“最小,完整和可验证的示例(MCVE)” ,但我们可以从您的函数中推断出字符串的地址正在传递给get_word ,例如:

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

Then later there is something done to append text at the end of that pointer (which was the purpose for *string_ptr += strlen( *string_ptr ); in get_word ), something like: 然后,需要执行一些操作以在该指针的末尾追加文本(这是*string_ptr += strlen( *string_ptr );get_word中的get_word ),类似于:

strcpy (p, new_word);

The result being, buffer would now contain: 结果是,缓冲区现在将包含:

"word_onebird"

So in effect, by passing the address of a pointer to get_word , the pointer is advanced to the end of the current word in string_ptr by *string_ptr += strlen( *string_ptr ); 因此,实际上,通过将指针的地址传递给get_word ,该指针通过*string_ptr += strlen( *string_ptr );前进到string_ptr当前单词的string_ptr *string_ptr += strlen( *string_ptr ); and the change to where string_ptr is pointing is reflected back in the calling function. 并将string_ptr指向的位置更改反映回调用函数中。

Had you only passed get_word(string_ptr) , the change made in get_word would not be visible back in the calling function, and the pointer there would be unchanged. 如果只传递了get_word(string_ptr) ,则在get_word所做的更改将在调用函数中不可见,并且指针将保持不变。 But, by passing the address of string_ptr with get_word(&string_ptr) , the change in get_word (which operates on the original pointer itself through *string_ptr = ... is reflected in the original pointer back in the calling function. 但是,通过使地址的 string_ptrget_word(&string_ptr)在变更get_word (其通过对原始指针本身操作*string_ptr = ...被反映在原始指针返回调用函数。


Understanding Pointers By Example 通过示例了解指针

A pointer is simply a normal variable that holds the address of something else as its value. 指针只是一个普通变量,将其他地址作为其值。 In other words, a pointer points to the address where something else can be found. 换句话说,一个指针指向可以找到其他内容的地址。 Where you normally think of a variable holding an immediate values, such as int a = 5; 通常您会想到一个包含立即数的变量,例如int a = 5; , a pointer would simply hold the address where 5 is stored in memory, eg int *b = &a; ,指针将仅保存内存中存储5的地址,例如int *b = &a; . It works the same way reqardless what type of object the pointer points to. 无论指针指向什么类型的对象,它都以相同的方式工作。 (a pointer, is just a pointer....) (一个指针,仅仅是一个指针...。)

If you need to change the address pointed to by a pointer within a function without returning the new pointer, you must pass the address of the original pointer as a parameter so that the function can operate on the original pointer itself, rather than a copy of the pointer which would be present in the function if the parameter took the pointer itself. 如果您需要在函数中更改指针所指向的地址而不返回新指针,则必须将原始指针的地址作为参数传递,以便函数可以对原始指针本身进行操作,而不是对它的副本进行操作。如果参数本身带有指针,则该指针将出现在函数中。

An example may help. 一个例子可能会有所帮助。 Take time to work through the code and understand how the original pointer is available in get_word , but only a copy of the original is available in get_word_single below: 花时间通过代码工作,明白,原来指针是如何在提供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;
}

Example Use/Output 使用/输出示例

$ ./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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM