初步认识指针(C语言)

在学习指针之前我们要知道一些东西:

1.int* p = &a;,我们来看这个代码的意义:*可以说明p是指针,int是指p指针所指向的对象是int类型&a就是将a的地址存放到p中。这个含义在二级指针会进一步讲解。

2.*还有其他含义,例如解引用,*(p + 1);,这个代码的意义就是,我要引用p指针所指向的值的后一个值。而arr[i]本质上就是*(arr + i),arr[ i ]代表我们要引用arr中第i个元素,而arr又代表首元素地址,那么我们就可以理解了,原来arr[ i ]=*(arr + i)=*(p + i),此处int* p = arr ; 。

一、指针和指针类型

       1.指针:所谓指针,就是指向某一个元素的变量,也叫做指针变量,可以将其理解为地址。例如:我们创建一个变量int a = 0;,当我们想得到这个变量的地址时,我们就可以这样写:int* pa = &a; 再将其打印出来printf("%p\n",pa);这样我们就可以得到a的地址。

        2.指针类型:指针类型也分为int float double long char....这些类型,而在我们对这些指针之间的地址进行加减之类的操作的时候,他们对应地址所跳过的字节大小也各不相同。例:对int型的指针+1也就是上述的pa+1。当它与pa进行比较的时候,我们可以在输出的地址中看出他们之间相差4个字节,而char类型的指针之间相差1个字节,double类型相差8个字节。

        各个类型的指针之间也是不能相互应用的,例如我们不能将一个整形的地址传给一个char类型的指针。

        当然,我们也可以进行强制类型转换,来达到我们将不同类型变量取地址来赋给不同类型的指针,是这样做会出现一系列的问题,例如,我们都知道,一个整形所占4个字节。举个例子:int a = 0x11223344,此时我们查看内存可以发现a的地址中储存着 44 33 22 11,那我们可以解引用a的指针变量来讲a地址中储存的值全都改为0, *pa = 0;,内存中显示的结果就变为00 00 00 00,但是,如果我们取a的地址,将这个地址赋给一个char类型的指针变量的时候,char* pc = (char*)&a,此时我们再次解引用*pc =0;,那么这时候我们就不能将a地址中4个字节的全部内容都改为0,内存中显示的结果为 00 33 22 11。这也在某种程度上印证了,不同类型的指针,最好不要通用,以及int类型的指针与指针之间相差4个字节,而char类型的指针与指针之间相差1个字节。

二、野指针

野指针是我们在写代码的时候,总会出现的一些错误,野指针的形成方式有三种:

        1.指针没有初始化,这种类型的野指针可能是因为,我们创建一个指针的时候,暂时还不知道给这个指针赋一个什么地址,那么就会形成野指针,为了避免这种情况的发生,我们可以先给这个指针赋值一个NULL(空指针),当我们想要使用这个指针的时候,再写一个选择语句:如果这个指针不是空指针。再使用这个指针变量,就避免了这种情况。

        2.指针越界访问,指针的越界访问类似于数组的越界,只不过数组的越界是当我们访问数组的某一个元素的时候越界,而指针的越界类似于我们想访问越界数组的元素所对应的指针。

住:指针的越界在“指针运算”中有一种情况很特殊,在指针-指针以及指针的关系运算会讲到。

        3.指针所指向的空间释放,众所周知,变量是分为全局变量以及局部变量的,当我们在一个函数test()中定义一个数int a = 10;,然后将这个数的地址返回到我们的主函数时,在主函数想用一个指针变量来接收,int* pa = test(),这时,由于a是局部变量,在函数调用结束的一瞬间,这个变量所占的空间就还给了操作系统,销毁了,也就是指针所指向的空间释放,那么此时的*pa就成了野指针

三、指针运算

全局变量:这里用的数组都是arr[6]={0};

        1.指针+-整数:*p+1,可以找到*p所对应的地址的后一个地址,减类似。

        2.指针-指针:指针-指针可以得到两个指针之间元素的个数(指针指向一个元素的前面),不是字节。比如一个数组的下标5元素的指针-此数组下标0元素的指针=5,此处不是6的原因就是因为指针是指向一个元素的前面。

        注:我们可以用下标为6的元素指针-下标为0的元素指针,但是最好别用下标为5的元素指针-下标为-1元素指针。

        3.指针的关系运算:指针之间是可以进行相互比较的,比如在一个数组中,下标为5元素的指针就大于下标为0元素的指针。

        注:如果我们想用指针的关系运算把这个数组的数全都改为0(此数组一共有6个元素),那么就会涉及到指针的“越界”。我们在指针-指针的时候就已经发现了,一个数组的下标为5元素的指针-此数组下标0元素的指针=5,但是0~5是6个元素,我们要注意,指针是指向一个元素的前面,那么就意味着我们把下标为5的元素给落下了。

        那么也就是说,如果我们想运用指针的关系运算把这个数组的数全都改为0,就要使用第“7”个元素的指针来减去第1个元素的指针。但是这个数组一共只有6个元素,那么就造成了指针的“越界访问”,但是这种情况我们可以忽略不计。

四、指针和数组

数组:一组相同类型元素的集合                                                                                                        指针变量:是一个变量,存放的是地址

其他内容在解引用中。

五、二级指针

       在开头我们提到了int* p = &a ; 的含义。在此基础上,我们可以写出这样的代码int** ppa = &pa那么按照我们一开始的理解,也就不难得出第二个*代表着ppa是一个指针,int*代表ppa指针所指向对象的类型,而ppa中存放着pa的地址,这就是二级指针。

        此时我们就可以得出结论:二级指针是用来存放一级指针变量的地址的。

        二级指针的解引用:我们就以a为例,*ppa是对ppa进行解引用,就可以找到pa,如果我们要找到a,那我们就需要再次解引用,也就是**ppa,此时我们就可以找到a。

六、指针数组

        所谓指针数组就是存放指针的数组,例如int* parr[ 3 ]={arr1 , arr2 , arr3};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值