字體:小 中 大 | |
|
|
2009/10/31 21:09:18瀏覽51566|回應2|推薦4 | |
cpu是如何拿到所要的資料的呢?靠位址線(address)來選擇到所要的資料,所以位址線有多少條關係到總儲存數量的大小,一顆cpu有多少位址線是不一定的,未必一定要 . 一般來說pointer會依定址能力的寬度來分配大小,是設計compiler公司來決定的,只要足以存取到這顆cpu能定址到的位址就可以了,例如8051定址能力是16bit,可是這顆cpu擁有好幾個不同記憶體區塊,就需要多一個byte來指定到底是在哪裡,所以pointer在8051就是3bytes的大小,而Arm7一般來說都是32bit大小。 . “char *”的意思是資料為有正負號8bit的pointer,”unsign long *” 為無號32bit的pointer,那(void *)呢?就是無型別。 char *ptr8; unsigned long *ptr32; void * ptrx; ptr32 = ptr8; // 會引發compiler型別錯誤 ptrx = ptr8; // 不會引發錯誤,最多只有警告。 *ptr8 = 100; // 在一個8bit寬的地方填入100 *ptrx=100; // 錯誤,因為不知道目的地到底有多大。 . 那到底void *有甚麼用呢?用處很大ㄡ,”轉手與暫存用”,例如你寫了一個function要多種用途,尤其是具有擴展性的程式: typedef struct { char type; ooxx.... } OBJ_A; . typedef struct { char type; ccdd...; } OBJ_B; . enum { OBJ_A_LABLE, OBJ_B_LABLE }; OBJ_A MyObjA = { OBJ_A_LABLE, . . . .}; OBJ_B MyObjB = { OBJ_B_LABLE, . . . .}; . void ObjParser(void *obj) { char *type_p = (char*)obj; switch(*type_p) { case OBJ_A_LABLE: { OBJ_A *obj_p = (OBJ_A *)obj; // ....process } break;
case OBJ_B_LABLE: { OBJ_B *obj_p = (OBJ_B *)obj; // ....process } break; . . . . . . . } } void main(void) { ObjParser((void*)&ObjA); ObjParser((void*)&ObjB); } 當然引數也可以轉換成function pointer,不同傳回值與不同引數的function pointer都可以因為有void *的引數而被統一起來,將來也很容易擴展這個函式,整個程式不會因為功能變多而變得要修改許多地方,甚至可以function pointer與data pointer共用同一個void *obj,你只需要在你的switch case增加一個項目就可以了,善用void*,是可以讓程式穩定度與擴展性提升的方法之一,寫C程式要如何善用pointer是非常重要的,學校不知為什麼都不太願意交代清楚。 |
|
( 心情隨筆|心情日記 ) |