【问题标题】:How to pass by reference in this case?在这种情况下如何通过引用传递?
【发布时间】:2015-11-02 16:10:58
【问题描述】:

我尝试使用change() 函数来更改y 的内容。 我想问为什么在将x分配给"abc"时删除*y不能改变?

另外,我发现&*x&y是一样的,那是否意味着x指针的地址被赋值为和*y指向的内容地址一样?还有,为什么&x不等于"abc"

我的代码:

void change(char *x) {
    *x = "abc";
    printf("S3: %x\n", &x);
    printf("S4: %x\n", &*x);
}

int main() {
    char *y = "def"; 
    printf("S1: %x\n", &y);
    printf("S2: %x\n", &*y);
    change(&y);
    printf("result: %s\n", y);
    return 0;
}

【问题讨论】:

  • 不能合法地改变y的“内容”,因为它指向一个字符串字面量。
  • *x="abc"??? -Wall它。
  • 为什么编译时禁用警告?
  • @Jason 它们不是指针,它们是 C++ 中 const char[] 和 C 中 char[] 类型的 数组(即使修改它们是 UB)。
  • 这段代码不能用 C 或 C++ 编译。请确定您使用的语言,使代码以该语言编译,并删除其他语言的标记。

标签: c pointers pass-by-reference


【解决方案1】:

您必须阅读有关指针和参数传递的更多信息。 指针是一个变量,它保存着另一个变量的内存地址。 当您在代码中引用变量时,编译器会使用该变量的,因此,当您引用指针时,您将获得其内容即地址。

操作符&返回一个变量的地址,所以在sn -p中:

int a = 10;
int *p = &a;

指针p 将保存变量a 的内存地址。如果我们在p上使用运算符*,我们将得到a持有的内存地址的内容:

printf("%d", *p);

将打印10

如果我们写&*p,虽然它并不完全正确,许多编译器甚至会发出警告,但我们得到的是指针指向的值,而不是需要该内容的地址,也就是把指针内容的数据地址重新找回来。

现在是函数,当您在函数中传递参数时,变量的副本被压入堆栈,从函数内部访问的位置。 这些值是本地的,当您离开该函数时,对它们所做的任何更改都会丢失。当然,如果你传递一个指针,你的变量的地址,然后使用指针改变值,你可以反映真实变量的变化。

但是当你在函数原型中声明指向 char 的指针时,你在代码中犯了一个大错误:

void change(char *x)

您正在传递change(&y);,即char **ychar *&ychar **)。您应该为此收到很多警告。 无论如何,这个概念在调用方是正确的,您传递存储字符串地址的地址,更改它y 将指向新字符串。这是完全合法的,因为您正在使用另一个常量字符串更新指针(而不是更改非法的常量字符串)。 但是你需要指向字符串的指针的地址,你的函数必须是:

void change(char **x)
{
    *x = "abc";
    printf("S3: %p\n", (void *)&x);
    printf("S4: %p\n", (void *)&*x);
}

int main(int argc, char *argv[])
{
    char *y = "def"; 
    printf("S1: %p\n", (void *)&y);
    printf("S2: %p\n", &*y);
    change(&y);
    printf("result: %s\n", y);
    return 0;
}

最后在printf 中使用正确的格式作为指针,它是%p

【讨论】:

    【解决方案2】:

    为什么 &x 不等于 "abc"?

    因为&x 给出了x 的地址而不是它指向的值。要获得价值,您需要*x

    y 无法更改,因为它指向常量字符串。任何改变它的尝试都会导致 UB。

    这是否意味着指针x的地址与*y指向的内容的地址相同?

    指针x 具有指针y 的地址,因为您将y 的地址作为参数传递给函数。

    【讨论】:

      【解决方案3】:

      您的代码中有很多问题,请指出其中一些问题

      1. y 指向一个字符串文字。任何修改字符串文字的尝试都是undefined behaviour
      2. 要打印地址,请使用%p 格式说明符,并将参数转换为(void*),使用不正确的参数类型是undefined behaviour。同样,要打印char,您需要%c,要打印您需要%s 的字符串。阅读更多here
      3. change() 函数内部,*x 的类型为char,而您正试图为其分配一个指针(字符串文字"abc" 的基地址)。

      够了!!让你的编译器告诉你剩下的事情。(换句话说,请启用编译器警告并尝试修复报告的问题。)

      【讨论】:

        【解决方案4】:

        它应该是change(y) 而不是change(&y)change(&y)*y 的地址而不是y 中的地址。所以 y 给出了字符串中第一个字符的地址,其中 &y 给出了 y 的地址而不是第一个字符串的地址。

        HTH

        【讨论】:

        • HTH 是什么意思?另外,请改进格式和内容(即添加更多解释)。
        • HTH --> 希望对您有所帮助
        猜你喜欢
        • 2021-01-21
        • 1970-01-01
        • 1970-01-01
        • 2023-03-29
        • 1970-01-01
        • 2021-12-06
        • 2022-01-20
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多