• [原创]C/C++中复杂指针声明&&数组名的一点小事


    C/C++中指针声明一向是一个难点,当情况复杂时很容易弄错。当然实际情况可能较少用到复杂指针,但是深挖指针的内涵毕竟没有坏处。来看以下一例。

    有三个简单函数

    int mydb(int a)
    {
        return 2*a;
    }
    int mytri(int a)
    {
        return 3*a;
    }
    int myqua(int a)
    {
        return 4*a;
    }

    Q1. 声明一个指针数组存放以上三个函数。

    int (*fun_arr[3])(int) = {mydb, mytri, myqua};

    Q2. 声明一个指向数组元素的指针。

    int (** pfun)(int) = fun_arr;

    Q3. 声明一个数组指针,指向fun_arr

    int (*(*parr)[3])(int) = &fun_arr

    确定指针类型的步骤:

    1. 在一个声明表达式中定位 标识符

    例如在Q1中,标识符为fun_arr

    2. 根据优先级,将标识符先后与左右操作符相结合。注意声明指针的 * 的优先级低于 声明为数组的 [],圆括号()优先级最高。

    例如Q1中,fun_arr优先与[]结合,表明fun_arr是一个数组;Q3中parr被圆括号括住,那么parr先与*结合,表明parr是一个指针。

    3. 从标识符开始,由内向外递归结合左右操作符,逐渐扩大结果;并依据当前结果的类型填充“上下文”。

    例如,当前结果是指针,那么隐含的下文应该是,指针指向的类型是____?

            当前结果是数组,那么隐含的下文应该是,数组元素的类型是____?

    分析Q2的指针声明如下:

    a. pfun是一个指针: *pfun

    b. pfun指向一个指针: (**pfun)

    c. 这个指针指向一个函数: (** pfun)()

    d. 这个函数的参数是一个int,返回int: int (**pfun)(int)

    分析Q3如下:

    a. parr是一个指针: (*parr)

    b. 它指向一个数组,包含三个元素: (*parr)[3]

    c. 数组的元素是指针: * (*parr)[3]

    d. 指针指向一个函数  * (*parr)[3] ()

    e. 函数接受一个int,返回int : int * (*parr)[3](int)

    关于Q3的答案中为什么要把 fun_arr取地址再赋给 parr,这里引出第二个问题

    Q4. 数组名称的类型与对数组名取地址的类型一样吗?

    即 若int arr[3] = {1,2,3};

    arr与&arr的类型是一样的吗?

    ——————————————

    答案是不一样。

    arr 的类型是:指向arr中元素的指针,即 int *

    &arr的类型是:指向整个arr数组的指针,即 (*)[3]

    编译器会对语句: int * pi = &arr;

    显示类型不兼容的警告。

    知道了这些,可以解决这样的问题:

    int arr[3] = {1,2,3};

    print("%d\n",*((int *)(&arr+1)-1));

    结果是?

    ————————————————

    结果是:3

  • 相关阅读:
    第五次作业
    第四次作业
    第三次
    request.getAttribute()和 request.getParameter()有何区别
    .Servlet API中forward()与redirect()的区别
    jsp和servlet的区别、共同点、各自应用的范围
    Servlet的生命周期
    如何从CDN加载jQuery
    window.onload()函数和jQuery中的document.ready()的区别
    jquery中$.get()提交和$.post()提交的区别
  • 原文地址:https://www.cnblogs.com/friedwm/p/2621323.html
Copyright © 2020-2023  润新知