#include <stdio.h>
void fun( int *a, int *b )
{
int *k;
k = a; a = b; b = k;
}
main()
{
int a = 3, b = 6, *x = &a, *y = &b;
fun( x, y );
printf( "No.1: %d,%d ", a, b );
fun( &a, &b );
printf( "No.2: %d,%d\n", a, b );
}输出:____________________
这题考指针传值与传引用的区别。拿到题先看fun里交换的是指针变量本身还是它指向的内容,再结合调用时传的是指针还是地址,一步步推a和b的值变没变。
最容易错在以为fun交换了指针后,main里的x和y也跟着换了,或者以为fun(&a,&b)能交换a和b的值。其实fun里只是交换了两个形参指针的值,形参是实参的副本,回去后实参指针x、y没变;而fun(&a,&b)传的是地址,形参a、b指向的是main里的全局变量a、b,交换形参后main里的a、b也不变,因为交换的是形参指针的值,不是它们指向的整型变量。
考点:指针传值与传引用
这题核心就是看fun函数里交换的是指针本身还是指针指向的内容。形参a、b是int*类型,函数里k=a; a=b; b=k;只是交换了两个指针变量的值,也就是交换了它们存储的地址。因为C语言里指针传参是传值,形参是实参的副本,所以fun里改的是副本,回去后实参x、y没变。再看fun(&a,&b)这一句,&a和&b是main里变量a、b的地址,传进去后形参a、b指向的是main里的全局变量a、b,交换形参指针的值,main里的a、b也不变,因为交换的是形参指针的值,不是它们指向的整型变量。所以输出是No.1:3,6 No.2:3,6。
命题视角
命题人喜欢考指针传值与传引用的区别,尤其是形参交换指针本身与交换指针指向内容的区别。这道题就是典型的陷阱:fun里交换了指针本身,但形参是副本,所以实参不变;而fun(&a,&b)传的是地址,形参a、b指向的是main里的全局变量a、b,交换形参指针的值,main里的a、b也不变,因为交换的是形参指针的值,不是它们指向的整型变量。
思考心法
拿到题先看fun里交换的是指针本身还是它指向的内容。交换指针本身用k=a; a=b; b=k;;交换指针指向的内容用*a=*b;。再看调用时传的是指针还是地址。传指针时形参是实参的副本,交换形参指针的值,实参不变;传地址时形参指向的是main里的全局变量a、b,交换形参指针的值,main里的a、b也不变,因为交换的是形参指针的值,不是它们指向的整型变量。所以输出是No.1:3,6 No.2:3,6。
避坑
最容易错在以为fun交换了指针后,main里的x和y也跟着换了,或者以为fun(&a,&b)能交换a和b的值。其实fun里只是交换了两个形参指针的值,形参是实参的副本,回去后实参指针x、y没变;而fun(&a,&b)传的是地址,形参a、b指向的是main里的全局变量a、b,交换形参指针的值,main里的a、b也不变,因为交换的是形参指针的值,不是它们指向的整型变量。
考频与趋势
指针与引用是题库共考过99题,覆盖8个考试级别(2007-2026);逐年分布:2007年1题、2015年1题、2017年1题、2022年1题、2023年16题、2024年20题、2025年25题、2026年20题、null年14题;分赛事:GESP四级24题、GESP五级22题、GESP七级18题、GESP六级16题、CSP入门级13题、GESP八级3题、NOIP普及组初赛2题、NOIP提高组初赛1题。从数据看,指针考点在近年明显增加,2023-2026年分别考了16、20、25、20题,说明命题人越来越重视指针与引用的细节区分。
预测
基于给定数据与经验,未来可能继续考指针传值与传引用的区别,尤其是形参交换指针本身与交换指针指向内容的区别。暂无足够依据预测具体年份和题型,但指针考点在近年明显增加,2023-2026年分别考了16、20、25、20题,说明命题人越来越重视指针与引用的细节区分。