AI大模型教程
一起来学习

指针讲解(1) 细致版

目录

1. 指针变量    

基本用法

指针变量大小与类型

2.void*指针

3.const修饰指针变量

4.指针运算

(1)指针+-整数

   (2)指针-指针

(3)指针的关系运算

5.野指针

6.assert断言

7.传值调用和传址调用


1. 指针变量    

基本用法

 对于我们定义好的,int a=0当中,向内存申请空间来存放a,而这a所在的空间就为一个地址,再用取地址符号&就能得到a的地址。

   由于这个地址,我们会在后续调用到,所以也得先存放,而用什么来存放这个地址呢?这个时候引入了指针变量。

由上面程序调试可知,p确实存放了a的地址。那我们就先来仔细解读这个指针变量。

星号*表明了p是指针变量,而int表明p指向的对象是一个整形数据类型a=0。既然是指针,不仅可以指向所在位置(地址),也可以找到位置里面具体存放的内容。   

*在这里是解引用操作符,通过p存放的地址找到具体的内容/值。当然,这里都能找到改值,也能通过这个指针改变原来存放的内容。如下  

将指针变量p解引用之后得到a=0,而这里直接*p=3,更改了原来a的值,所以打印出来的值从0变为了3。

指针变量大小与类型

指针变量的一些基本用法到这,而有关指针变量的大小直接用一张图说下大致情况。

指针变量的大小只与所在平台有关,与数据类型int还是char无关,直观点说就是无论int*p还是char*p,这个指针变量p都只申请了4个字节或者8个字节的空间大小。但是值得注意的一点是,反过来对p进行解引用操作的时候,就跟数据类型有关了,意思就是在32位平台下,若int*p=0,那么*p解引用出来能访问4个字节的空间,若char*p=0,则是1个字节空间。在这些指针运算即p+/-1的时候,指针移动的跨度不一样。也就是说,指针类型决定了指针走一步的距离有多远。

2.void*指针

接下来了解一下void*指针,这个指针可以用来接收任何数据类型的地址,但是不能进行+-整数运算操作,不能解引用。这个指针一般用在函数参数部分。具体用法后面章节再提。

3.const修饰指针变量

讲具体部分之前,先温习一下const修饰变量这一内容。

这里我的编译器是运行不了,大家可以自行尝试打印。

当然在这里,这个const也并不是真的完全限制的更改c的这个途径,我们可以绕过c,对c的地址进行修改,依旧可以实现c=10。如下

若要将const修饰后不被修改这个功能做到严谨的话,我们就得对指针进行const修饰。

const修饰指针变量可以放在*左边也可以放在*的右边,但作用不一样。

通过以上两种测试,我们可以简单总结为:

接下来来谈谈指针运算。

4.指针运算

指针运算大致分为三种:

指针+-整数、指针-指针、指针的关系运算。

(1)指针+-整数

   (2)指针-指针

(3)指针的关系运算

5.野指针

(1)概念:是指指针指向的位置是不可知的。

(2)成因:指针未初始化、指针越界访问、指针指向的空间释放。

指针未初始化:就比如,常规的话是int*p=arr;但是未初始化就是int*p;后面没有等于,这时候系统默认为指针指向随机值。

指针越界访问:比如,一个数组arr【5】,但是指针访问的时候用到了*P【6】,这个时候就说指针越界访问了。

指针指向的空间释放:

而如何避免出现野指针这种情况呢?

(1)将指针初始化。如果说暂时不知道指针改指哪里,可以指向NULL,如int *p=NULL。

(2)当已经知道指针非要往下走但是已经会越界的时候,我们也可也将该指针置为NULL。(p=NULL),在下次使用的时候,先将p重新指向一个地址,再判断不为NULL。(先p=&…;再if(p!=NULL)……)

(3)避免出现返回局部变量的地址。

6.assert断言

assert.h头文件定义了宏assert(),用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行。这个宏常常被称为“断言”。

assret()接收一个表达式作为参数,如果该表达式为真,程序继续运行;如果为假,assert()就会报错。

好处:能自动标识文件和出现问题的行号,如果确认程序无误,不需要断言,直接在#include语句的前面,定义一个宏NDEBUG(#define NDEBUG),这样的话,程序再次运行就会禁用掉所有的assert()语句。如果又需要断言就直接注释掉#define NDEBUG。

7.传值调用和传址调用

传值调用就先说一个点,实参传递给形参的时候,形参会单独创建一份临时空间来接受实参,对形参的修改不影响实参。

而传址调用,可以让函数与主函数之间建立真正联系,在函数内部可以修改主调函数中的变量。

假设有一个交换两个数值的函数swap,

在传值调用中,传过去是swap(a,b),接收是swap(int a,int b);在该函数内修改的值不会影响main函数里面a,b的值。

在传址调用中,传过去是swap(&a,&b),接收是swap(int*a,int*b)。在该函数内修改的值可以直接影响main函数里面a,b的值。

            

文章来源于互联网:指针讲解(1) 细致版

相关推荐: 探索文心一言在AI人工智能领域的智能教育应用

探索文心一言在AI人工智能领域的智能教育应用 关键词:文心一言、AI人工智能、智能教育应用、教育创新、个性化学习 摘要:本文聚焦于探索文心一言在AI人工智能领域的智能教育应用。首先介绍了研究的背景、目的、预期读者和文档结构等内容。接着阐述了文心一言及智能教育的…

赞(0)
未经允许不得转载:5bei.cn大模型教程网 » 指针讲解(1) 细致版
分享到: 更多 (0)

AI大模型,我们的未来

小欢软考联系我们