运行下面代码,屏幕上输出是( )。
double* p_arr = new double[3];
p_arr[0] = 0.2;
p_arr[1] = 0.5;
p_arr[2] = 0.8;
p_arr += 1;
cout << p_arr[0] << endl;
p_arr -= 1;
delete p_arr;答案B。指针和数组的代码追踪:画出变量和指针的内存示意图,追踪每次赋值后值的变化。
指针和数组追踪时画内存布局图可以大大简化理解。
【考点】指针算术运算|动态内存分配|指针与数组映射
考纲定位:本题考查 GESP 四级大纲中"指针与动态内存"核心模块的复合应用。命题人特意将指针算术与下标访问嵌套,卡住的是"指针移动后下标仍从当前位置起算"这一盲区——多数学生只背"p++ 后 p[0] 是下一个元素",却忽略移动后的"p[0]"实际对应原数组下标 1。
解题思维:按执行流拆解——new double[3] 分配连续内存,p_arr 初始指向下标 0;依次赋值 0.2/0.5/0.8;p_arr += 1 使指针后移一个 double 长度(4 字节),此时 p_arr 实际指向原下标 1;cout << p_arr[0] 访问当前指针位置,即原数组第二个元素 0.5;p_arr -= 1 回退不影响输出;delete 释放内存,cout 已执行完毕。因此输出为 0.5。
陷阱拆解:A 项 0.2 是忘记指针移动,仍按初始位置取值;C 项 1.2 是误将 p_arr[0] 当作原下标 0+1 的元素再相加,混淆了指针偏移与下标偏移;D 项 1.5 是错误地认为 p_arr += 1 后 p_arr[0] 会累加前两个值,本质是把指针当成索引累加器。最阴险的是 p_arr += 1 后 p_arr[0] 访问的是第二个元素,许多学生只注意到"p 变了"却未重新评估"p[0]"的含义,导致选择 A。
反命题思维:若将 += 1 改为 += 2,输出将变为 0.8,考察多级偏移;若将 cout 改为 p_arr[1],则输出 0.8,暴露下标与指针关系;若保留 += 1 但将赋值改为 p_arr[0]=0.3,输出变为 0.5+0.3=0.8,检验是否理解"p_arr[0] 是当前指针位置的值"。刷到此类题,先自问:"指针移动后,p[0] 到底指哪个位置?"