×

指针

一直没明单片机C语言的指针这块内容,在什么情况下会用到指针呢?C语言学到指针了,我经常把数组指针和指针数组弄混,它俩究竟有何区别该如何理解

jnlyseo998998 jnlyseo998998 发表于2022-11-11 08:14:16 浏览74 评论0

抢沙发发表评论

本文目录

一直没明单片机C语言的指针这块内容,在什么情况下会用到指针呢

作为一名长期使用C语言进行开发的老司机,我来回答一下C语言指针的问题。

首先、C语言指针的本质是什么?

C语言指针的本质是内存变量,是内存单元的编号。内存单元是以字节为单位的。所以指针就是字节的编号。如下图所示,一个4G内存的编号,指针的值其实就是内存编号。

其次、搞清楚变量和指针的关系

变量对应的是具体的内存,变量的内容就是内存中保存的数据。

比如,我们定义一个变量uint8_t a=10,假如a的位置是0,也就是上图中0位置的内存中保存的数据是10;

我们再来看指针,定义指针uint8_t * b=&a,我们知道&的含义是取地址,那么根据上面的假设变量a位于地址0,那么&a也就是0,此时指针变量b的值也就是0.

如果不好理解指针定义uint8_t * b=&a,我们可以变通一下:

(uint8_t *) b =&a,把(uint8_t *) 当做一个新的数据类型就好理解了,其实我们实际的编程中,也通常会这么定义:typeof uint8_t * uint8_p

uint8_p b=&a

这样 b就更像是一个变量了,理解起来更容易了。

第三、指针单元和内存

指针每个单元代表多少个内存呢?这要看指针的类型

比如,char * a,short int * b,int *c,long int * d等

指针所指的每份内存数量为1个字节,2个字节,4个字节,8个字节,也就是每个变量类型所占的内存单元。

假设a、b、c、d四个指针变量值均为100,分别做自加运算后,指针的值是多少呢?

a++;

b++;

c++;

d++;

你能猜出,a、b、c、d的值分别是多少吗?

答案是:101,102,104,108.

也就是每次指针移动一个变量类型对应的内存数,这个可以在keil 开发环境上面通过模拟环境验证,有兴趣的可以自行验证一下。

最后、指针的优势和应用场景

优势:

1.效率高;2、灵活,可以访问任意位置的内存数据;3、作为函数参数传递,只需要传递4个字节,比数组传值节省内存拷贝时间。

应用场景:

1.函数中交换两个变量的值

在学习函数时,交换两个数的值,做一个swap函数,传递值进去,也可以将两个值交换过来,没问题,可是离开swap就没有用了,为什么?因为传进去的是两个值。如果传递的是指针就没有问题。因为指针传递过去的是两个变量的地址,变量的位置不变。

2.函数通过指针返回多个值

3.函数返回运算的状态,结果通过指针返回

…………

指针的弊端

指针是C语言的灵魂所在,通常说C语言是“低级”语言的原因,很大程度上也是因为C语言指针的问题,C语言指针让开发者可以访问任意内存位置的数据。这是其他语音没有办法达到的。也正因为指针,C语言也很容易出错,最常见的问题是地址越界,如果地址越界,读写了不该读写的内容会直接导致系统崩溃,而且这种问题很难定位,因为语法上是没有错误的,编译的时候无法检查出来。

对于C语言指针的问题,大家有什么意见,欢迎留言讨论。

C语言学到指针了,我经常把数组指针和指针数组弄混,它俩究竟有何区别该如何理解

谢谢邀请。

很多C语言初学者在学到指针时,都会遇到“数组指针”和“指针数组”这两个名词,然后就一脸懵逼了,其实在考虑C语言中的数组指针和指针数组时,只需多加几个字,一切就清晰许多了:


数组指针 -》 数组类型的指针,所以数组指针是一个指针。

指针数组 -》 指针类型的数组,所以指针数组其实是一个数组。


指向数组的指针

在讨论数组指针之前,先来看一段C语言代码,如下:

C语言中的指针不仅有加法运算,还有减法运算,不过乘除运算就是非法的了。编译并执行上述C语言代码,可以得到如下输出:

其实,访问指针 p 指向的数值,除了“* ”运算符外,也可以以数组的形式,本例中 p 和 *(p+N) 是等价的:

相信有读者已经注意到 p 了,这似乎与C语言数组下标不能为负的语法相悖,那为何这里能够编译通过,并正常运行呢?鉴于该问题与主题无关,这里不再赘述,感兴趣的读者可翻阅我之前的文章。

数组指针

如果题主觉得上面的C语言代码示例没有难度,其实你已经会用数组指针了。在上面的例子中,p 就是一个数组指针。p 是一个 char* 型的指针,它指向数组,所以叫“数组指针”。

数组指针就是指向数组的指针,就像 int 型指针就是执行 int 型变量的指针一样。

数组指针就这么简单。其实,记住数组指针就是指向数组的指针这句话后,再复杂点的情况也能轻松应对。请看下面的例子,我们先用C语言定义一个二维数组,用来存三个人名:

name 中的 3 表示 name 数组一共有 3 行,6 表示每行最多有 6 个 char 型数据。现在,我想用数组指针指向这三个人名,可以如下定义:

() 优先级高,说明 p2 首先是个指针,什么类型呢?括号里的内容看过了,现在忽略它,那显然,p2 是一个指向 char 型的数据,所以可以直接把 name 赋值给 p2:

p2 = name;

如果题主看过我之前的文章,应该知道指针的加法运算结果受指针的类型影响,那如果 p2 指向的地址为 0, p2 (即p2+1) 指向的地址为多少呢?

答案是 6,因为 p2 是一个 char 恰好指向的是 name 的每一行,因此数组指针又被称作“行指针”。 如果执行以下C

