#include < include >
int main(int argc, char **argv)
{
char j;
int k;
int q[10]={1,2,3,4,5,6,7,8,9,10};
int *p= (int*) q[5];
for(j=0;j<3;j++) {
k = (j)[(unsigned int*) &q[5]];
printf("k is %d\n",k);
}
}
它的輸出是:
black@black2:~/workarea$ ./a.out
k is 6
k is 7
k is 8
如果我把
k = (j)[(unsigned int*) &q[5]];
改成
k = (j)[(unsigned char*) &q[5]];
則輸出會是 6,0,0, 若改成 unsigned short, 則輸出會是 6,0,7!
但是我改變 j 的型態為 char, short, long 都不會有影響!!
事實上, 一個陣列名稱不過是代表某個位址的 symbol, 因此, 它的元素的位址本來就是
symbol address + index*element_size
所以也許我們可以把 j 看成一個變動的 symbol address!! 於是我作個實驗, 把 [ ] 中的指標拿掉, 結果出現錯誤:
error: subscripted value is neither array nor pointer
C 似乎期待在中間一定要有一個 pointer 或 arrary!! 事實上, 在 C 中 array 和 pointer 本來也是互相為用!!
從以上結果可以推論: 它的位址計算方式, 是 ( (unsigned char*) &q[5] + j), 如果你是 unsigned char 的話!! 我們再作一次實驗:
#include
int main(int argc, char **argv)
{
short j;
int k;
int l;
int q[10]={1,2,3,4,5,6,7,8,9,10};
int *p= (int*) q[5];
for(j=0;j<3;j++) {
k = (j)[(unsigned char *) &q[5]];
printf("k is %d\n",k);
l = ((unsigned char *) &q[5])[j];
printf("l is %d\n",l);
}
}
在此的 k 和 l 會得到完全相同的值!!
因此, 我們可以說: (j)[(unsigned char*) &q[5]] 幾乎就是 ((unsigned char*) &q[5])[j]!!
當然, 行文至此, 我只是用實驗的方式知道段程式的行為, 但仍不知那一條規則容許它這樣寫? 這有待高手替我解答了!!
我也不了解這位老兄為什麼用 (j)[(unsigned char*) &q[5]] 而不用 ((unsigned char*) &q[5])[j], 也許有我不知道的秘密也說不定!!