---
# System prepended metadata

title: 指標篇

---

# 指標篇
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
