小杨写了如下的指针接力程序,程序执行完后变量 a、*p1 和 *p2 的值分别是( )。
int a = 5;
int* p1 = &a;
int* p2 = p1;
*p2 = 10;答案C。指针和数组的代码追踪:画出变量和指针的内存示意图,追踪每次赋值后值的变化。
指针和数组追踪时画内存布局图可以大大简化理解。
【考点】指针赋值与解引用|变量作用域|内存地址传递
第一步:a = 5。第二步:p1 = &a,p1指向a的地址。第三步:p2 = p1,p2继承p1的地址(即a的地址)。第四步:*p2 = 10,解引用p2,把a的值改成10。最终a=10,*p1=10,*p2=10。这类题通法是:指针赋值是复制地址,解引用是修原变量。
陷阱1:认为*p2 = 10只改p2本身,不碰a(错在不解引用含义)。陷阱2:认为p2 = p1会改p1的值(错在指针赋值是复制地址)。陷阱3:认为*p1是a的副本,所以a变了*p1不变(错在*p1就是a的值)。选A的人常犯"指针只改指针自身"的错误,选B/D则是混淆了*p2和p2的语义。
反推:若p2初始为NULL,*p2=10会段错误;若p2指向a+1,则a不变但*p2=10。这类题核心是"指针是地址,赋值是复制地址,解引用是改原变量"。刷到指针题先问:p2指向哪里?*p2改的是谁?