C指针有浅到深

 1.指针的类型

       int*   (整型指针)  大小 4/8 (字节)
       char* (字符指针) 大小 4/8 (字节)
       short*  (整型指针) 大小 4/8 (字节)
       float*  (整型指针) 大小 4/8 (字节)
       long*  (整型指针) 大小 4/8 (字节)
       long long*  大小 4/8 (字节)

 2.指针变量的大小

    2.1.指针变量

       在我们平时口头叙述中习惯性的将指针变量叫做指针,其实我们口中的指针实则是一个指针变量,eg:int*p   ,p就是我们说的指针也就是指针变量也是地址

    2.2.指针大小

       以上几种指针类型的大小是多少尼,其实取决于你的编译环境,在计算指针大小的时候不能用类型去决定指针的大小,指针的类型无法去决定指针变量在存储的时候占用几个字节。
      int* char*  short*等以上的指针的大小其实都是4/8(字节),具体取决与我们的编译环境是x86机器还是x64机器,当使用x86机器环境编译是指针的大小都是4字节,当时用x64机器环境编译的时候指针的大小是8字节。

 3.常见的变量如何声明指针类型

    3.1.如下变量取地址后,该如何去声明指针类型

          int a=8  char b= 'a'    int c[10]={0}   char d[10]="ada"  int*x[5]={}  
          int*e=&a 
          int*f=&b 
          int *h=c
          int(*h)[10]=&c    
          int**h=x
          int*(*h)[5]=&x

    3.2.前两个简单的

         3.2.1  int*e=&a

            首先a是一个整数,取地址后用整型指针接收

         3.2.2  char*b=&b

             b是一个字符,取地址后用字符指针接收。

     3.3.深度理解,数组取值后的含义

           首先一个数组的数组名肯定是数组第一个元素的首地址,所以int*h=c,因为c表示的是数组首元素的地址,首元素是整型所以int*h=c,两个类型是等价的。
           其次int(*h)[10]到底是一个指针数组还是数组指针,(*h)先结合然后再是类型int[10],所以它是一个数组指针指向的是一个大小为10的数组,&c取到的并不是数组的首地址而是整个数组的地址,但是我们在控制台进行输出的时候可以发现c大的大小一致,因为整个数组在表示的时候也是采用首地址表示。如何去证明&c和c的地址大小不同,采用+1,当&c+1的时候我们可以发现跳过了整个数组大小,c+1只是跳过4个字节的大小也就是一个元素大小。
           总结int(*h)[10]的含义:其实指针指向的是一个存放10个整型的数组。

      3.4.int**h=x

          1.首先要知道二级指针指向是啥,二级指针指向的是存放一级指针存放的地址。
           2.举个简单的例子,int a=5 int*p=&a   int**c=&p,可以看出来我们&p去除了一个一级指针在内存的存放位置,根据二级指针的概念我们就完全可以用int**c来接受&p。
           3.那么来理解int**h=x,首先我们看一下int*x[5]={},根据我们上面叙述的数组指针和指针数组的判别方法我们就可以判断出int*x[5]={}是一个指针数组,是一个数组存放的是指针,那么我们x数组名表示的是首元素的地址,首元素是指针那么首元素的地址就可以用二级指针来接受。

        3.5int*(*h)[5]=&x

           那这个该怎么理解,首先x存放的是一个指针数组,对x取值拿到的是整个指针数组地址,那么我们需要一个大小相同的指针数组把就是int*[5],然后地址应该用指针*h那么合起来就是答案int*(*h)[5]=&x。

     4.指针类型的作用

           在上面,我们刚才说了那几种类型的指针大小都是相同的,那么指针类型到底有啥作用,其实指针类型可以控制我们在用那几种类型指针去访问地址的时候可以访问几个字节char类型是一个字节,int是四个字节,还有int类型指针加一跳过的是四个字节,但是char类型指针加一跳过的就是一个字节了。这里就可以体现出指针类型的作用了。

    5.指针数组的使用

        

         

// 数组指针的使用
// void print2(int (*p)[5],int r,int c){
//      int i=0;
//      int j=0;
//      for(i=0;i<r;i++){
//         for(j=0;j<c;j++){
//             // 正确写法
//             // printf("%d",*(*(p+i)+j));
//             printf("%d",p[i][j]);
//             // 错误写法
//             // printf("%d",*(((*p)+i)+j));
//         }
//         printf("\n");
//      }
// }
// int  main(){
//     int a[3][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
//     print2(a,3,5);
// }

  首先我们要认识到,二维数组的首地址其实是第一行整个一维数组的地址。所以我们在接受的时候需要使用一个数组指针类型是int[5],*(p+i)其实拿到的就是下一行的一维数组的整个数组的地址,那么我们进行加一和解引用拿到的是不是就是每一行的一维数组中存储的数据呢。*(*(p+i)+j)其实作用等于p[i][j],要理解这个先要理解地址加一解引用等于什么,举个简单的例子,int a[]={0},int*p=a,*(p+1)==a[0],是不是这个道理,那么*(p+i)等价于*(p[i]+j)是不是就等价于p[i][j]。

6.函数指针

  

// 函数指针
// int Add(int x,int y){
//     return x+y;
// }
// int main(){
// // 因为我们指针  存放的是int类型的函数地址  那么我们创建指针类型的时候也必须是int类型的函数指针
//   int(*p)(int,int)=Add;
//   int(*x)(int,int)=&Add;
// //   上面两种方式都表示的是函数的地址
// //   下面展示如何调用  一下两种调用方式都可以
//    int a=(*p)(2,3);
//    int b=x(2,3);
//    printf("%d %d",a,b);
// }

这里只是快速过了一下指针,其实指针还有很多复杂的写法其实我们只要理解了基础的原理在实际中遇到那些复杂的指针用法的之后我们完全可以自己分析。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值