# 指標篇 contributed by < `colinyoyo26` > ## cdecl 科技公司面試題: ```clike void **(*d) (int &, char **(*)(char *, char **)); ``` 一開始看到覺得這個東西很神奇,但其實仔細拆開理解後就沒那麼困難了 cdecl 的解釋 - Warning: Unsupported in C -- 'reference' - declare d as pointer to function - (reference to int, - pointer to function - (pointer to char, - pointer to pointer to char) - returning pointer to pointer to char) - returning pointer to pointer to void 一開始 Warning 是因為 c 語言只有 call by value 沒有 call by reference 把上面的 declaration 拆成以下三個部份,在遞迴的拆解 arguments 的部份就很好理解了 - returning type: - void** - function designator - (*d) - arguments - (int &, char **(*)(char *, char **)) ## C語言規格書的定義 - C99 [3.14] ***Object*** - object region of data storage in the execution environment, the contents of which can represent values - C99 [6.2.5] ***Type*** - Array,function, and pointer types are collectively called derived declarator types.A declarator type derivation from a type T is the construction of a derived declarator typefromTby the application of an array-type, a function-type, or a pointer-type derivation to T. 看到這裡覺得把 Array function pointer 歸類成 derived declarator types 很貼切 去找了有關 derived declarator types 的敘述 - C99 [6.2.5] ***Type*** -Any number ofderived typescan be constructed from the object, function, and incomplete types, as follows: - An array type describes a contiguously allocated nonempty set of objects with a particular member object type, called the element type.36)Array types are characterized by their element type and by the number of elements in the array. Anarray type is said to be derived from its element type, and if its element type isT,the array type is sometimes called ‘‘array of T’’.The construction of an array type from an element type is called ‘‘array type derivation’’. >array type 為連續非空的特定 obeject type - A function type describes a function with specified return type. A function type is characterized by its return type and the number and types of its parameters. A function type is said to be derived from its return type, and if its return type is T,the function type is sometimes called ‘‘function returning T’’.The construction of a function type from a return type is called ‘‘function type derivation’’ - A pointer type may be derived from a function type, an object type, or an incomplete type, called the referenced type. A pointer type describes an object whose value provides a reference to an entity of the referenced type. A pointer type derived from the referenced type T is sometimes called ‘‘pointer to T’’.The construction of a pointer type from a referenced type is called ‘‘pointer type derivation’ :::info [這篇](https://hackmd.io/hqJBzualRcOrb2wMhheKCQ?both)寫到該敘述是 C 語言 call-by-value 的實證,有點不太理解是從哪裡看出來的 ::: ## Pointer to pointer ```clike= int B = 2; void func(int *p) { p = &B; } int main() { int A = 1, C = 3; int *ptrA = &A; func(ptrA); printf("%d\n", *ptrA); return 0; } ``` ``` 輸出結果: 1 ``` 上述程式碼中,第 6 行的地方,傳入 func 的值是 &A (address of A) 但是 p 和 ptrA 是不同的 object (p 是 func 的 local variable 而 ptrA 是 main 的 local variable) 所以更改 p 並不會更改到 ptrA 但是可以改為以下 code 直接更改 A 得值,結果如下 ```clike= void func(int *p) { *p = B; } ``` ``` 輸出結果: 2 ``` ```clike= int B = 2; void func(int **p) { *p = &B; } int main() { int A = 1, C = 3; int *ptrA = &A; func(&ptrA); printf("%d\n", *ptrA); return 0; } ``` ``` 輸出結果: 2 ``` 上述程式碼 p 的值為 &ptrA 所以 *p 和 ptrA 為不同別名的相同物件 (p 一樣是在 func 的 local variable ) *p 可以直接更改到 ptrA 的值,注意這裡第二個作法不同的是改變了 ptrA 的指向,而上面是改變 A 的值 以下用 gdb 把位址印出來進行驗證 main function ``` (gdb) p ptrA $12 = (int *) 0x7fffffffdd28 (gdb) p &ptrA $13 = (int **) 0x7fffffffdd30 (gdb) p *ptrA $17 = 1 ``` func function ``` (gdb) p &p $28 = (int ***) 0x7fffffffdd08 (gdb) p &(*p) $30 = (int **) 0x7fffffffdd30 ``` 從 address 可以看出 ptrA 和 *p 的確是相同的 object