zoukankan      html  css  js  c++  java
  • 数组指针、函数指针和尾置返回类型

    /* 本文试着给出一些结论

    * 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
    ", (*func(5))[9]);
    
        func = arithmetic_sequence1;
    
        // 正如预期,输出13
        printf("%d
    ", (*func(5))[8]);
    
        typedef int (*(*Func)(int i))[10];
        Func func1= arithmetic_sequence;
    
        // 正如预期,输出12
        printf("%d
    ", (*func1(5))[7]);
    
        decltype(arithmetic_sequence) *func2 = arithmetic_sequence;
    
        // 正如预期,输出11
        printf("%d
    ", (*func2(5))[6]);
    
        return 0;
    }
  • 相关阅读:
    PTA(Advanced Level)1063.Set Similarity
    PTA(Advanced Level)1047.Student List for Course
    PTA(Advanced Level)1023.Palindromic Number
    PTA(Advanced Level)1023.Have Fun with Numbers
    PTA(Basic Level)1017.A除以B
    PTA(Advanced Level)1059.Prime Factors
    PTA(Advanced Level)1096.Consecutive Factors
    expected primary-expression before xx token错误处理
    PTA(Advanced Level)1078.Hashing
    PTA(Advanced Level)1015.Reversible Primes
  • 原文地址:https://www.cnblogs.com/the-capricornus/p/6066379.html
Copyright © 2011-2022 走看看