数组指针、函数指针和尾置返回类型
/* 本文试着给出一些结论
* 1 就近原则,const在指针符后面时修饰指针本身,在指针符前面时修饰指针所指变量
* 2 指针化原则,任何的变量,你想定义它的指针的时候,只要在指针声明上多加个括号和指针符即可
* 3 还原原则,任何的指针,你想知道它指向的变量的类型时,只要把小括号和*号去掉即可
* 4 优先原则,当指针被小括号扩起来时,优先考虑它是指针,否则,它是数组
*
* 指针化原则和还原原则对数组和函数都是适用的。
* 以后如果想定义一个函数的指针,只要比函数声明时多加括号和星号即可
*
* 还要说一下对 typedef 的理解,typedef 和变量声明的格式是一样的
* 只不过 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; }