zoukankan      html  css  js  c++  java
  • 浅谈指针的本质

      

    内存地址(普通指针)或偏移地址(成员指针)。

    指向变量的指针,是数据内存的地址,指向函数的指针是代码内存的地址,指向数据的指针指向数组开始位置的地址。

    抽象点说,就是以一种统一的方式产生对不同数据结构的元素的引用

    理解指针要注意以下几个点:

      -- 每个指针都有类型,类型决定指针移动时的步长(假设可移动:++ / -- / +n / -n)

      -- 从内容上讲,指针就是地址,尤其是在机器级层面上

      -- 对指针进行类型转换,仅仅是改变了解释指针所指内存区域的方式,位模式没有变

      -- 指针可以指向函数,其值是函数对应机器代码的第一条指令的地址

      -- 指针和数组关系暧昧,如果你明白比例变址寻址,你就能清除数组名,下标,指针类型之间的关系,简单说:数组名即基地址(立即数),下标即变址,指针类型即比例因子,而指针的值就是:偏移量 + 变址 * 比例因子 +基地址【IA32】,这样你就明白数组名是个常量(在机器眼里就是个立即数寻址时对变址没有限制也就说明了C语言对下标越界不检查

      指针是储存地址的一个变量

    指针变量储存的就是一个地址, 可以有如下行为:
      * 改变该变量的值;
      * 取得该变量的值
    这和其他变量是一样的, 但是指针还可以做到:
      * 改变该变量指向的那个地址的值
      * 取得该变量指向的地址的值
    这只是编译器赋予指针的特定行为而已(通过& * 等语法), 在汇编层面大概就是间接寻址了.
    因此指针就是储存地址, 纠结「指针的指针」什么的可以退散了.

    指针为什么要有类型

    汇编中数据是没有类型的, 所以指针的类型是编译器在规定的, 通过了指针的类型检查, 才能保证你少犯错.
    因为其他数据有类型, 所以指针也得有类型.


    指针的类型表明: 你期望从这个地址里取出来的数据, 是什么类型的.

      大部分时候, 我们想从一个 *int 指针中取出来的值总是 int, 只有在特殊情况下我们才会想把 int 当成 uint 取出来, 类型检查就帮我们减少弄错类型的可能.

      另外, 类型也规定了指针移动的粒度, 你期望从一个 *int 取出一个 int, 那 *(int + 1) 如果是地址+1的话, 不就取出了奇怪的数字?
    所以这里的 *(int + 1) 的 1 起始是指代一个 sizeof(int), 这样你才能方便地访问连续的内存数据.
    在汇编中大概就是 [arr + 4]. (32位限定), 编译器根据指针的类型帮你做了这一步转换.
     
      你会发现计算机的本质就是计算,计算的内容是什么呢,就是数据,数据哪里来呢,需要有东西搬过来,这里面就需要用到寄存器了,在这里也可以理解成指针,不然计算机里面这么多数据,鬼知道要用到哪些数据来计算呢,要知道运算器只知道计算,再谈指针的类型??不就是告诉运算器或者说是计算机这些数据的内存范围吗,当然也有其他用途。对指针的理解不能止步于此,深入了解还得指望汇编了,无奈暂时没时间学习汇编,暂时粗粗的看看反汇编代码罢了,日后再整理。
     
  • 相关阅读:
    [error]The command could not be located because '/usr/bin' is not included
    hadoop伪分布式
    ssh免密码登录
    移动端中的陀螺仪,摇一摇
    利用百度地图做的定位,获取位置和经纬度
    租房短租发布场地,工作中遇到的复杂日期插件功能
    深入理解定时器系列第三篇——定时器应用(时钟、倒计时、秒表和闹钟)
    BOM之navigator对象和用户代理检测
    jq css3实现跑马灯+大转盘
    Vue小事例
  • 原文地址:https://www.cnblogs.com/still-smile/p/11646340.html
Copyright © 2011-2022 走看看