指针详细介绍上

指针定义

个人感觉3步骤

int main()
{
        int  a = 10;
        //定义指针的三步骤
        //1  *与变量结合代表是一个指针变量  2 要保存谁的地址,将他的定义形式放在此处
        //3 用*p替换掉定义的变量
        //*p
        int  *p  =&a; 
        //分析
        //1与*结合代表这个一个指针变量
        //2p是变量,p的类型是将变量p本身拖黑,剩下的类型就是指针变量的类型  int   *
        //3指针变量p用来保存什么类型数据的地址 ,将指针变量p和指针变量p最近的*一起拖黑,
        //剩下什么类型就保存什么类型数据的地址
        //p = &a;
        return 0;
}

指针变量的使用

  1. 在使用时,对一个表达式取*,就会对表达式减一级*,如果对表达式取&,就会加一级*

  1. 不管什么类型的指针,指针变量的大小与编译器系统有关

int main()
{
        char  *p1;
        short *p2;
        int *p3;
        int **p4;//p4也是一个指针变量  int **
        printf("%d\n",sizeof(p1));
        printf("%d\n", sizeof(p2));
        printf("%d\n", sizeof(p3));
        printf("%d\n", sizeof(p4));
        return 0;
}

宽度

不同类型的指针变量,取指针指向的内容的宽度

指针的宽度 = sizeof(将指针变量与指针变量最近的*拖黑,剩下的类型)

宽度也叫做步长;

步长: 指针加1跨过多少个字节

char *p 1

short *p 2

int *p 4

Int **p sizeof(int *) 4

14 不同类型的指针变量,取指针指向的内容的宽度
指针的宽度 = sizeof(将指针变量与指针变量最近的*拖黑,剩下的类型) 
宽度也叫做步长; 
步长:  指针加1跨过多少个字节
char  *p       1 
short *p     2
int    *p      4
Int  **p    sizeof(int  *)   4

空指针

空指针的作用就是 如果使用玩指针讲指针赋值NULL,方便提醒下次使用时是否能用

int main()
{
        int  a;
        //将指针的值赋值为0,0x0000000 =  NULL
        int  *p = NULL;//给指针p的内容赋值为0
        
        *p = 200;//err  因为p保存了0x0000的地址,这个地址是不可以使用的,非法
        printf("%d\n",*p);
        system("pause");
        return 0;
}

野指针

野指针就是没有初始化的指针,指针的指向是随机的,不可以操作指针

指针p保存的地址一定是定义过的即向系统申请过的

/野指针
int main01()
{
        //野指针就是没有初始化的指针,指针的指向是随机的,不可以 操作野指针
        //int  a = 0;
        //指针p保存的地址一定是定义过的(向系统申请过的)
        int  *p;//野指针 
        *p = 200;
        printf("%d\n",*p);
        return 0;
}

万能指针void*

万能指针可以保存任意类型的地址但是访问时需要根据实际类型进行转换

//万能指针
int main()
{
        //void b; 不可以定义void类型的变量,因为编译器不知道给变量分配多大的空间
        //但是可以定义void *类型,因为指针都是4个字节
        int  a = 10;
        short b = 10;
        void *p = (void *)&a;//万能指针可以保存任意的地址
        void  *q = (void *)&b;
        //printf("%d\n", *p);//err  p是void*,不知道取几个字节的大小
        printf("%d\n",* (int *)p);// *(  (int *)地址)
        system("pause");
        return 0;
}

const修饰变量

const修饰变量时,不能通过直接更改变量来改变,要通过变量的地址来改变变量的值

const修饰谁,谁不能直接被改变,要通过地址来直接改变

int main()
{
        int  a = 10;
        int  b = 20;
        //const修饰的是 * 还是变量p,
        //这里修饰的是*
        
        //const int  *p = &a;//不能通过 *p,改p所指向空间的内容
        //*p = 100; err  因为不能通过p改p所指向空间的内容
        //const修饰的变量p
        //p保存的地址不可以修改
        //int  * const p = &a;
        //p = &b;err  p本身的值不能被更改
        const  int *const p = &a;//p本身的指向不能改变,不能通过*p修改p
        //向那块空间的内容
        system("pause");
        return 0;
}

多级指针

多级指针

定义多级指针保存数据的地址时,定义的指针的类型只需要比要保持的数据的类型多一级*

//多级指针
int main()
{       
        int a = 10;
        //*p  int a     int *p
        int *p = &a;
        //*q  int *p   int **q
        int **q = &p;
        //如果*和&相遇,相抵消
        // **q == *(*q) == *(p) ==  a
        //**q == *(*q) == *(&a) ==  a
        printf("%d\n", **q);
        // *k  int **q  int ***k
        int ***k = &q;
        //*符号结合,代表这个k是一个指针变量
        //k是一个变量
        //k的类型,将变量k拖黑,剩下的类型
        //k用来保存谁的地址  将变量k和k最近的*一起拖黑,剩下什么类型
        //就保存什么类型数据的地址
        int *******************g;
        int ********************f = &g;
        system("pause");
        return 0;
}

指针结合数组

指针结合数组

指针加1,跨过一个步长

int *p;

步长 = sizeof(int)

要得到内存的数据,就该先得到数据的地址

*(地址) 得到的是地址里面的内容

int main()
{
        //int  a[10] = {1,2,3,4,5,6,7,8,9,10};
        int  a[10] = { 0 };
        //a 数组名,首元素的地址
        int  *p = a;//指针p保存的是首元素的地址
        for (int i=0;i<sizeof(a)/sizeof(a[0]);i++)
        {
               //printf("%d ",a[i]);
               //printf("%d ", *(p+i));
               *(p + i) = i;
        }
        for (int i = 0; i<sizeof(a) / sizeof(a[0]); i++)
        {
               printf("%d ",a[i]);
               //printf("%d ", *(p+i));
               //*(p + i) = i;
        }
        system("pause");
        return 0;
}

指针运算

指针运算

两指针(类型一致)相减,得到的是中间跨过多少元素

两指针相加没有意义

int main()
{
        int  a[10] = {1,2,3,4,5,6,7,8,9,10};
        //sizeof(int [10])
        int *p = a;
        //int  *q = (int *)(&a + 1) - 1;
        int  *q = &a[9];
        printf("%d\n",q-p);//  p+9 ==  q
        printf("%d\n",*(p+3));
        //两指针相加没有意义
        // printf("%d\n", p+q);err
        system("pause");
        return 0;
}

指针数组

指针数组

整型数组 是一个数组,数组的每一个元素是整型

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

int main()
{
        int a = 10;
        int b = 20;
        int c = 30;
        // int *p1 = &a  int *p2 = &a  int *p2 = &a
        //需求:  数组中的每一个元素都是指针(地址)
        int *num[3] = {&a,&b,&c};
        //printf("%d\n",sizeof(num));
        &a  ==  num[0]
        //for(int i=0;i<sizeof(num)/sizeof(num[0]);i++)
        //{
        // printf("%d\n",*num[i]);
        //
        //}
        //定义一个指针用来保存数组num首元素的地址
        // num ==  &num[0] =   &(int *)  == int **
        //num[0]是int *类型,要保持int  *类型的地址,需要比它多一级*
        int **k = num;
        for (int i = 0; i < sizeof(num) / sizeof(num[0]); i++)
        {
               printf("%d ",**(k+i));
        }
        
        system("pause");
        return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值