指针与引用与常规传递值c ++

时间:2010-02-22 01:51:46

标签: c visual-studio visual-c++ visual-studio-2008

请在回答之前阅读。我不希望你为我说明显的事。谢谢:D

我试图区分指针和传递值。而且我认为我理解它们,但我读到的一个来源并不清楚,传递指针和传递值之间的区别是什么。考虑以下......

andy = 25;
fred = andy;
ted = &andy; 

第一行将值25传递给andy。第二行将andy的值传递给fred。现在fred拥有值25.第三行传递给ted。现在ted保存了andy的内存地址,它保存了25的值。现在看看下一个代码

andy = 25;
fred = andy;
ted = &andy; 
joe = *andy;

上面的代码看起来就像第一个代码段,除了我们将指向andy的指针传递给了joe。现在,joe保持指针值为25.这几乎和刚刚做的一样(joe = andy)。没有*

传递指针值与传递值相比有什么不同?

在我的解释中,似乎joe的指针值仍然受影响,如果后来我决定改变andy /的值,那么如果我只是通过值,它就不会受到影响。 Ť

据我所知,传递引用和传递指针之间的唯一区别是,一个保存地址,另一个保存该地址内的值。如果任何拥有该值引用的变量,它仍然会改变,决定改变它。如果是这种情况,通过引用传递和传递值的意义是什么。

这是我正在阅读的内容的链接

http://www.cplusplus.com/doc/tutorial/pointers/

谢谢你们!

5 个答案:

答案 0 :(得分:6)

您所谈论的内容与传递引用或传递值无关。这些术语仅指函数调用时参数的变化。规范示例是swap()函数。这个功能:

void swap(int a, int b)
{
    int t = a;
    a = b;
    b = tmp;
}

什么都不做;如果调用它们,参数将不会被交换,因为它们是按值传递的。如果你通过引用传递(在C ++中)或传递指针(在C或C ++中),它将按你想要的那样做:

void swap(int *a, int *b)
{
    int t = *a;
    *a = *b;
    *b = t;
}

或仅在C ++中,

void swap(int &a, int &b)
{
    int t = a;
    a = b;
    b = a;
}

传递引用版本的优点是它可以保证获得良好的引用。第一个例子,如果你传递了错误的指针,会使程序崩溃。

答案 1 :(得分:3)

你不能做joe = *andy因为andy不是指针,它是一个int。

但是,你可以joe = *ted,因为ted是一个指针。

假设你这样做了:

andy = 25; 
fred = andy; 
ted = &andy;  
joe = *ted;
andy = 26;
jim = *ted;

然后joe的值为25,而jim的值为26。

原因是ted是指向andy的指针。使用*ted为您提供该指针的值。

答案 2 :(得分:1)

我认为你就在那里,但你的术语令人困惑。让我们再看一下你的例子:

  

andy = 25;
  fred = andy;
  ted =& andy;

第一行将值25分配给andy。 第二行将由andy持有的值分配给fred(在本例中为25)。 第三行为ted指定了地址。

所有三个变量都具有独立的值。改变其中任何一个都不会影响其他人。

现在,看看你的下一个例子:

  

andy = 25;
  fred = andy;
  ted =& andy;
  joe = * andy;

就像你说的那样,前三行是相同的。第四行将andy指向的值赋给joe。在这种情况下,joe现在将值保存在存储器位置25,因为andy被视为存储器位置(并且在这种情况下实际值是未知的,因为我们不知道给定存储在地址25处的数据)。

而且,此时所有四个变量都保持独立的值。改变其中任何一个都不会影响其他人的价值。

让我们看另一个例子:

  

andy = 35;
  吉姆=& andy;   alex = * jim;

第一行将值25分配给andy。这里没什么新鲜的。 第二行为jim指定了andy的地址。 第三行取消引用存储在jim中的地址,并将值赋给alex。变量alex现在保持值25.但是亚历克斯持有的25与alan持有的25不同,因为alan和alex住在不同的内存地址。如果我们将alan的值更改为30,则alex仍然保持25。

