简体   繁体   English

C - 如何通过函数增加指向字符串的指针?

[英]C - How to increment a pointer to a string through a function?

I want to execute the following code, but through a function.我想执行以下代码,但通过一个函数。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    
    int main(){
    char* string = "hello_World";
    string++;
    printf("%s\n", string);
    // ignore memory leak for sake of quiz
    return 0;
    }

OUTPUT:输出:

ello_World

Now instead of incrementing the pointer inside main I tried to pass the reference of the pointer to a function and then increment it.现在,我没有在main中递增指针,而是尝试将指针的引用传递给函数,然后递增它。

    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    void myfunc(char** param){
    param++;
    }

    int main(){
    char* string = "hello_World";
    myfunc(&string);
    printf("%s\n", string);
    return 0;
    }

But the OUTPUT was hello_World但是 OUTPUT 是hello_World

Can you please tell me what is happening in the code that I wrote and how can I change it for the desired result?您能否告诉我我编写的代码中发生了什么,以及如何更改它以获得所需的结果?

你增加了指向指针的指针,你需要(*param)++;

The memory could be looking like the following.内存可能如下所示。 The 0x1122***** represent some address of the byte below it. 0x1122*****代表其下方字节的某个地址。 Each +---+ box represents one byte with the value inside.每个+---+框代表一个字节,其中包含值。 Below are the function names with variable names.下面是带有变量名的函数名。 The ----> arrows represent "points to" relation between pointer and memory. ---->箭头表示指针和内存之间的“指向”关系。 The illustration assumes a pointer has 4 bytes and data are stored in big endian, which is most probably not true on the architecture you are running, but it's just to illustrate the point.该插图假设一个指针有 4 个字节并且数据以大端字节序存储,这在您正在运行的体系结构上很可能不是真的,但这只是为了说明这一点。

0x11223000                                       0x11223300                              0x11223344
+------+------+------+------+                    +------+------+------+------+           +---+---+---+---+---+---+---+---+---+---+---+------+
| 0x11 | 0x22 | 0x33 | 0x00 | . . . . . . . . .  | 0x11 | 0x22 | 0x33 | 0x44 | . . . . . | h | e | l | l | e | _ | W | o | r | l | d | 0x00 |
+------+------+------+------+         +--------->+------+------+------+------+           +---+---+---+---+---+---+---+---+---+---+---+------+
                                      |                                                  ^
+---------------------------+---------+          +---------------------------+-----------+
       myfunc::param                                     main::string

When you do param++ in myfunc you are incrementing the value of param , not the value it points to.当你param++myfunc你是递增的价值param ,而不是价值它指向。 Pointers are increment by the size they are pointing to, so param beeing char** will be incremented by sizeof(char*) .指针按它们指向的大小递增,因此param beeing char**将按sizeof(char*)递增。 In my illustration above, a pointer has 4 bytes, so doing param++ increments param = 0x11223300 to param = 0x11223304 and it points somewhere after main::string into some unknown memory region.在我上面的插图中,一个指针有 4 个字节,因此执行param++ param = 0x11223300递增到param = 0x11223304并且它指向main::string之后的某个位置到某个未知内存区域。

If you mean to do this:如果您打算这样做:

0x11223300                              0x11223344
+------+------+------+------+           +---+---+---+---+---+---+---+---+---+---+---+------+
| 0x11 | 0x22 | 0x33 | 0x45 | . . . . . | h | e | l | l | e | _ | W | o | r | l | d | 0x00 |
+------+------+------+------+           +---+---+---+---+---+---+---+---+---+---+---+------+
                                            ^
+---------------------------+---------------+
        main::string

Then you have to increment the string pointer inside main .然后你必须增加main内的string指针。 Because param points to string , you may (*param)++ - increment the value of what the param points to, so increment the string pointer inside main .因为param指向string ,您可以(*param)++ - 增加param指向的值,因此增加main内的string指针。 Because string is a char* , it will be incremented by sizeof(char) - which is 1 .因为string是一个char* ,它将按sizeof(char)递增 - 即1

