C语言--指针初阶

指针初阶顾名思义就是指针内容中相对较为简单的内容,下面我将自己对初阶指针的理解与大家分享。
目录:
1、内存.
2、指针概念.
3、指针类型及其意义.
4、野指针.
5、指针的运算.
6、指针和数组.

7、二级指针.

一、内存
1、内存是如何规划的?
内存的结构可以看作一个大的空间被划分成小矩形,每个矩形代表一个内存单元
(规定一个内存单元占一个字节)如图所示;
在这里插入图片描述

2、每一个内存单元是如何进行编号的?(地址是如何定义的?)
注:我们所使用的机器分为32位机器和64位机器,下面以32位机器为例;
正文:
(1)地址的产生原理:32位机器中有32根地址线(物理线),通电后产生电信号(正,负),在转化为数字信号分别对应1和0,由此产生一个32位的二进制数字序列,则此序列成为一个内存单元的编号,也就是地址;
(2)现在我们知道了地址是如何定义的,那么一共会产生多少个编号(地址)呢?
如图所示:
如图
由上可知每一个地址是由一个32位的二进制数字序列组成的,如图,若序列从32个0排到32个1,则共有2的32次方种情况,所以就对应2的32次方个地址,也就是可以管理2的32次方个内存单元。

二,指针的概念
介绍完内存,我们可以引出指针的概念;

在计算机科学中,指针是编程语言中的一个对象,利用地址,它的值直接指向存在电脑存储器中另一个地方的值。

其实说白了,指针就是地址
1,用法:

#include<stdio.h>
int mian()
{
    int a=10
    int *pa=&a;
    *pa=10;
    return 0;
}

如图所示,此串代码应该是最简单的指针的运用,此处包含四个重要的知识点;
1.// *说明pa为指针变量;
2.// int说明pa执行对象(a)为int型;
3.// &a表示a的地址,通过赋值运算符将a的地址存放到pa指针变量中;
4.// *pa为解引用操作本质上是通过pa中的地址找到其本体(即a);

此处还应注意的是:c语言规定int型变量初始化时占4个字节的内存(也就是四个内存单元),每个内存单元对应一个地址,但是&a并不是代表四个地址,而是a的首地址,所以指针变量pa中存放的也是a的首地址。
三、指针类型及其意义;
1,指针类型分为 int char double float等类型,
2,指针变量无论是int还是char类型大小都一样;

注:为什么会相等呢?这是因为指针是用来存放地址的,所以指针的大小只与要存放的地址大小有关。由前面内容可知,存放地址时无论是int类型或者数组都是存放首地址,所以一个指针不可能存放多个地址。而一个地址大小取决于二进制序列长短,例如64位机器产生的一个二进制序列由64个二进制数字组成,而一个二进制数字大小为1个bite,8个bite=1个字节,所以结果大小为8.
问题:既然大小都相等,规定指针类型还有什么意义呢?
意义a:指针类型决定了指针解引用的权限有多大
意义b:指针类型决定了指针走一步能走多远

如上图,char类型指针变量pp+1后地址向后走一位,而int类型向后走了4个地址
四,产生野指针的几种情况;
1、野指针定义

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)指针变量在定义时如果未初始化,其值是随机的,指针变量的值是别的变量的地址,意味着指针指向了一个地址是不确定的变量,此时去解引用就是去访问了一个不确定的地址,所以结果是不可知的。

2,野指针的几种情况
(1)指针未初始化;
在这里插入图片描述
*如图,这里的指针变量就是一个野指针,p=10//非法访问内存;

(2)指针越界访问;
在这里插入图片描述
如图,此处以数组为例,定义数组arr[10],下标最大为9,当i=10时此处地址不属于数组了,所以当访问a【10】时便为非法访问,此时pa为野指针;
(3)指针指向的空间被释放;

int* text()
{
   int a=10;
   return &a;
}
int main()
{
    int* p=text();
    * p=20;
    return0;
}

此处操作按正常逻辑是将一个指针传到函数中,函数返回a地址,然后*p解引用操作改变a值,但实际上此时p已经是野指针了,因为a用完便会还给操作系统,此时便不属于自己了,而指针变量还记住a的地址,此时p为野指针;

五、指针的运算;

指针的运算包括:指针加减整数,指针-指针,指针的关系运算
(1)指针加减整数:本质上就是根据指针变量的类型使地址前移或者后移(个人理解)
在这里插入图片描述
此处的代码理解:通过指针加整数的方法改变数组每个元素的数值,此处的pa+i其实是对应下标为i的元素的地址,在通过解引用进行赋值。

(2)指针减指针
在这里插入图片描述

如图可知,两个指针相减结果其实就是中间元素个数;

还需要注意的是,两个指针相加或相减的前提是指针类型相同,否则没有意义;

(3)指针的关系运算:

int arr[10]={0};
int* pa;
for(pa=&arr[0];pa<&arr[9];pa++;)
{
   *pa=0;
}

在此处的for语句中就用到了指针的关系运算(也用到了指针加减整数),数组地址由小到大排列,for语句中pa<&arr[9],pa++就相当于i=0,i<10,i++;

六、指针和数组.

此处较为重要的知识点为数组名就是数组首元素地址
定义一个arr数组:int arr[10]={0};
拿出一个数组元素:arr[5]
这里其实可以这样理解:
arr是首元素地址,[5]代表跳过五个整形来到第六个元素。

七、二级指针

1、定义:“二级指针A(即B的地址)是指向指针的指针,称为二级指针,用于存放二级指针的变量称为二级指针变量.

例:

int a=10int *pa=&a;
int* *ppa=&pa;

看到这,你肯定会有疑问,为什么会出现两个*操作符呢?下面列出了各个符号的意义:
(1)第一个int * :说明所执行对象pa类型为int *
(2)第二个 *:说明ppa为指针变量

2、二级指针的解引用;

*ppa指pa
**ppa指a
由此可知二级指针ppa可以连接到变量a

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值