こんにちは。
なるほど、なかなかハードな問題ですね。一旦具体的な値を想定するのが良いです。
short *ai2 = (short *)(&ai[sizeof(ai)/sizeof(short)-2])-4;
について、やってみます。
まず、比較的メジャーなケースで考えましょう。int型が4バイト、short型を2バイトの処理系とします。
すると、sizeof(ai)
はint型2の配列のサイズのなで8、sizeof(short)
は2ですね。
すると、sizeof(ai)/sizeof(short)-2
は8/2-2
=2
です。
すると、ai[sizeof(ai)/sizeof(short)-2]
はai[2]
であることが分かります。
ここはいきなりハードですね。(初心者に出す問題としては「無し」のレベルかも)
aiは要素数が2の配列なので、ai[0]とai[1]は存在しますがai[2]は存在しません。
では、そのアドレスを計算できないかと言うと、アドレスは計算できます。
配列は必ずアドレスが連続しますから、ai[2]はメモリは割り当てられてなくてもアドレスは計算でき、ai[1]のアドレスにその要素のサイズを加えた値となります。
今、ai先頭のアドレスをxと置くとint型は4バイトですから、&ai[0]はx, &ai[1]はx+4, &ai[2]はx+8となります。
&ai[2]はx+8です。そして、(short*)へキャストして4引いてます。
x+8から、short型4つ分のバイト数を引くのでx+8-2*4
=x
となります。
(なんか泣きたくなりますね。でも、勉強のためですから我慢しましょう。)
つまり、ai2に入っている値とはaiと同じ値です。
確かめてみましょう。
C
1#include<stdio.h>
2
3int main(void){
4 int ai[2]={123,456};
5
6 short *ai2 = (short *)(&ai[sizeof(ai)/sizeof(short)-2])-4;
7 short *ai3 = (short *)((char *)((short *)(ai+2)-3)-1);
8printf("ai=%p, ai2=%p\n", ai, ai2);
9
10 int n;
11
12 for(n=0;n<7;n += 2)
13 printf("%d, %d\n",*(short *)((char *)ai2+n),n);
14
15 for(n=0;n<3;n++)
16 printf("%d, %d\n",*(ai3+n),n);
17}
Wandboxでやってみました。
txt
1ai=0x7ffdfceae780, ai2=0x7ffdfceae780
2123, 0
30, 2
4456, 4
50, 6
60, 0
7-14336, 1
81, 2
確かに同じ値になってますね。
これと同様の考え方をすれば解けるのではないかと思います。
後は頑張って下さい。(いや、なかなかハードでした。)