/* 本文試着給出一些結論數組
* 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; }