最后一个例子:

  

andy = 25;
  jim =& andy;
  * jim = 30;

前两行与上一个示例类似,andy的值为25,jim包含andy的地址。

第三行将值30赋给jim指向的内存地址。因为这是andy所在的地址,现在它的值为30.在这种情况下,andy和* jim引用相同的内存位置。

术语传值和传递指针(或传递引用)是指将参数传递给函数。按值传递时,如:

void myfunc(int a) { a = a+5; }

然后如下所示:

  

int b = 2;
  MYFUNC(B);

从函数返回时b的值不会改变,因为你只是将b的值传递给函数,将它赋值给a。变量a已更改,但由于它位于不同的内存地址,因此更改a不会影响b的值。

但是当按指针传递时,如:

void myfunc(int* a) { *a = *a+5; }

然后如下所示:

  

int b = 2;
  MYFUNC(和b);

b的值从2更改为7,因为您将b的地址传递给函数,然后将地址解除引用到getit的当前值,向其添加5,并将结果存回到同一地址。函数返回时,存储在地址b的值已更新。

答案 3 :(得分:1)

您的示例显示了赋值和引用/解除引用指针/对象的示例,而不是通过值或引用传递。就像撒克逊上面所说的那样,你不能指定joe = * andy。

简单来说,您可以将它们定义为:

  • 传递值:传递副本 函数的值。副本 存在于范围内 仅限功能。对它的任何改变都是 本地范围,例如。 void funcA(int 一个)
  • 通过引用传递:将包含值的对象的地址传递给函数,并且该对象仍存在于其父作用域中。您拥有父作用域中对象的地址,因此将对该同一对象进行更改。例如。 void funA(int& a)
  • 通过指针传递:您传递一个指针,该指针将地址保存到该对象。您实际上是将指针作为值(将地址保存到对象)传递给方法。如果将指针更改为指向另一个对象,则父作用域中的原始对象不会更改。如果你想改变它指向的对象,那么你必须尊重它。例如。 void funA(int * a)

答案 4 :(得分:0)

通过引用传递和传递值有什么意义?

你是对的,在这种情况下,

之间没有区别

(a)直接分配值,例如(joe = andy)和
(b)复制存储器地址,然后取消引用例如 (ted = &andy; joe = *ted;

没有区别,因为它们具有相同的范围,即它们具有相同的功能。一旦你开始将指针传递给其他函数,传递指针的重要性就开始了。

当我试图理解指针(仅仅6个月前)时,对我来说主要的时刻是(并且没有人告诉过你)... 函数通过复制函数传递参数。这很重要,因为这意味着如果您只是将变量传递给其他函数,那么中的变量的更改将不会反映在程序中的其他函数中。

假设您有一个程序可以跟踪班级中的学生人数。当新学生加入课程时,会调用函数AddStudent来增加课程中学生的数量。这里有2个版本的AddStudent,通过引用传递和传递值。我们将从main调用每个,并打印结果以查看差异。

int AddStudent_pass_by_value(int value)
{
    value = value+1;
    printf("Number of students (within function): %d\n", value);
    return 0;
}

int AddStudent_pass_by_reference(int* value)
{
    *value = *value+1;
    printf("Number of students (within function): %d\n", *value);
    return 0;
}

int main()
{
    int NumStudents = 0;  //number of students
    printf("Number of students, (within main): %d\n", NumStudents);
    printf("Pass it by value\n");
    AddStudent_pass_by_value(NumStudents);
    printf("Number of students (within main): %d\n\n", NumStudents); 
    /*In main, the value is still 0! The function has not changed the original variable, just a copy of it.*/

    printf("Now pass it by reference\n");
    AddStudent_pass_by_reference(&NumStudents);
    printf("Number of students (within main): %d\n", NumStudents);  
    /*Now, because we passed by reference, the original variable has been changed. */
    return 0;
}

希望这会有所帮助......