數組指針、函數指針和尾置返回類型

/* 本文試着給出一些結論數組

* 1 就近原則,const在指針符後面時修飾指針自己,在指針符前面時修飾指針所指變量函數

* 2 指針化原則,任何的變量,你想定義它的指針的時候,只要在指針聲明上多加個括號和指針符便可spa

* 3 還原原則,任何的指針,你想知道它指向的變量的類型時,只要把小括號和*號去掉便可指針

* 4 優先原則,當指針被小括號擴起來時,優先考慮它是指針,不然,它是數組code

*orm

* 指針化原則和還原原則對數組和函數都是適用的。blog

* 之後若是想定義一個函數的指針,只要比函數聲明時多加括號和星號便可ip

*it

* 還要說一下對 typedef 的理解,typedef 和變量聲明的格式是同樣的io

* 只不過 typedef 聲明瞭一個類型而已

*

* 若是由於返回類型太複雜而沒法顯式聲明一個函數指針,那你能夠用decltype來查詢函數的類型

*

* 本文還要說明的知識點是:

* 1 函數如何返回數組指針

* 2 尾置返回類型

* 3 typedef

* 4 decltype

*/

#include <algorithm>

/*
 */
void ptr_description()
{
    int a[10]; // 整型數組, a的類型是 int*, &a的類型是 int (*)[10]
    int *p1 = a; // 整型指針指向整型數組

    // 看看符合指針化原則嗎?
    // 同時優先原則也起做用,它是個指針
    int (*p2)[10] = &a; //數組指針, 因此初始化時記得要用地址符取地址

    // 根據優先原則來判斷,它是數組
    int *pp1[10]; // 指針數組
    pp1[0] = a;

    int b[5];

    // 就近原則
    const int *cp1 = a; // 指向只讀數組的指針
    cp1 = b;

    // 就近原則
    int *const cp2 = a; // 指向數組的只讀指針
    *(cp2 + 2) = 3;

    // 錯誤: cannot convert 'int*' to 'int (*)[10]' in initialization
    // int (*ep2)[10] = a;

    // 錯誤: assignment of read-only location '*(cp1 + 8u)'
    // *(cp1 + 2) = 3;

    // 錯誤: assignment of read-only variable 'cp2'
    // cp2 = b;
}

/* arithmetic_sequence是一個返回數組指針的函數
 * 函數的聲明形式是 Type (*function(parameter_list))[dimension]
 * 咱們來逐層理解該聲明的含義
 *    arithmetic_sequence(int i) 決定了函數名和參數列表
 *    (*arithmetic_sequence(int i)) *號決定了函數返回的是一個指針
 *    int (*arithmetic_sequence(int i))[10] int 和 10 決定了數組的元素類型和長度
 * 函數的聲明也遵循指針化原則和優先原則
 */
int (*arithmetic_sequence(int i))[10]
{
    static int array[10];

    std::transform(array, array + 10, array, [&] (int) {return i++;});

    return &array;
}

// 這是一種尾置返回類型的聲明格式
// 對於返回類型比較複雜的函數更有效,能夠直觀的看出返回類型
auto arithmetic_sequence1(int i) -> int (*)[10]
{
    static int array[10];

    std::transform(array, array + 10, array, [&] (int) {return i++;});

    return &array;
}

int main(int argc, char *argv[])
{
    // 指針化原則和還原原則
    int (*(*func)(int i))[10];
    func = arithmetic_sequence;

    // 正如預期,輸出14
    printf("%d\n", (*func(5))[9]);

    func = arithmetic_sequence1;

    // 正如預期,輸出13
    printf("%d\n", (*func(5))[8]);

    typedef int (*(*Func)(int i))[10];
    Func func1= arithmetic_sequence;

    // 正如預期,輸出12
    printf("%d\n", (*func1(5))[7]);

    decltype(arithmetic_sequence) *func2 = arithmetic_sequence;

    // 正如預期,輸出11
    printf("%d\n", (*func2(5))[6]);

    return 0;
}
相關文章
相關標籤/搜索