C的指针定义及使用方式

在这里祝大家新年快乐,万事如意,在新的一年心想事成。

本篇文章全程都是小生自己按照自己的所学知识之后的总结,按照自己的方式去编写出来,如若编写方式不够好,还希望多指点指点。

在看本篇之前小生希望大家有了解什么是指针,以及指针的一些概念。

很多小伙伴在大学期间特别是计算机专业的同学都会上过C语言,那么最让人瑟瑟发抖,难以忘怀的便是指针了,什么地址,什么函数指针,指针函数,函数指针数组,指针函数数组,指向指针的指针,指向函数指针数组的指针,指向指针函数数组的指针,什么只读指针变量,什么只读变量指针,都让人不仅感叹C的强大,这就是为什么C的精髓在于指针,而且很多例如:结构体指针,链表,二叉树,栈,堆等等的数据结构和一些算法都是会运用到C的指针,而且你会发现,很多数据结构和算法书都是C语言版本,虽然也有其他语言版本的,但是在这里我强烈建议大家读明白学明白C版本的数据结构和算法,因为小生就是从C版本学起,因为当你理解了C版本的,再去学其他语言版本的数据结构和算法,就会发现只是换换语法罢了,很多还是一样的啊,就比如Java使用的是类与对象来实现链表,就好比使用C语言的结构体和结构体指针一样;那么话不多说,今天就开始学习C的指针吧。

那么首先我们得清楚C定义指针的基本语法

#include <stdio.h>


int main(){
    int *p = NULL;
    return 0;
}

普通变量一般只需要int p;但是指针变量就不一样了,只需要在p的基础上前面加一个*就是指针变量

那么有的小伙伴就会说,哎,为什么定义出来后要指向一个空NULL呢?按照小生的理解啊,其实就是为了防止指针会被乱使用,在这里我们可以去掉=和NULL,打印一下这个p

#include <stdio.h>


int main(){
    int *p;
    printf("%d\n", p); // 16
    return 0;
}

会发现,打印出来的是16,你以为这里的16就是数字16,不,其实是一个乱码值,而p就是指向这个乱码,而一旦指向一个乱码,那么就是一个野指针!野指针是一个很不好的东西,很可能导致你的程序错乱,甚至电脑蓝屏;所以为了避免野指针的出现,我们最好赋值上NULL(空)。那么有的人就会说,那赶紧给他赋值为NULL呗,其实在这里没有赋值也没有关系,因为这只是一个小实验,但是在真正开发当中,却不能这样子做,所以一旦指针定义出来,在没有赋值任何地址的情况下,一定要定义为NULL。

那么就会有疑惑了,为什么指针要定义int类型的指针呢?其他类型的指针可不可以?当然可以啦,只不过小生这里使用int类型的指针会方便理解一些。

那么接下来我们来看接下来的一个例子:

#include <stdio.h>


int main(){
    int a = 10;
    int *p = &a;
    printf("%d\n", *p);
    return 0;
}

哦~ 新的概念,这里我来解释一些,我们定义一个a变量,让它赋值为10;然后定义一个int类型的指针p等于&a;那么就会有疑惑出来了,&a是什么东西?我们知道,&&是与的意思,一个&呢?就是取地址,这里取的是谁的地址?当然是a啦,那么为什么可以把a的地址给p指针呢?因为指针本身就是指向一个地址,他可以通过该地址找到对应内存空间内对应的值;什么意思?就比如我们的去超市买东西,而我们自己也有东西,但是拿进去超市又不方便,于是就有了储物柜这个东西的出现。

 一般呢,每一个储物柜上都有对应的编号,那么超市的人员也会把对应的钥匙放在上面,那我们把东西放在某一个储物柜里面,通过钥匙锁上去,比如说我放在一号储物柜里面,那么这个时候,我们就可以通过这个储物柜来理解指针与地址的关系了,就相当于啊,储物柜就是内存空间,而你的东西就是对应的值,而1号就是这个储物柜的地址,而你就是指针p,你呢最后肯定会回来打开这个储物柜的东西;说到这,可能有的人还在云里雾里;那么我们可以在举一例:假如我小生,要去找小明,这个时候我联系了小明,说你家的地址在哪啊?小明给了我一个他家的地址,那么我根据这个地址找到了小明;那么大家就可以看成我小生就是*p,小明就是值10,而小明家地址就是a的地址,而他家就是那个对应的内存空间;相信聪明的你们一定能理解。

