第6章 C语言的指针运算 (三)

发布于:2023-01-04 ⋅ 阅读:(296) ⋅ 点赞:(0)

文档视频讲解链接地址

  1. 腾讯课堂链接 : 54_指针_指针算术运算
  2. 腾讯课堂链接 : 55_指针_指针关系运算

6.3 指针运算

  1. 指针运算

    • 指针运算是以指针变量所存放的地址量作为运算量而进行的运算。因此,指针运算的实质就是地址的计算。
    • 指针运算的种类是有限的,它只能进行算术运算、关系运算和赋值运算。
    • 两个地址可以进行加 , 减 乘(没有意义) , 除(没有意义)
  2. 指针的算术运算见下表:
    01-c-79

  3. 指针变量运算

    • 指针加减一个n的运算
      px + n px - n
      01-c-80
  4. 指针变量运算注意事项

    • 不同数据类型的两个指针实行加减整数运算是无意义的。
    • px+n 表示的实际位置的地址量是:
      • (px) + sizeof(px的类型) * n
    • px-n 表示的实际位置的地址量是:
      • (px) - sizeof(px的类型) * n
  5. 指针加一、减一运算

    • px++, ++px, px–, --px
    • 01-c-81
  6. 指针变量占用内存字节数

    • 指针变量占用字节数和系统32位或64位有关系, 和前面的类型没有关系
    • 一个字节等于8个二进制的位
    • 32位是32个二进制的位
    • 64位是64个二进制的位
    • 32位系统的地址是32位(4字节)的, 因此一个指针变量保存一个地址, 这个指针变量占用4字节
    • 64位系统的地址是64位(8字节)的, 因此一个指针变量保存一个地址, 这个指针变量占用8字节
  7. 实例73

    • 分别计算char ,short ,int, long , long int , long long, float , double, long double 类型的指针++ 运算的值
    • 源文件
    01-cbase\73-pointer.c
    
    • 源代码
    #include <stdio.h>
    
    int main(int argc, char const *argv[])
    {
        char        a = 10;
        short       b = 10;
        int         c = 10;
        long        d = 10;
        long int    e = 10;
        long long   f = 10;
        float       g = 10.1;
        double      h = 10.1;
        long double i = 10.1;
    
        char         *pa = &a;
        short        *pb = &b;
        int          *pc = &c;
        long         *pd = &d; 
        long  int    *pe = &e; 
        long  long   *pf = &f; 
        float        *pg = &g; 
        double       *ph = &h; 
        long  double *pi = &i; 
    
        printf("&a=%p\n",&a);  // 是8个字节的地址, 保存这个地址,需要使用8个字节的存储空间
        printf("&b=%p\n",&b); 
        printf("&c=%p\n",&c); 
        printf("&d=%p\n",&d); 
        printf("&e=%p\n",&e); 
        printf("&f=%p\n",&f); 
        printf("&g=%p\n",&g); 
        printf("&h=%p\n",&h); 
        printf("&i=%p\n",&i); 
        
        // 指针变量存放的是地址量 , 
        // 这个系统是64为的系统, 每一个地址用64位表示, 因此每一个地址都是64位的
        // 一个地址用64位表示, 占用字节8个 , 存放一个地址的变量要使用8个字节来保存这个地址
        // 因此指针变量统一占用8字节的存储空间
        printf("sizeof(char  )=%d\n",sizeof(char  )); // char   是字符类型 
        printf("sizeof(char *)=%d\n",sizeof(char *)); // char * 是字符指针类型 
        printf("sizeof(pa    )=%d\n",sizeof(pa));// pa 是字符指针变量, 保存的是64位地址, 要占用8字节的存储
    
        printf("sizeof(short  )=%d\n",sizeof(short )); // short  是短整型 
        printf("sizeof(short *)=%d\n",sizeof(char *)); // short * 是短整型指针类型 
        printf("sizeof(pb     )=%d\n",sizeof(pb));// pb 是短整型指针变量, 保存的是64位地址, 要占用8字节的存储
    
        printf("sizeof(int    )=%d\n",sizeof(int   )); // int   是整型 
        printf("sizeof(int   *)=%d\n",sizeof(int  *)); // int  * 是整型指针类型 
        printf("sizeof(pc     )=%d\n",sizeof(pc));// pc 是短整型指针变量, 保存的是64位地址, 要占用8字节的存储
    
        printf("sizeof(long   )=%d\n", sizeof(long  )); // long  是长整型
        printf("sizeof(long  *)=%d\n", sizeof(long *)); // long * 是长整型指针类型
        printf("sizeof(pd     )=%d\n", sizeof(pd));     // pb 是短整型指针变量, 保存的是64位地址, 要占用8字节的存储
    
        printf("sizeof(long int  )=%d\n", sizeof(long int  )); // long int   是长整型
        printf("sizeof(long int *)=%d\n", sizeof(long int *)); // long int  * 是长整型指针类型
        printf("sizeof(pe        )=%d\n", sizeof(pe));     // pe 是长整型指针变量, 保存的是64位地址, 要占用8字节的存储
    
        printf("sizeof(long long  )=%d\n", sizeof(long long  )); // long long   是长整型
        printf("sizeof(long long *)=%d\n", sizeof(long long *)); // long long  * 是长整型指针类型
        printf("sizeof(pf         )=%d\n", sizeof(pf));     // pe 是长整型指针变量, 保存的是64位地址, 要占用8字节的存储
       
    
        printf("sizeof(float  )=%d\n", sizeof(float )); // float  是单精度浮点数
        printf("sizeof(float *)=%d\n", sizeof(float *)); // float * 是单精度浮点指针类型
        printf("sizeof(pg     )=%d\n", sizeof(pg));     // pg 是单精度浮点指针类型变量, 保存的是64位地址, 要占用8字节的存储
    
        printf("sizeof(double  )=%d\n", sizeof(double )); // double  是双精度浮点
        printf("sizeof(double *)=%d\n", sizeof(double *)); // double * 是双精度浮点指针类型
        printf("sizeof(ph      )=%d\n", sizeof(ph));     // ph 是双精度浮点指针变量, 保存的是64位地址, 要占用8字节的存储
        
        printf("sizeof(long double  )=%d\n", sizeof(long double )); // long double  是长双精度浮点
        printf("sizeof(long double *)=%d\n", sizeof(long double *)); // long doublet * 是长双精度浮点指针类型
        printf("sizeof(pi           )=%d\n", sizeof(pi));     // pi 是长双精度浮点指针变量, 保存的是64位地址, 要占用8字节的存储
    
    
        printf("pa =%p\n",pa);// pa保存的是变量a的地址 
        // char a = 10 ; 
        // char         *pa = &a;
        pa ++ ;  // 指针变量运算, 自增, pa +1 = pa + sizeof(char)  = 最后地址增加1 
        printf("pa =%p\n",pa);// pa保存的是变量a的地址 
    
    
        printf("pb =%p\n",pb);// pb保存的是变量b的地址 
        //  short        *pb = &b;
        pb ++ ;  // 指针变量运算, 自增, pb +1 = pb + sizeof(short)  = 最后地址增加2 
        printf("pb =%p\n",pb);// pb保存的是变量b的地址 
    
        printf("pc =%p\n",pc);// pc保存的是变量c的地址 
        //  int          *pc = &c;
        pc ++ ;  // 指针变量运算, 自增, pc +1 = pc + sizeof(int)  = 最后地址增加4 
        printf("pc =%p\n",pc);// pc保存的是变量c的地址 
    
        printf("pd =%p\n",pd);// pd保存的是变量d的地址 
        //  long          *pd = &d;
        pd ++ ;  // 指针变量运算, 自增, pd +1 = pd + sizeof(long)  = 最后地址增加4 
        printf("pd =%p\n",pd);// pd保存的是变量d的地址 
    
        printf("pe =%p\n",pe);// pe保存的是变量e的地址 
        // long int          *pe = &e;
        pe ++ ;  // 指针变量运算, 自增, pe +1 = pe + sizeof(long int)  = 最后地址增加4 
        printf("pe =%p\n",pe);// pe保存的是变量e的地址 
    
        printf("pf =%p\n",pf);// pf保存的是变量f的地址 
        // long long          *pf = &f;
        pf ++ ;  // 指针变量运算, 自增, pf +1 = pf + sizeof(long long)  = 最后地址增加8 
        printf("pf =%p\n",pf);// pf保存的是变量f的地址 
    
        printf("pg =%p\n",pg);// pg保存的是变量c的地址 
        //  float          *pg = &g;
        pg ++ ;  // 指针变量运算, 自增, pg +1 = pg + sizeof(float)  = 最后地址增加4 
        printf("pg =%p\n",pg);// pg保存的是变量g的地址 
    
        printf("ph =%p\n",ph);// ph保存的是变量h的地址 
        //  double          *ph = &h;
        ph ++ ;  // 指针变量运算, 自增, ph +1 = ph + sizeof(double)  = 最后地址增加8 
        printf("ph =%p\n",ph);// ph保存的是变量h的地址 
    
        printf("pi =%p\n",pi);// pi保存的是变量i的地址 
        //  long double          *pi = &i;
        pi ++ ;  // 指针变量运算, 自增, pi +1 = pi + sizeof(long double)  = 最后地址增加16 
        printf("pi =%p\n",pi);// pi保存的是变量i的地址 
    
        return 0;
    }
    
    
    • 运行结果
    &a=000000000061FDD7
    &b=000000000061FDD4
    &c=000000000061FDD0
    &d=000000000061FDCC
    &e=000000000061FDC8
    &f=000000000061FDC0
    &g=000000000061FDBC
    &h=000000000061FDB0
    &i=000000000061FDA0
    sizeof(char  )=1
    sizeof(char *)=8
    sizeof(pa    )=8
    sizeof(short  )=2
    sizeof(short *)=8
    sizeof(pb     )=8
    sizeof(int    )=4
    sizeof(int   *)=8
    sizeof(pc     )=8
    sizeof(long   )=4
    sizeof(long  *)=8
    sizeof(pd     )=8
    sizeof(long int  )=4
    sizeof(long int *)=8
    sizeof(pe        )=8
    sizeof(long long  )=8
    sizeof(long long *)=8
    sizeof(pf         )=8
    sizeof(float  )=4
    sizeof(float *)=8
    sizeof(pg     )=8
    sizeof(double  )=8
    sizeof(double *)=8
    sizeof(ph      )=8
    sizeof(long double  )=16
    sizeof(long double *)=8
    sizeof(pi           )=8
    pa =000000000061FDD7
    pa =000000000061FDD8
    pb =000000000061FDD4
    pb =000000000061FDD6
    pc =000000000061FDD0
    pc =000000000061FDD4
    pd =000000000061FDCC
    pd =000000000061FDD0
    pe =000000000061FDC8
    pe =000000000061FDCC
    pf =000000000061FDC0
    pf =000000000061FDC8
    pg =000000000061FDBC
    pg =000000000061FDC0
    ph =000000000061FDB0
    ph =000000000061FDB8
    pi =000000000061FDA0
    pi =000000000061FDB0
    
  8. 两指针相减运算

    • px-py 运算的结果是:
      • 两指针指向的地址位置之间相隔数据的个数。因此,两指针相减不是两指针持有的地址值相减的结果,而是按下列公式计算出的结果:
      • (p - q) / 类型字节长度
      • 两指针相减的结果值不是地址量,而是一个整数值,表示两指针之间相隔数据的个数。
  9. 实例74

    • 计算两个int类型指针相减的值
    • 源文件
    01-cbase\74-pointer.c
    
    • 源程序
    #include <stdio.h> 
    
    int main(int argc, char const *argv[])
    {
        int a[5];  // a[0],a[1],a[2],a[3],a[4]
                   //  pa   .    .    pb 
        int *pa = &a[0] ; 
        int *pb = &a[3] ; 
        printf("pa=%p\n",pa); 
        printf("pb=%p\n",pb); 
        printf("pb-pa=%d\n",pb-pa);  // pb-pa = (pb-pa)/sizeof(int)  = 3 
    
    
        return 0;
    }
    
    
    • 运行结果
    pa=000000000061FDF0
    pb=000000000061FDFC
    pb-pa=3
    
  10. 指针的关系运算

    • 指针的关系运算见下表:

      01-c-82

  11. 指针关系运算

    • 两指针之间的关系运算表示它们指向的地址位置之间的关系。指向地址大的指针大于指向地址小的指针。
    • 具有不同数据类型的指针之间的关系运算没有意义,指向不同数据区域的数据的两指针之间,关系运算也没有意义。
    • 指针与一般整数变量之间的关系运算没有意义。但可以和零进行等于或不等于的关系运算,判断指针是否为空。
  12. 指针赋值运算

    • 指针的赋值运算是通过赋值运算符向指针变量送一个地址值。向一个指针变量赋值时,送的值必须是地址常量或指针变量,不能是普通的整数(除了赋零以外)。

    • 指针赋值运算常见的有以下几种形式:

      • 把一个普通变量的地址赋给一个具有相同数据类型的指针变量

        • 例如:
        double  x=15,  *px  ;
        px=&x;
        
      • 把一个已有地址值的指针变量赋给具有相同数据类型的另一个指针变量,

        • 例如:
        float  a , *px,  *py  ; 
        px = &a  ;
        py = px  ;
        
      • 把一个数组的地址赋给具有相同数据类型的指针。

        • 例如:
        int  a[20],  *pa;
        pa = a;   //等价 pa = &a[0]
        
      • 把零赋给一个指针。

        • 例如:
        int  *pa;
        pa =0;     //表示指针的状态,什么也不指 , 此时这个指针就是空指针 
        
      • 复合形式,运算结果是一个地址量赋给一个具有相同数据类型的指针变量:

        • 例如:
        double  a[20],  *px=a,  *py ;   int  n=2 ;
        py = px+n ;
        py = px-n ;
        
      • 野指针 : 定义一个指针变量不赋初始值

        • 例如:
        int *pa ;  // 定义一个变量 , 不给这个变量赋初始值, 这个变量是随机值 
        *pa = 100 ; // 可能引发段错误, 非法操作内存, 操作系统认定这个应用程序做了危险的操作, 会把这个应用程序杀死 
        
        • 这个指针就是野指针, 野指针使用的时候很危险, 这个指针变量是随机数, 对指针进行写操作时候,可能会引发错误 。
  13. 实例75

    • 数组成员与数组的地址
    • 源文件
    01-cbase\75-pointer.c
    
    • 源代码
    #include <stdio.h>
    
    
    int main(int argc, char const *argv[])
    {
       
       int a[5] = {1,2,3,4,5};
       
       // 输出每一个成员的地址 
       printf("&a[0]=%p\n",&a[0]) ; 
       printf("&a[1]=%p\n",&a[1]) ; 
       printf("&a[2]=%p\n",&a[2]) ; 
       printf("&a[3]=%p\n",&a[3]) ; 
       printf("&a[4]=%p\n",&a[4]) ; 
    
       printf("a    =%p\n",a) ; // a是数组名,是一个地址常量,也是数组的起始地址, 同样也是数组第一个元素的地址 
       printf("&a[0]=%p\n",&a[0]) ; // a是数组名, 也是数组的起始地址, 同样也是数组第一个元素的地址 
    
    
       return 0;
    }
    
    
    • 运行结果
    &a[0]=000000000061FE00
    &a[1]=000000000061FE04
    &a[2]=000000000061FE08
    &a[3]=000000000061FE0C
    &a[4]=000000000061FE10
    a    =000000000061FE00
    &a[0]=000000000061FE00
    
  14. 实例76

    • 指针的使用

    • 用指针指向a,b两个变量,通过指针运算选出值最小的那个数

    • 源文件

    01-cbase\76-pointer.c
    
    • 源代码
    #include <stdio.h> 
    
    int main(int argc, char const *argv[])
    {
       int a,b;
       printf("请输入2个整数>:");
       scanf("%d%d",&a,&b);
       printf("a=%d,b=%d\n",a,b);
    
       int *pa = &a , *pb = &b ; 
       
       int min  = (*pa < *pb)?*pa:*pb;
       printf("min=%d\n",min);
    
    
    
       return 0;
    }
    
    
    • 运行结果
    // 第一次运行结果
    请输入2个整数>:12 9 
    a=12,b=9
    min=9
    // 第二次运行结果 
    请输入2个整数>:1 8
    a=1,b=8
    min=1
    
本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到