C++指针作为函数参数:原理、常见错误与实战应用

Ada
Ada
发布时间:2026-10-13 | 2人浏览过
原创

C++中指针作为函数参数是实现函数间数据双向交互的关键手段。与普通的值传递不同,通过传递变量的地址,被调用函数可以直接修改主调函数中的原始数据。本文结合典型代码案例,详解指针参数的正确用法、底层逻辑及常见的陷阱,助你编写更安全的C++程序。

核心机制:为什么需要指针参数?

C++函数的参数不仅可以是基本数据类型(如整型、浮点型),还可以是指针类型。其本质作用是将一个变量的内存地址传递给被调用函数的形参。在面向对象的现代C++设计中,虽然常引用(&)更为常用,但理解指针传参对于理解底层内存模型依然至关重要。



在早期的C语言或追求极致性能的场景中,利用函数指针可以编写通用算法;而在处理普通变量修改时,使用指针作为参数可以实现“通过调用函数使变量的值发生变化”,这是普通值传递无法做到的。

第1步:通过指针实现两个变量的值交换

为了直观展示指针的作用,我们来看一个经典的 swap 交换函数实现。我们的目标是通过调用函数,让主函数中的两个整数 a 和 b 完成大小互换。

首先需要定义指向整型的指针变量,并将其实例化后传入函数:

#include <iostream>
using namespace std;

int main( )
{
  void swap(int *p1,int *p2); //函数声明
  int *pointer_1,*pointer_2,a,b; //定义指针和整型变量
  cin>>a>>b;
  pointer_1=&a; //使pointer_1指向a的地址
  pointer_2=&b; //使pointer_2指向b的地址
  
  if(a<b) swap(pointer_1,pointer_2); //调用时传入的是指针(地址)
  
  cout<<"max="<<a<<" min="<<b<<endl;
  return 0;
}

void swap(int *p1,int *p2) 
{
  int temp;
  temp=*p1;    //取出p1指向的值存入临时变量
  *p1=*p2;     //将p2指向的值赋给p1指向的位置
  *p2=temp;    //将临时变量的值赋给p2指向的位置
}

运行结果如下:

45 78↙
max=78 min=45

关键细节分析

  • 地址传递: 在 main 函数中调用 swap(pointer_1,pointer_2) 是正确的,因为我们需要传递的是地址。
  • 解引用操作: 在 swap 内部,*p1 和 *p2 代表的是 p1 和 p2 所指向的实际存储空间中的数据。

第2步:警惕常见的指针参数错误

在使用指针作为函数参数时,新手容易混淆“改变指针本身的值”与“改变指针指向的值”。以下两种情况是典型的错误用法。

错误一:未初始化指针导致内存非法访问

如果在 swap 函数内部错误地使用了未初始化的临时指针变量,程序会崩溃:

// 错误的写法
void swap(int *p1, int *p2)
{
  int *temp; // 这是一个野指针!
  *temp=*p1; // 危险:向未分配的随机地址写入数据
  *p1=*p2;
  *p2=*temp;
}



正确的做法是使用普通整型变量 int temp 作为中转站,而不是指向未知的指针。

错误二:误用值传递导致交换失效

如果不小心将调用改为 swap(*pointer_1, *pointer_2),或者在函数声明中将参数定义为普通整型 void swap(int x, int y),则无法成功交换。

// 这种声明完全丢失了指针意义
void swap(int x, int y)
{
  int temp;
  temp=x; x=y; y=temp;
}

这是因为C++采用单向的“值传递”。当 x=a, y=b 被赋值后,x 和 y 只是副本。在函数内修改 x 和 y 不会影响到 main 函数中的 a 和 b。



只有传递了真正的地址(即指针的值),被调函数才能通过解引用操作去修改主函数内存空间中的变量。注意:我们交换的是 *p1 和 *p2 指向的内容,而不是 p1 和 p2 这两个指针变量本身。

第3步:进阶——多变量值互换与排序

如果需要同时修改多个变量,只需按照同样的逻辑扩展指针参数即可。以下示例展示了如何输入三个整数并按从大到小输出。

操作步骤

  1. 在 main 函数中定义三个变量 a, b, c 及其对应的指针 p1, p2, p3。
  2. 将指针指向对应变量地址:p1=&a, p2=&b, p3=&c。
  3. 编写一个通用的 exchange 函数接收三个指针。
  4. 在 exchange 内部复用之前的 swap 逻辑进行两两比较和交换。
#include <iostream>
using namespace std;

int main( )
{
  void exchange(int *,int *,int *);
  int a,b,c,*p1,*p2,*p3;
  
  cin>>a>>b>>c;
  p1=&a;p2=&b;p3=&c;
  
  exchange(p1,p2,p3); //传入三个指针
  
  cout<<a<<" "<<b<<" "<<c<<endl;
}

void exchange(int *q1,int *q2,int *q3)
{
  void swap(int *,int *); //前置声明
  
  if(*q1<*q2) swap(q1,q2); //确保q1指向最大
  if(*q1<*q3) swap(q1,q3); //确保q1指向最大
  if(*q2<*q3) swap(q2,q3); //确保q2大于q3
}

void swap(int *pt1,int *pt2) 
{
  int temp;
  temp=*pt1; *pt1=*pt2; *pt2=temp;
}

测试结果:

12 -56 87↙
87 12 -56

总结与注意事项



通过上述分析可以看出,指针作为函数参数的核心优势在于它能突破单向值传递的限制,允许被调用函数修改外部变量。但在实际操作中必须遵循一条铁律:

  • 不要企图通过改变形参指针变量的值(即改变指针的指向)来影响实参指针。 例如,在 swap 函数里写 p1=p2; p2=temp; 只能改变函数内的局部指针副本,对 main 函数中的 pointer_1 和 pointer_2 毫无影响。
  • 真正需要操作的是指针指向的目标(即解引用后的内容 *p)。

函数的调用通常只返回一个值,而通过指针参数,我们可以像数组一样一次性获取或修改多个状态,这在处理复杂数据结构(如链表节点交换、大型对象拷贝优化)时是非常实用的技术。

以上就是C++指针作为函数参数的详细内容,更多关于C++编程基础与内存管理的资料请关注本站其它相关文章!

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表