zoukankan      html  css  js  c++  java
  • <C和指针---读书笔记6>

    指针

    指针是一种变量,和int、float、char一样,是一种基本的变量。只不过它比较抽象一些。

    我们知道在C语言中,声明一个变量a、b,编译器会为其分配一个物理地址 addr_1 、addr_2,在之后的C语言中,a =1操作,是把数值1存入该 addr_1,就等价于a值变为1。b = b+1 ,是先读取 addr_2的内容,加1操作后,再写会 addr_2内。

    可以这样理解: 变量出现在 =右侧,一般是 读 addr_x的内容,变量是左值,一般是 存入 addr_x。 在C语言中变量实质上就是 物理地址的代号。对变量名的操作本质上就是对 物理地址的操作。

    所以 a =1 ,b=b+1,都无非是 地址的读写操作。 像float、int、char这类变量,变量名等价于物理地址,a = "address 1"   b= "address 2"

    访问a就是访问 address1.   address1/2里面的内容就是a、b的值,没有其他特别的意义。

    int *p 声明了一个指针变量p, 依然存在  p = "address 3" 的映射。但是p里面的内容是一个特别得信息。它是地址 "address  n“。

    C语言使用    *p 间接的访问 ”address n“     使用p访问 "address 3",

    声明和初始化 

    (1)  int  *p ;  p = &a   (2) float  *p = &b ;

    方法1,首先声明p是一个 "指向int"的指针变量。 然后 p = &a ,把a的地址,存入 p内。 即 p内存储的值 = address_a

    方法2, 声明p是一个 "指向float"的指针变量。 是一个缩写形式。

    一定要理解: 变量p自己有一个物理地址addr_p,只不过(addr_p) =  &a.

     未初始化和非法指针

    因为我们经常需要对 指针变量进行间接访问,一定要保证指向的地址是一个安全可靠的。比如指针变量指向了一个未知的地址,后续盲目的

    对该地址进行间接读写,很可能出现大问题。所以要保证指针--->安全地址。

    非常可惜的是: 编译器对于未明确指定的指针变量不会进行分配。那我们分配到哪?最好有一个 绝对安全的地址供我们使用。

    NULL指针:  NULL值在stdio.h文件有明确  #define NULL  (  (void *) 0 )   把整型0强制转为指针型,并指向void类型数据。

    int *p = NULL ;  int *p =  (void *) 0  相当于   指针变量p =  0,并指向了 void。

    指针变量的间接访问 和直接访问

    int *p = &a ;    这时候  p =  10 ;这是非法的,本质原因是: 10是整型变量,p是 指针型变量,不能对等。  可以 p = (int *) 10; 把10也变为

    指向整数的指针变量。

    &p: 同样对变量p取地址,获得的是p的物理地址。该操作合情合法。

    *p : 左值,表示存入 (P)---->  address 内。 右值,取(P)---->  address内的数据。

             * &a = 25 , 即 * (address a) = 25 即存入 a地址内。

    指针的指针

    既然指针是一个变量,自己拥有自己的地址,那完全可以再用指针指向它,。 这就是指向指针的指针,简称指针的指针

    怎么声明? int **pp ;

    怎么表明指向的规则?  int  *p = &a ; int **pp = &p 即可。

    那么如何通过指针的指针 访问 整型变量a? 

     pp = &p

    *pp  是对 指针变量p的间接操作。  *p 是完成对 整型a的间接访问。

    **pp 才是最终对a的间接访问。

    指针表达式实例

    Char  ch =’a’;

    Char  *cp = &ch;

    表达式形式

    左值

    右值

    &ch

     

    获得ch变量的地址

    cp

    修改cp的内容,则指向位置将会变化

    读取cp的内容,即获得某个间接地址

    &cp

     

    获得指针变量cp自己的地址

    *cp

    把数据存入 间接地址内

    获取 间接地址 的内容

    *cp+1

    非法

    获取 间接地址 的内容,并加1操作

    *(cp+1)

    把数据存入 (间接地址+1)内

    获取 (间接地址+1) 的内容,

    ++cp

    非法

    Cp值加1,再返回新cp值,

    同时 指针的指向位置变化

    Cp++

     

    Cp值加1,返回旧cp值

    同时 指针的指向位置变化

    *++cp

    把数据存入(间接地址+1)内,

    同时 指针的指向位置变化

    获取 (间接地址+1) 的内容,

    同时 指针的指向位置变化

    *cp++

    因为返回的是旧cp值,故而

    把数据存入(间接地址)内,

    同时指针的指向位置变化

    因为返回的是旧cp值,故而

    获取 间接地址 的内容

    同时,指针的指向位置变化

    ++*cp

     

    获取 间接地址 的内容,+1之后,返回值

    指针的指向位置不会变化

    (*cp)++

     

    获取 间接地址 的内容,并返回。

    指针的指向位置不会变化

    ++*cp++

     

    获得间接地址 的内容+1,并返回

    指针的指向位置变化

    ++*++cp

     

    获得 间接地址+1 的内容,并对其加1,再返回,

    指针的指向位置变化

     这只是一个表格,描述了各种运算的结果。只为加深理解。

    指针的运算

    指针变量主要用于 间接操作,一般对指针变量本身的操作,并不是很多,主要就是加法运算。

    float  a[10] ; 

    float  *p = a;

    定义了一组浮点型数组,并把数组首地址赋给p。我们知道一个float 型会占用 4 bytes空间。

    P = Address_of_a[0].  如果我们执行p+1,本质上是想 P = Address_of_a[1].  那么p+1 应该是  p + 1* sizeof(float)

    庆幸的是,C编译器为我们进行了这个处理,使得我们可以更加方便的使用指针变量+1. 

    这也是我们声明指针时,为什么要说明指针指向的是什么数据类型。它其实是为了编译器处理 sizeof(xxx)操作、

     

     

  • 相关阅读:
    20162317袁逸灏 第四周实验报告:实验一 线性结构
    仿ArrayList功能的bag类
    算法复杂度课后作业
    20162317 2017-2018-1 《程序设计与数据结构》第3周学习总结
    学号 2017-2018-1 《程序设计与数据结构》第1周学习总结
    Android:有关下拉菜单导航的学习(供自己参考)
    Android:有关菜单的学习(供自己参考)
    Java:类集框架中集合的学习
    20162305李昱兴 2017-2018-1 《程序设计与数据结构》第1周学习总结
    第十六周 数据库课堂实践 20162305 李昱兴
  • 原文地址:https://www.cnblogs.com/mokang0421/p/7450440.html
Copyright © 2011-2022 走看看