看程序写结果:
#include<stdio.h>
void fun( int *a, int *b )
{
int *k;
k = a; a = b; b = k;
}
int main()
{
int a = 3, b = 6, *x = &a, *y = &b;
fun( x, y );
printf( "%d,%d ", a, b );
}输出:_______________________________
别被指针吓住,这道题考的是C语言最基础的参数传递机制。拿到题先别急着看函数体,想想实参和形参的关系:所有参数都是值传递,交换形参的指向绝不等于交换实参的值,更别指望能改内存里的数,所以答案肯定是不变。
最容易栽跟头就是以为传了地址就能改原值,或者觉得函数里交换了指针,main里的指针也跟着换了。其实指针本身也是值传递的,交换的是形参副本,实参毫发无损。还有种情况是看到指针就下意识想解引用去改值,但题目里根本没写解引用操作,所以值不会变。另外要注意区分‘交换指针指向’和‘交换指针所指的变量值’,前者不影响实参,后者才需要解引用。
这道题考查的是C语言指针作为函数参数时的值传递机制,以及参数交换对实参的影响。从命题角度看,出题人特意把指针当参数传进来,再在函数里交换这两个形参的指向,就是想测试学生是否真正理解‘值传递’的含义——即便传的是地址,函数内部对形参的修改也不会波及到实参。历年这类题在NOIP普及组初赛出现过,属于高频考点,尤其容易在‘看起来像交换了’的陷阱里掉进去。
先理清概念:C语言里所有函数参数都是按值传递的。也就是说,调用fun(x, y)时,系统会把x和y的值(也就是它们存储的地址)各复制一份给形参x和y。形参只是实参的一个副本,函数里改形参,实参毫发无伤。特别要注意,指针本身也是一种值,所以交换两个指针形参,只是交换了这两个副本的地址,绝不会改变main里原来的指针变量x和y,更不会通过它们去修改a和b的值。
现在一步步看代码:
main里定义了a=3,b=6,x=&a,y=&b。调用fun(x, y)时,形参x拿到&a,形参y拿到&b。进入fun函数后,用临时指针k保存x(即&a),然后把x指向y(&b),y指向k(&a)。这一步确实把两个形参的指向互换了,但函数返回后,main里的x和y还是原来的值,a和b也从来没被解引用过,所以它们的值一直是3和6。
printf输出的是a和b的值,所以结果必然是3,6。
避坑指南:很多学生会以为‘传了地址就能改原值’,或者看到函数里交换了指针就认为main里的指针也跟着换了,甚至误以为a和b的值被交换了。记住:指针作为参数也是值传递,交换形参不等于交换实参,更不等于交换实参指向的变量值。只有当函数里写了解引用操作(比如*temp = *x; *x = *y; *y = temp;)时,才会真正修改内存里的数。
从考频数据看,指针相关题目在近些年占比很高,2025年单年就有25题涉及,2024年17题,2023年13题,整体呈上升趋势。GESP竞赛里四级、五级、六级、七级都大量出现,说明这是从入门到进阶都必须扎实掌握的基础。未来预测:基于现有数据,指针作为参数传递、交换指针形参、解引用修改值这类辨析题仍会是初赛和GESP的常客,难度不会突变,但可能会结合更复杂的调用链或数组指针,继续考察学生对‘值传递’本质的理解。暂无足够依据预测具体年份的题型变化,但掌握这一核心思想足以应对绝大多数变式。