那么通过这一步相信你一定能理解基本的指针了,也不是很难,只要把他想象成储物柜,或者是我说的小明家的地址,很快就能明白了。

还有一个疑惑,为什么我们一定要用int类型的指针去指向int类型的值呢?如果我们用int类型的指针去指向其他的值呢?或者是用其他类型的指针去指向int类型的值呢?

#include <stdio.h>


int main(){
    int a = 10;
    float *p = &a;
    printf("%d\n", *p); // 0
    return 0;
}

比如这一块例子,大家看到输出出来是0?为什么是0,这其实也好理解嘛,类型的问题,你使用float类型的指针肯定得指向float类型的地址嘛,int类型明显就不行嘛;就好比你是男生你非得去女厕所撒泡尿再走,这不就是有点问题。

那么到这里我们学点难度一点点的,那就是通过指针改变值

#include <stdio.h>


int main(){
    int a = 10;
    int *p = &a;
    printf("%d\n", *p); // 10
    *p = 20;
    printf("%d\n", *p); // 20;
    return 0;
}

大家请看,我通过p指针去指向这个a的地址,也就是指向这个10,然后我通过了p这个指针去改变a中这个地址对应的值,将10换成20,虽然我这边打印的是*p而不是a,但是大家可以去试一下,在最下面return 0之前打印a这个值是不是变成20,那么*p中的*是什么?这个就类似于解包,当然不懂也没有关系;你把*看成是获取p指向这个a地址对应内存空间对应的值,那么*p=20则是将p指向的对应内存空间对应的值10替换成20。

看起来是不是有点绕,没有关系哈哈哈,刚开始学习确实有点难度;当然如果这一关你能理解,那么我们在深一点的

#include <stdio.h>


int main(){
    int a = 10, b = 20;
    int *p = &a, *p1 = &b;
    printf("变化前:\n");
    printf("%d\n", *p); // 10
    printf("%d\n", *p1); // 20

    p1 = p;
    printf("变化后\n");
    printf("%d %d\n", *p1, *p); // 10, 10
    return 0;
}

Σ(っ °Д °;)っ,这是什么操作,我的天;为什么p1变成跟p一样的值呢?还要为什么p能够赋予给p1呢?太绕了┭┮﹏┭┮;

别担心,我一个一个解答,p1为什么会和p一样的值呢?大家别忘了,我p1 = p这一步就彻底把p1对应的值改变成p对应的值了,因为p和p1都是指向a和b的地址,那么此时我将p指向的地址赋予给p1,此时p1指向的位置就彻底被改变了,就和p一样都指向了a的地址,那么打印出来就会两个都是10啦;至于为什么p能够赋予值给p1,因为我们知道*p1和*p都是int类型的指针对不对,那么p和p1则就是指向对应变量的地址,那么p和p1就表示该变量的地址了;而*p则是获取该地址指向对应内存空间对应的值,而p则就是指向这个对应内存空间对应值的地址。那有的人就会有疑惑,那我可不可以跟&a一样,把p前面也写上&这个呢?那这样的话就相当于啊,你把p的地址给了p1,那么就是把p指针本身的地址给了p1,那这样是不行的,因为*p是属于一级指针,你把一级指针的地址给了一级指针是不对的,应该把一级指针的地址给二级指针,关于二级指针有兴趣的可以去了解一下,或者是后续有机会小生也会讲解。

那么这就是简单C指针基础,后续小生也会去再编写一些关于指针的讲解。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Kepler_Class

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值