初了解指针

指针

指针的概念

        在内存中每一个数据都有一个地址,这个地址叫做指针

        用于储存这个地址的变量叫做指针变量

        只不过平时我们把指针叫做地址,指针变量叫做指针。

指针的操作方式

        &  取地址符

            获取数据的地址,多字节数据获取首地址    

        在定义指针时是一个标识符     

             在其他场景下表示指针指向内存空间里的数据

 指针与变量的关系

         #include<stdio.h>

        int main(int argc, const char *argv[])
        {
            int a=100;
            int *p=&a;
            printf("a=%d &a=%p\n",a,&a); // a=100 &a=0x7ffdbf7f315c

           printf(" *p=%d  p=%p  &p=%p\n",*p,p,&p); // p=100 p=0x7ffdbf7f315c  &p=0x7ffdbf7f3160
           return 0;
        }

 指针的内存大小

        32位系统中 指针内存大小是4个字节;

        64位系统中 指针内存大小是8个字节;

指针的运算符

        算术运算符:+   -   ++  --  

        赋值运算符:=

        关系运算符:>=   <=  == !=

        *  指针操作的是内存地址  指针的运算就是把地址当作变量来进行运算

            因此不是同类型的指针变量运算毫无意义      

指针与一维数组

        数组名本身就是首地址

         #include<stdio.h>                                        

        int main(int argc, const char *argv[])
        {
            int s[10]={0};
            printf("s=%p     &s[0]=%p\n",s,&s[0]);
            //s=0x7ffd502a0ce0     &s[0]=0x7ffd502a0ce0

                   return 0;
        }

        因此   int *p=s;

        p==s    p==s[0]   p+1==s[0+1]

指针和二维数组

        数组名是数组的首地址,那么二维数组也是一个数组   但是二维数组有行和列两个[ ] [ ] 

         如果        

        s=[10][10]={0} ;       

        int *p=s ;   

        因为指针可以运算  那么p+1等于什么?

  

        #include<stdio.h>

        int main(int argc, const char *argv[])
        {
            int s[2][2]={0};
            int *p=s;
            printf("s=%p s[0][1]=%p s[1][o]=%p\n",s,&s[0][1],&s[1][0]);
            printf("p=%p   p++=%p\n",p,p+1);
            return 0;
        }        

        s=0x7ffc0375b100    s[0][1]=0x7ffc0375b104   s[1][o]=0x7ffc0375b108
        p=0x7ffc0375b100    p+1=0x7ffc0375b104

        p+1=是s[0][0+1]      如果要访问s[1][0]     也可以访问    p+3=s[1][0]

        很麻烦   所以有数组指针

数组指针

        本质上是个指针;

        格式   数据类型 (*变量名)[列宽]

        int (*p)[2]=s;

        

        #include<stdio.h>

        int main(int argc, const char *argv[])
        {
            int s[2][2]={0};
            int (*p)[2]=s;
            printf("s=%p s[0][1]=%p s[1][o]=%p\n",s,&s[0][1],&s[1][0]);
            printf("p=%p   p++=%p\n",p,p+1);
            return 0;
        }

        s=0x7ffc26f06cf0   s[0][1]=0x7ffc26f06cf4   s[1][o]=0x7ffc26f06cf8
        p=0x7ffc26f06cf0   p+1=0x7ffc26f06cf8

        指针每次加1     就会加  数据类型*列宽 个单位;

        相当于一个行指针    指定到行数         指向的是每行的头一个地址

        如果想获取其他元素   可以用  *  变成列指针

        #include<stdio.h>

        int main(int argc, const char *argv[])
        {
            int s[2][2]={0};
            int (*p)[2]=s;
            printf("s=%p s[1][0]=%p s[1][1]=%p\n",s,&s[1][0],&s[1][1]);
            printf("p+1=%p   *(p+1)+1=%p\n",p+1,*(p+1)+1);
            return 0;
        }

        s=0x7ffd103f6e00           s[1][0]=0x7ffd103f6e08         s[1][1]=0x7ffd103f6e0c
        p+1=0x7ffd103f6e08     *(p+1)+1=0x7ffd103f6e0c

      数组指针多用与函数传参二维数组时

指针数组

         本质上是个数组   是一个保存元素都是指针的数组;

         格式         数据类型  *数组名 [数组元素的个数]      

指针和字符串

        char s=“hello”;    这是把字符串常量 hello  赋值给了变量s   

        char *p=“hello”;       这是把char类型的指针 p 指向了字符串  hello 的地址

        注意  字符串常量定义之后不可以更改

 二级指针

        是一个保存指针的地址的指针;

        #include<stdio.h>

        int main(int argc, const char *argv[])
        {
            int a=100;
            int *p=&a;
            printf("a=%d &a=%p\n",a,&a); // a=100 &a=0x7ffdbf7f315c

           printf(" *p=%d  p=%p  &p=%p\n",*p,p,&p); // p=100 p=0x7ffdbf7f315c  &p=0x7ffdbf7f3160
           return 0;
        }

        指针p保存是变量a的地址     对p取地址得到的是     &p=0x7ffdbf7f3160

        指针的类型是 int * (8字节)  需要用一个int *的指针变量来保存 

        格式

                数据类型 *  指针变量名=&一级指针名; int **q=&p;

        

        #include<stdio.h>

        int main(int argc, const char *argv[])
        {
            int a=100;
            int *p=&a;
            int **q=&p;
            printf("a=%d &a=%p\n",a,&a);
            printf("p=%d p=%p  &p=%p\n",*p,p,&p);
            printf("q=%p *q=%p  **q=%d\n",q,*q,**q);
            return 0;
        }

                a=100 &a=0x7ffc0888b9c4
                p=100 p=0x7ffc0888b9c4          &p=0x7ffc0888b9c8
                q=0x7ffc0888b9c8           *q=0x7ffc0888b9c4  **q=100

        一级指针只能用二级指针保存    二级指针只能用三级指针保存 ............

        8字节用long 类型也能保存   只能保存地址的值  没办法用 * 取出里面的值

指针函数

        是一个返回值为指针类型的函数

        int *  function(){

                return  指针变量;

        }

        注意  不能返回局部变量的指针;

                局部变量在函数运行结束的会释放,指针就成了野指针

                可以返回

                全局变量的指针变量; 

                static 关键字修饰的局部变量;

                形参传递过来的指针变量;

函数指针

        是一个指向函数调用的指针;

        格式    返回值类型   (*指针名)(形参表);

         

        #include<stdio.h>

        void function(){

            printf("我是function\n");
        }


        int main(int argc, const char *argv[])
        {
    
            void (*p)()=function;
            function();
            p();
            return 0;
        }

        我是function
        我是function

        多用于回调函数

函数指针数组

        是一个数组  每个元素都是指向函数的指针

        格式     返回值(*指针名[ 元素个数] )  (形参表);

                         void( *p[2] )()={NULL};

                        p[1]=function1;

指向函数指针数组的指针

        是一个指针   指向函数指针数组

        格式 

                  返回值类型    (* ( * 指针名 ) )  ( 形参表 )=数组名;

                void  (*(*q) )()=p;

截至————————————————————————————————------2022.12.11

如有错误   接受批评  并改正

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值