指针与引用的高级用法

C++编程中,指针和引用是两个非常强大的特性,它们允许程序员直接操作内存地址。然而,正确理解并使用指针和引用的高级形式,如指针到指针(ptr-to-ptr)和引用到指针(ref-to-ptr),对于编写高效且可维护的代码至关重要。本文将详细探讨这些概念,并提供实例代码,帮助读者更好地理解它们在函数中传递指针时的重要性。

为什么需要指针到指针和引用到指针

当通过指针传递参数给函数时,实际上传递的是指针的副本。这意味着,如果函数内部修改了指针,那么修改的只是指针的副本,原始指针并不会受到影响。这在某些情况下会导致问题。以下是一个C++示例,展示了这种行为:

int g_n = 42; void example_ptr() { int n = 23; int *pn = &n std::cout << "example_ptr()" << std::endl; std::cout << "Before :" << *pn << std::endl; // 显示 23 func_ptr(pn); std::cout << "After :" << *pn << std::endl; // 显示 23 } void func_ptr(int *pp) { pp = &g_n; }

在这个例子中,尽管函数func_ptr修改了指针pp,但原始指针pn并没有改变。这是因为pp只是pn的一个副本。

指针到指针的语法

指针到指针允许在函数内部修改指针的地址。以下是如何使用指针到指针参数调用函数的示例:

int g_n = 42; void example_ptr_to_ptr() { int n = 23; int *pn = &n std::cout << "example_ptr_to_ptr()" << std::endl; std::cout << "Before :" << *pn << std::endl; // 显示 23 func_ptr_to_ptr(&pn); std::cout << "After :" << *pn << std::endl; // 显示 42 } void func_ptr_to_ptr(int **pp) { *pp = &g_n; }

在这个例子中,函数func_ptr_to_ptr通过指针到指针参数修改了指针pn的地址,从而使得pn指向了全局变量g_n

引用到指针的语法

引用到指针是C++特有的语法,它允许通过引用直接修改指针。以下是如何使用引用到指针参数调用函数的示例:

int g_n = 42; void example_ref_to_ptr() { int n = 23; int *pn = &n std::cout << "example_ref_to_ptr()" << std::endl; std::cout << "Before :" << *pn << std::endl; // 显示 23 func_ref_to_ptr(pn); std::cout << "After :" << *pn << std::endl; // 显示 42 } void func_ref_to_ptr(int *&pp) { pp = &g_n; }

在这个例子中,函数func_ref_to_ptr通过引用到指针参数直接修改了指针pn,使其指向了全局变量g_n

返回指针的语法

另一种修改指针的方法是直接在函数中返回新的指针。以下是如何实现的示例:

int g_n = 42; void example_ret_ptr() { int n = 23; int *pn = &n std::cout << "example_ret_ptr()" << std::endl; std::cout << "Before :" << *pn << std::endl; // 显示 23 pn = func_ret_ptr(); std::cout << "After :" << *pn << std::endl; // 显示 42 } int *func_ret_ptr() { return &g_n; }

在这个例子中,函数func_ret_ptr返回了全局变量g_n的地址,然后在函数example_ret_ptr中,将指针pn更新为这个新地址。

返回引用的语法

与返回指针类似,也可以通过返回引用来修改指针。以下是如何实现的示例:

int g_n = 42; void example_ret_ref() { int n = 23; int *pn = &n std::cout << "example_ret_ref()" << std::endl; std::cout << "Before :" << *pn << std::endl; // 显示 23 pn = &func_ret_ref(); std::cout << "After :" << *pn << std::endl; // 显示 42 } int& func_ret_ref() { return g_n; }

在这个例子中,函数func_ret_ref返回了全局变量g_n的引用,然后在函数example_ret_ref中,将指针pn更新为这个引用。

指针到指针与引用到指针的比较

指针到指针和引用到指针都可以用于修改指针,但它们之间并没有明显的优劣之分。选择使用哪一种通常取决于个人偏好。有些程序员认为引用到指针的语法更“干净”,而有些程序员则认为指针到指针的语法更清晰。

不要误用指针到指针参数

不要将所有的指针到指针参数都视为纯粹的指针到指针。例如,有些人会将int main(int argc, char *argv[])误写为int main(int argc, char **argv),但实际上**argv是一个指针数组。在使用指针到指针参数时,一定要先查阅库文档。

引用到指针类型(RTTI)

void test(int *& rpInt) { std::cout << "type of *&rpInt: " << typeid(rpInt).name() << std::endl; // 将显示 int * }
沪ICP备2024098111号-1
上海秋旦网络科技中心:上海市奉贤区金大公路8218号1幢 联系电话:17898875485