zoukankan      html  css  js  c++  java
  • c/c++指针

    指针主要分:

       指向单一的某个对象/变量, 用于多态或函数指针, 这个不难 - 一级指针

      其次是指向数组, 用来操作/遍历数组元素 - 一级/二级指针

    指向数组的一级指针很简单了: p指向的是数组的元素, p++是指向下一个元素值, *p返回数组元素的值

    二级指针也不难吧, 你只要想到: p指向的是指针, p++指向的是下一个指针, **p才能得到具体的值. 二级指针主要用在:

      1 改变数组中局部变量指针, 移动局部指针;int **pp =&p; int *p=&arr;

      2 二维字符串数组

    指针常量和常量指针?

    正确解释和判断const的位置即可:

    指针常量:指针本身是一个常量: int * const p;

    常量指针: 指向常量的指针: int const *p;

    解释是"????的_ _", 然后看const的位置,和它后面跟的是什么:

    比较常用的是指针常量 const p, 这个主要用在函数形参上, 使得: 安全性(形参函数内部不能让该指针指向其他对象(但可以改变指向对象的值),也不能销毁该指针)

      和效率性(函数内部不需要检查该指针)

    函数指针和指针函数?

    跟上面的区别方法是一样的:

    函数指针: 指向函数的指针: int (*fp) (int x, int y);

    指针函数: 返回指针的函数: int * func(int, int);

    为什么会有这样的区别呢?是因为c/c++中的运算符的优先级和结合性:

    判断表达式的计算结果, 不只是看运算符的优先级,还要看运算符的结合性:

      优先级=1的: () [] . -> 它们是左结合, 计算时/判断时,结合性: 左结合, 是从左向右看;

      优先级=2的: "所有的单目运算符: - * ++ -- ! | ~等, 结合性: 右结合, 是从右向左看

        如:char **pp=&p ;   *pp++和(*pp)++是不一样的:因为*和++都是二级运算符,优先级相同,就要看结合性,由于都是右结合,所以

       *pp++是先让pp跟++结合,由于pp指向的只是一个指针, 不是数组, 则二级指针pp本身往下移动一次,然后再取值,这个是错误的,二级指针往下再移,就移到非法地址了!

       (*pp)++:由于有了括号,所以先计算*pp,找到那个一级指针,(由于一级指针指向的是数组首地址), 这个时候,一级指针++, 就可以执行数组的下一个元素了

    由于()的优先级高于*, 所以:  int * func(int, int) ,首先是func跟括号结合, 表示这是一个函数,....

                 int (*fp) (int , int), 括号将*fp括起来, 而括号是左结合,所以 先计算(*fp), 因此这是一个指针 然后看后面(int, int),

              则为一个函数,...

    指针函数返回地址,使用如: x=* func(1,2)

    函数指针代替函数名调用函数,而且它还可以通过switch结构, 指向别的函数 y=fp(1,2) 或者: y=(*fp)(1,2);

    指针和引用?

    要说它们的区别的话: 在传函数形参的时候都差不多,都是传递的变量地址,

    c++primer中说:

    1 指针形参, 得另外创建一个变量,就是指针变量; 而引用不会再创建新的变量;

    2 引用是绑定到某个对象上的, 别名, 一旦绑定,就不能再绑定其他变量,就像古代的妇女一样, 从一而终,所以引用要在定义时就要初始化,并且不能用空对象去

      初始化引用,指针则更随意, 随便指

    3 最重要的区别是: 赋值: 给引用赋值, 改变的是引用绑定的对象的值, 并不改变引用本身,不改变引用的绑定关系:

          int x, y;  int &rx =x; int &ry=y;

            rx=ry;  

        rx绑定的还是x,  x的值已经和y的值相同;

        而指针则很明确,改变指针, 将使指针指向新的变量, 但指针原来指向的变量的值并不改变;

    数组做形参的传递?

    数组名做参数,传递的只是数组名所指向的地址, 而且这个地址是不能变的, 相当于" 指针常量 int * const p; 也就是说不能: arr=&another_arr;

    不可能传递一个数组,再生成一个数组拷贝, c语言的设计者(当然,传递数组拷贝还是数组地址, 取决于设计者写的编译器的解释方式)设计不可能那样低效率

    数组的长度length=sizeof(arr)/sizeof(arr[0]); 不能在传递的函数中这样去求数组长度, 因为传递的是地址指针...

    new所指向的指针要不要加括号?

    中括号[ ] , 表示new出来的是一个对象还是多个对象,

    class Doctor;

    Doctor *pDoctor=new Doctor / new Doctor(); 表示的new出一个对象

    delete pDoctor;

    Doctor *pDoctors = new Docotor[N]/ new Doctor()[5] 表示向堆 申请new出 多个连续空间的对象出来

    delete [ ] pDoctors            要delete指针时, 必须加上[ ]表示销毁的是指向 :多个对象: 的指针...

    new Doctor= new Doctor() , 表示调用的是类的"默认的无参的缺省构造函数"

  • 相关阅读:
    [Ps]图层混合模式——排除
    [Swift]自定义View
    [Swift]Closures概念与使用
    [Swift]Class的概念与使用
    [Swift][OC]tableView去掉顶部空白
    html引用css的四种方法
    plSQL技巧:“tns:无法解析指定的连接标识符”问题详解
    桌面任务栏右侧的输入法状态(也就是语言栏)不见了,通常有以下几种解决方法:
    Myeclipse下java.lang.OutOfMemoryError: Java heap space的解决
    Tomcat使用相对路劲来访问
  • 原文地址:https://www.cnblogs.com/bkylee/p/4914506.html
Copyright © 2011-2022 走看看