1

我想执行以下代码,但通过一个函数。

    #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;
    }

输出:

ello_World

现在,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;
    }

但输出是hello_World

您能否告诉我我编写的代码中发生了什么以及如何更改它以获得所需的结果?

4

3 回答 3

3

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

于 2020-10-14T13:56:04.380 回答
3

myfunc()函数中,指针param指向string指针。它看起来像这样:

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

当你这样做param++时,它将导致指针在你的平台上增加指针1)的大小,因为param可以指向一个char指针。假设指针的大小为864位平台)并假设string指针的地址为100param++则将导致指针param指向108地址。请注意,它无论如何都不会影响 string指针。它看起来像这样:

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

现在,当您打印stringinmain()函数时,您将获得输出“hello_World”。

为了证明这一点,我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;
}

输出:

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

要获得所需的行为,在myfunc()函数中,您应该首先取消引用param指针以获取string指针,然后递增它,即您应该这样做(*param)++。这将导致string指针按char1)的大小递增:

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

示范:

#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;
}

输出:

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

  1. 当增加一个指针时,它会以指针可以指向的对象大小为单位递增。
于 2020-10-14T14:49:34.930 回答
3

内存可能如下所示。代表它下面的字节的0x1122*****某个地址。每个+---+框代表一个字节,其中包含值。下面是带有变量名的函数名。箭头表示指针和内存之间的---->“指向”关系。该图假设一个指针有 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

当你这样做param++时,myfunc你是在增加 的param而不是它指向的值。指针按它们指向的大小递增,因此parambeeingchar**将递增sizeof(char*)。在我上面的插图中,一个指针有 4 个字节,因此param++递增param = 0x11223300param = 0x11223304并指向某个main::string未知内存区域之后的某个位置。

如果您打算这样做:

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

然后你必须增加string里面的指针main。因为param指向string,你可以(*param)++增加指向的值param,所以增加string里面的指针main。因为stringis a char*,它会增加 -which sizeof(char)is 1

于 2020-10-14T14:35:40.530 回答