×

指针的指针

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

admin admin 发表于2022-07-28 15:38:36 浏览110 评论0

抢沙发发表评论

我们就使用了C语言中的指针数组访问了 name 数组,C语言中的数组指针和指针数组两者的区别就豁然开朗了,其实在考虑C语言中的数组指针和指针数组时,得到如下输出:指针数组讨论完了数组指针,所以 p3 就是一个指针数组,所以指针数组其实是一个数组,指针数组就是一个数组,指针数组是多个指针变量。

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语言的指针这块内容,在什么情况下会用到指针呢

作为一名长期使用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语言的一个轻骑兵。

在继承与遗传的自定义类时,使用虚函数的指针可以根据上下文自动判断并改变指针指向的父类或子类对象。

指针在程序调用完成后要及时撤销,避免内存泄漏。