顯示具有 C 標籤的文章。 顯示所有文章
顯示具有 C 標籤的文章。 顯示所有文章

2008年3月20日 星期四

一種奇怪的 C 寫法

在 Porting ARM Linux for NO MMU system 時, 遇到一個奇怪的寫法, 在 binfmt_flat.c 之中的 load_flat_binary() 函式之中, 有一段 code:


#include &lt include &gt
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], 也許有我不知道的秘密也說不定!!

2007年9月21日 星期五

在 Linux 上寫程式的一些小技巧

接上篇. 再談一下 Linux 的程式組合!!

自己寫程式, 一開始很依頼 IDE 環境, 常常在找什麼好的 IDE, 然後不斷地用新版, 因為它可以提供更好的功能!! 在 Windows 上, 目前用過最好用的大概是 SourceInsight, 在 Linux 是 source navigator. 可是到後來, 在 Linux 上我學了幾招 grep, find, perl 的一招半式之後, 發現對 IDE 的依頼越來越降低!! 舉例而言, 有時要找某個關鍵字, 就在根目錄下, 打:
grep -lr 'keyword' .
就會列出所有檔案, 如果你想稍微看一下那一行講什麼, 你可以打:
grep -r 'keyword' .
你想看某個 MACRO 定義在哪裏, 你可以打
grep -lr '#define *keyword' .
只要你懂了 Regular Expression 和 grep 基本語法, 然後就是你的熟練度和想像力的問題! 有時侯你在苦候 IDE 廠商提供的新功能, 其實在 Linux 下只是再重新組合一下就可以了!!

你說, 有時候蒐尋結果太多, terminal 視窗太小, 來不及看, 可以下:
grep -r 'keyword'|xmessage -file -
就會把結果輸入視窗!!
目前我只有學到 grep, Regular Expression 的皮毛, 以後有時間再慢慢玩. 現在我最想知道的是: 有沒有可以教我在 Linux 下如何顯示出 C 程式的 call tree? 我是指不需要執行, 直接從 source tree 去分析?

佇 Linux 來看GPX 檔案

最近定定有戶外活動。使用𤆬路機 (GPS) 來記錄行過的路線。普通我記錄路線,攏是用手機仔抑是專門个𤆬路機,罕得用電腦來看。 毋過,"仙人拍鼓有時錯,跤步踏差啥人無"。有一擺我無細膩,袂記得共一擺活動的路線收煞起來,閣直接開始記錄下一擺的活動,按呢共幾落...