函数中的C ++指针

时间:2011-06-08 23:23:28

标签: c++ pointers

这是我在C ++中为学习目的而创建的代码片段,我目前正在尝试自学。我的问题是:

为什么*ptr = 30会改变我主要的两个最后一个cout语句的输出值? (输出为30,30,30)。因此,int y = 30;ptr = &y;为什么不改变main中的输出,并保持函数的本地? (如果我注释掉* ptr = 30,而不是前两个语句,则输出为30,5,5)

如果我将功能输入更改为void printPointer(int *&fptr) - 并注释 *ptr = 30 - 那么我的主程序中的*ptr将被修改,但不会X。我理解这一点,因为引用传递是修改指针,而不是我的第一个语句如何修改我的主中的* ptr和x。

#include <iostream>

using namespace std;

void printPointer(int *fptr);

int main()
{
    int x = 5;

    int *ptr = &x;

    printPointer(ptr);

    cout << *ptr << endl;
    cout << x << endl;

    return 0;
}

void printPointer(int *fptr)
{

//  int y = 30;             // this does not change the output of the last two couts in main, output = 30, 5, 5
 // fptr = &y;

    *fptr = 30;          // uncommenting this and commenting out the former two statements: output = 30, 30, 30

    cout <<  *fptr << endl;
}

3 个答案:

答案 0 :(得分:3)

*ptr = 30更改指向的值。在您的情况下,您已将ptr设置为指向x(当您执行ptr = &x时,然后将其作为参数传递给printPointer())。因此x的值已更改。

当您执行int y = 30; fptr = &y;时,您所做的只是将fptr更改为指向不同的变量。而已。你没有改变指向的值(即x的值)。并且您不会影响ptr,因为fptr是一个单独的本地变量。因此ptr仍然指向x,而x仍为5。

当您修改函数以通过引用获取指针时,将fptr更改为指向y 会更改ptr,因为它们是相同的变量

答案 1 :(得分:0)

*fptr = 30将取消引用存储在fptr中的地址,并在内存中的位置写入30。这个地址在你用printPointer(ptr)赋予函数的内存中。在这种情况下,ptr是x的地址,您使用ptr = &x分配给ptr。

int y= y声明函数的局部变量。 fptr = &y将y的地址分配给fptr(并覆盖ptr中的值)。所以这种情况下的最后一行会改变局部变量y而不是x。

答案 2 :(得分:0)

如果我理解正确,你会问两段代码。第一个是您发布的内容:

#include <iostream>

using std::cout;

void f(int* fptr) {
    *fptr = 30;  // 11
    cout << "*fptr = " << *fptr << '\n'; // 12
}

int main() {
    int x = 5; // 1
    int* ptr = &x; // 2
    f(ptr); // 21
    cout << "*ptr = " << *ptr << '\n'; // 22
    cout << "x = " << x << '\n'; // 23
}

在这种情况下,指针始终指向x,并且在函数中,您仍然会更改x的值,因为这是fptr指向的值。如果它有帮助,这里是每行末尾变量值的演示:NE表示当前不存在变量。

1.  x = 5, ptr = NE, fptr = NE
2.  x = 5, ptr = &x, fptr = NE
11. x = 30, ptr = &x, fptr = &x
12. x = 30, ptr = &x, fptr = &x
21. x = 30, ptr = &x, fptr = NE

之后,值不会改变,并且所有三个语句都将打印30。

第二个是:

#include <iostream>

using std::cout;

void f(int*& fptr) {
    int y = 30; // 11
    fptr = &y; // 12
    cout << "*fptr = " << *fptr << '\n'; // 13
}

int main() {
    int x = 5; // 1
    int* ptr = &x; // 2
    f(ptr); // 21
    cout << "*ptr = " << *ptr << '\n'; // 22
    cout << "x = " << x << '\n'; // 23
}

在第一种情况下,指针通过引用传递,并指向y。事实上,在这种情况下,第21行涉及未定义的行为,因为y不再存在。再次,逐行分析:

1.  x = 5, y = NE, ptr = NE, fptr == NE
2.  x = 5, y = NE, ptr = &x, fptr == NE
11. x = 5, y = 30, ptr = &x, fptr == ptr
12. x = 5, y = 30, ptr = &y, fptr == ptr
13. x = 5, y = 30, ptr = &y, fptr == ptr
21. x = 5, y = NE, ptr = &y, fptr == NE

此后值再次不会更改:但是,在第22行,您尝试获取ptr的地址。如您所见,*ptr = y = NE,因此行为未定义。输出可以是任何东西。

(另一个注意事项是,您应该避免使用using namespace std;,因为它可能导致名称冲突;请使用using std::cout;和类似内容,如上面的代码所示。)