NOIP 普及组初赛 · NOIP 2007 普及组初赛试题 第 24 题

选择题 · 答案 3,6 · 考点:指针与内存

← 整套速查表 NOIP 普及组初赛 全部真题

题目

看程序写结果:

#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 );
}

输出:_______________________________

答案:3,6

考点

指针与内存

解题思维

别被指针吓住,这道题考的是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的常客,难度不会突变,但可能会结合更复杂的调用链或数组指针,继续考察学生对‘值传递’本质的理解。暂无足够依据预测具体年份的题型变化,但掌握这一核心思想足以应对绝大多数变式。

同考点真题

在 OI伴学 里做这道题
登录后可计时作答、查看完整六段式解析,并按你的错题自动生成同类练习。
去刷题先做一次 AI 学情诊断