语言代码:

实际上就是把 name 记录的三个人名打印出来。以数组的形式访问也是一样的:

编译并执行,得到如下输出:

指针数组

讨论完了数组指针,再来看看指针数组。其实,指针数组就是一个数组,只不过这个数组里存放的都是指针而已。就跟我们说int数组是一个存放 int 的数组一样。在C语言中指针数组的定义也很简单:

char *p3;

的优先级高于 * ,说明 p3 首先是个数组,什么类型的数组呢?char* 型的,char* 表示一个指针类型,所以 p3 就是一个指针数组

如果使用指针数组指向 name,就不能直接把 name 赋值给 p3 了,因为类型不同。但是,p3 里存放的都是 char* 型的指针,即 p3,请看如下C语言代码:

编译并执行,可以得到如下输出:

与预期一致。这样,我们就使用了C语言中的指针数组访问了 name 数组。

小结

到这里,C语言中的数组指针和指针数组两者的区别就豁然开朗了,数组指针是一个指针变量,它占有内存中一个指针的存储空间。指针数组是多个指针变量,也即数组,以数组形式存在内存当中,占有多个指针的存储空间。

欢迎在评论区一起讨论,质疑。文章都是手打原创,每天最浅显的介绍C语言、linux等嵌入式开发,喜欢我的文章就关注一波吧,可以看到最新更新和之前的文章哦。

C语言中的函数指针和指针函数,有什么区别吗该如何理解

函数指针和指针函数的区别:

1. 名字解析。这两个名词都是带有修饰的名词,可以略微扩展一下,在中间加个助词’的’,函数的指针和指针的函数;现在看看,稍微清晰了一点,现在再扩展一下,加点修饰词--指向函数的指针和返回值为指针的函数;现在基本明确了。

2. 格式。

Type (* pFunc)(Type para); -- 函数指针

Type* Func(Type para); -- 指针函数

3. 先说指针函数,其实它就是普通函数,只不过返回值是指针(其实就是地址)而已,很多人因为恐惧指针,觉得它神秘!

4. 函数指针。这个有点复杂,首先*和pFunc先结合,优先级最高,因此pFunc就是指针了,同时这个指针后面带走一对小括号,里面还有参数,和函数的参数是一样的格式,因此这个指针就是函数指针,这个指针前面还有个类型-返回值类型!有人这里感觉很奇怪,指针怎么有返回值呢?

5. 指针有返回值,是因为这个指针讲来使用的时候,会指向一个格式和它自己类似的函数,因此这个指针的返回值和参数格式就决定了指向的函数的格式!

6. 函数指针要熟练,没有为啥,必须会,因为函数指针使用的时候体现的是C语言中的联编特点,也是后来C++语言中多态的雏形!

lol为什么感觉高手都用旧版指针

对于玩了八九年的老玩家来说,英雄联盟的旧版指针是无可代替的。

其实有很多高分玩家也用新版指针,但大多岁数比较小,十几岁的那种。

其实这个并不能说全部,但大部分玩家还是喜欢旧版指针,也有部分玩家感觉新版指针还不错,还有一部分玩家不在乎这些东西,系统更新给什么就用什么。

像是我,我就坚持旧版指针,新版的用着比较别扭。以前盒子还有缩小指针,那时候喜欢用稍微小一点的,不过现在客户端内置了缩小功能,整体来说非常人性化。


关于英雄联盟鼠标指针

新版的指针在18年上线,当时拳头还专门发文感叹,一代新老更替。

在19年,拳头设计表示打算在9.15版本将旧版指针彻底删除。但消息放出后遭到全球玩家的抵制,各个服务器的玩家都一致抗议,最后设计总监迫于压力表示保留旧版指针。


其实很多游戏老玩家都有类似的“执念”,喜欢旧的东西。

学习c语言的时候指针应该怎么理解

简单的说,指针就是一个代表地址的无符号整数。

通常我们使用指针,是为了读取或改变指针指向的数据。

所以,单独理解指针是不够的。还得了解指针指向的数据空间是如何安排的。这有可能会涉及到与具体CPU/OS相关的一些知识。如果能结合计算机体系结构知识一起理解会更深入、更准确。

比如:

  • 各种整数(signed/unsigned long/int/short)是如何存放的?

  • 各种浮点数(float/double/long double)是如何存放的?

  • 数组在数据空间中是如何组织的?

  • 字符串是如何存放的?

  • 结构(struct)和联合(union)是如何存放的?

  • 位域(bit field)的组织

这其中和具体CPU相关的部分通常有:

  • 结构(struct)和联合(union)的对齐,通常会以CPU字长对齐

  • 整数的存放,会涉及CPU大小端的规定

  • 浮点数的存放,和FPU的设计直接相关

再进一步,还有一些扩展知识,涉及内存的分配和释放:

  • 程序中如何分配内存?(malloc/free)

  • 堆(heap)和栈(stack)各是什么?

这些又和CPU/OS相关。

小结一下:指针就是地址,也是一个整数。但要用好它,需要了解计算机存储空间的分配规律,难点在这里,突破点也在这里。

堆栈指针sp为什么只能指向偶地址

不强求,但是这样可以最大程度提高速度。 涉及到8086CPU的构成,它的存储分奇地址存储器和偶地址存储器,分别用BHE反,和A0接两个存储器的片选端(都是低电平有效)。 我几句话,没有图的话很难说清楚。反正由于这个构成,造成8086最顺畅的访问是以偶地址为低字节,以奇地址为高字节的一个字内容的访问,而8086堆栈规定了每次堆栈都是字操作,因此,你这样做可以保证快速的堆栈进出速度,(否则,SP指向奇地址的话,一个字的操作需要访问两次存储器,具体看第二章,Cpu结构的那章)