年紀大,東西都忘東忘西的,今天複習C Primer Plus 4/e,把一些東西記錄下來。
高度技巧的宣告
* 表示一個指標
() 表示一個函數
[] 表示一個陣列
※()與[]有相同的優先順序,他們的結合姓是由左到右 →
int a[8][8];  //int陣列的陣列
int **ptr;  //指向int 指標的指標
int *risks[10];  //指向int 型態的10個指標陣列
int (*risks)[10]; //指向10個int 陣列的指標 
int *oof[3][4];  //指向int型態的3x4指標陣列
int (*uuf)[3][4];      //指向3x4 int 陣列的指標
int (*uof[3])[4]; //指向4個元素的int 陣列的3個元素的指標陣列
char *fump();   //回傳指向字元的指標的函數
char (*fump)();  //指向會回傳字元型態的函數的指標
char (*fump[3])(); //3個指向會回傳字元型態的函數的指標陣列
typedef int arr5[5];  
typedef arr5 *P_arr5;
typedef p_arr5 arrp10[10];
arr5    togs; //togs是有5個int元素的陣列
p_arr5  P2;    //p2是指向有5個int陣列的指標
arrp10  ap;  //ap是10個指向5個int陣列的指標陣列
函數宣告與指標
void ToUpper(char *); //將字串轉大寫
其中ToUpper()函數型態是void,參數是char *,如果宣告為這個函數宣告一個 pf指標,就會像下面一樣:
void (*pf)(char*);   //指向函數的指標,例如: pf=ToUpper,但是不能寫成pf=ToUpper();
其中括號內的(*pf)會被括號結合,所以閱讀時他會是一個指標,所以他是一個指向函數的指標,如果省略就會不同意義:
void *pf(char *) ; //pf 是回傳指標的函數
※一般如果沒有註明時,定義的名稱本身就是位址起始,例如:
   int a[10];
   int *p;
   p=a; 或是 p=&a[0];
   
   void ToUpper(char *);
   void (*pf)(char*);
   pf=ToUpper;
應用範例:
   void ToUpper(char *);
   void (*pf)(char*);
   void Show(void (*ff)(char*), char *str);
   pf=ToUpper;
   Show(ToUpper, mis); //Show函數使用ToUpper函數: ff=ToUpper
   Show(pf, mis); //Show函數使用ToUpper函數: ff=pf
void Show(void (*ff)(char*), char *str)
{
   (*ff)(str); //呼叫ToUpper函數,參數=str
   puts(str); //顯示字串 
}
C語言與組合語言對應
;-------------------------------------------
;  VOID  Funcation_A(VOID);
;-------------------------------------------
Funcation_A  PROC    PUBLIC
    push   eax
    .... 
    pop    eax
    ret
Funcation_A ENDP
;------------------------------------------------------------------------------
;  VOID Funcation_B (IN UINT32 RegisterInEax, OUT  OEM_REGISTER *Reg);
;
;typedef struct {
;  UINT32 RegEax;
;  UINT32 RegEbx;
;  UINT32 RegEcx;
;  UINT32 RegEdx;
;}OEM_REGISTER;
;------------------------------------------------------------------------------
Funcation_B PROC    PUBLIC RegisterInEax:UINT32, Reg:PTR EFI_CPUID_REGISTER
     pushad
     ...
     mov    edi, DWORD PTR Reg
     ... 
     mov    DWORD PTR [edi].RegEax, eax   ; Reg->RegEax
     ...
     popad
     ret
Funcation_B  ENDP
;------------------------------------------------------------------------------
;  UINT32 OemIoPortRead32 (IN  UINT64    Address); //回傳值放EAX
;------------------------------------------------------------------------------
OemIoPortRead32 PROC    PUBLIC  Address:UINT64
    push   edx
    mov    edx, DWORD PTR  Address
    in     eax, dx
    pop    edx
    ret
OemIoPortRead32 ENDP
 
 
1 則留言:
我也來複習一下..
謝謝你的分享~!
張貼留言