在这种情况下如何通过引用传递?

时间:2015-08-10 16:33:45

标签: c pointers pass-by-reference

我尝试使用change()函数更改y的内容。 我想问一下,在将y分配给*时删除x时,为什么"abc"无法更改?

另外,我发现&*x&y相同,这是否意味着指针x的地址被指定为与{{{}的内容的地址相同1}}指出?另外,为什么*y不等于&x

我的代码:

"abc"

4 个答案:

答案 0 :(得分:5)

您的代码中存在许多问题,需要指出其中一些问题

  1. y指向字符串文字。任何修改字符串文字的尝试都是undefined behaviour
  2. 要打印地址,请使用%p格式说明符,并为参数添加(void*),使用不正确的参数类型为undefined behaviour。同样,要打印char,您需要%c,以打印您需要的字符串%s。阅读更多here
  3. change()内部,*x的类型为char,您正在尝试为其指定一个指针(字符串文字"abc"的基地址)。
  4. 够!!请你的编译器告诉你'其余的。(换句话说,请启用编译器警告并尝试修复报告的问题。)

答案 1 :(得分:2)

  

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

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

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

  

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

当您将x的地址作为参数传递时,指针y具有指针y的地址。

答案 2 :(得分:2)

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

运算符&会返回变量的地址,所以在代码段中:

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

指针p将保存变量a的内存地址。如果我们在*上使用运算符p,我们将通过a获取内存地址的内容:

printf("%d", *p);

将打印10

如果我们写&*p,虽然它不完全正确并且许多编译器甚至会发出警告,但我们得到指针指向的值,而不是要求该内容的地址< / strong>,即再次返回作为指针内容的数据地址。

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

但是你在代码中犯了一个大错误,而你在函数proto中声明了一个指向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

答案 3 :(得分:1)

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

HTH