In myfunc() function, the pointer param is pointing to string pointer.myfunc()函数中,指针param指向string指针。 It will look something like this:它看起来像这样:

        ---
  param |-|--
        --- |
            |
            |
           ---
   string  |-|----
           ---   |
                 |
                 |
                 --------------------------
                 |h|e|l|l|o|_|W|o|r|l|d|\0|
                 --------------------------

When you do param++ , it will result in incrementing the pointer by the size of pointer 1) on your platform because param can point to a char pointer.当您执行param++ ,它将导致指针在您的平台上增加指针1)的大小,因为param可以指向一个char指针。 Assume that size of pointer is 8 ( 64 bit platform) and assume the address of string pointer is 100 , then param++ will result in pointer param pointing to 108 address.假设指针的大小为864位平台),假设string指针的地址为100 ,那么param++将导致指针param指向108地址。 Note that it will not affect string pointer in anyway.请注意,无论如何它都不会影响string指针。 It will look something like this:它看起来像这样:

                             108
                   ---       ---
param++ -->  param |-|-------| |
                   ---       ---
            
           
           ---
   string  |-|----
           ---   |
                 |
                 |
                 --------------------------
                 |h|e|l|l|o|_|W|o|r|l|d|\0|
                 --------------------------

Now, when you print the string in main() function, you are getting the output "hello_World".现在,当您在main()函数中打印string时,您将获得输出“hello_World”。

To demonstrate this, I have added few printf() statement in your program:为了证明这一点,我在您的程序中添加了一些printf()语句:

#include <stdio.h>

void myfunc(char** param){
    printf ("param : %p\n", (void *)param);
    printf ("*param : %p\n", (void *)*param);
    param++;
    printf ("param : %p\n", (void *)param);
    printf ("*param : %p\n", (void *)*param);
}

int main(void){
    char* string = "hello_World";
    printf ("string : %p\n", (void *)string);
    myfunc(&string);
    printf ("string : %p\n", (void *)string);
    printf("%s\n", string);
    return 0;
}

Output:输出:

string : 0x10a654f97
param : 0x7ffee55abad0
*param : 0x10a654f97
param : 0x7ffee55abad8  ======> result of incrementing param
*param : 0xcb7d025      ======> result of incrementing param
string : 0x10a654f97    ======> not affected
hello_World

To get the desired behaviour, in the myfunc() function, you should first dereference the param pointer to get the string pointer and then increment it ie you should do (*param)++ .要获得所需的行为,在myfunc()函数中,您应该首先取消引用param指针以获取string指针,然后增加它,即您应该执行(*param)++ It will result in increment the string pointer by size of a char 1) :它将导致string指针按char 1) 的大小递增:

                       ---
                 param |-|--
                       --- |
                           |
                           |
                          ---
(*param)++  -->   string  |-|-------
                          ---      |
                                   |
                                   |
                                --------------------------
                                |h|e|l|l|o|_|W|o|r|l|d|\0|
                                --------------------------

Demonstration:示范:

#include <stdio.h>

void myfunc(char** param){
    printf ("param : %p\n", (void *)param);
    printf ("*param : %p\n", (void *)*param);
    (*param)++;
    printf ("param : %p\n", (void *)param);
    printf ("*param : %p\n", (void *)*param);
}

int main(){
    char* string = "hello_World";
    printf ("string : %p\n", (void *)string);
    myfunc(&string);
    printf ("string : %p\n", (void *)string);
    printf("%s\n", string);
    return 0;
}

Output:输出:

string : 0x100de5f97
param : 0x7ffeeee1aad0
*param : 0x100de5f97
param : 0x7ffeeee1aad0
*param : 0x100de5f98
string : 0x100de5f98
ello_World

  1. When increment a pointer, it gets incremented in steps of the object size that the pointer can point to.当增加一个指针时,它会按照指针可以指向的对象大小逐步增加。

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

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