C语言: 指针的进阶

目录

指针的进阶

前言

1. 字符指针

2. 数组指针

3. 指针数组

4. 数组传参和指针传参

5. 函数指针

6. 函数指针数组

7. 指向函数指针数组的指针

8. 回调函数



指针的进阶

前言

上文简易指针中我们介绍了一些常见的简单指针的用法

链接:简单指针

这期,咱们来学习进阶版的指针用法。

1. 字符指针

 其中*p指向的并不是把 “abcdef” 放到了指针p中,而是将首字符的地址放到了指针p中。这是很多人常犯的错误。

正是因为这个性质,在打印单个字符的时候,指针需要解引用,而用 %s 打印整个字符串的时候,只需要传首元素地址即可,而指针刚好指向的是首元素地址。

曾经的一道面试例题:

 答案是:......not same        .......same

原因:前面两个字符数组,是把其中的字符放入到了str1、str2中,这两个地址是不同的。所以他们不同。而指针str3、指针str4则是指向同一块内存中存放的字符串,所以他们是相同的。

 

2. 数组指针

顾名思义,这是一种指针,并且是一种可以指向数组的指针。

那么他是哪种形式的呢?我们知道

int* arr[10];

由于 [ ] 的的优先级比 * 的要高,所以,数组名是优先和 [ ] 结合的,这样就是指针数组了。

因此,我们应该确保 * 和数组名优先结合,形式如下:

int (*arr)[10];

&数组名和数组名的区别

我们知道数组名代表的是数组首元素的地址,那么&数组名代表了什么呢?我们看这段代码:

#include <stdio.h>
int main()
{
    int arr[10] = {0};
    printf("%p\n", arr);
    printf("%p\n", &arr);
    return 0;
}

运行结果如下:

可以看到结果是一样的,但是真的一样吗?

#include <stdio.h>
int main()
{
 int arr[10] = { 0 };
 printf("arr = %p\n", arr);
 printf("&arr= %p\n", &arr);
 printf("arr+1 = %p\n", arr+1);
 printf("&arr+1= %p\n", &arr+1);
 return 0;
}

这段代码的结果就很明显

 实际上:&数组名代表的是整个数组的地址,当数组的地址+1的时候,跳过的是整个数组的大小。所以差值是40了

数组指针应用于二维数组的实例

3. 指针数组

前文我们已经讲过,指针数组是一个存放指针的数组。

 

4. 数组传参和指针传参

在写代码的时候难免要把【数组】或者【指针】传给函数,那函数的参数该如何设计呢?
看看以下例题分析: 
一维数组:

 当传入的是数组名的时候,函数参数无论是数组、指针、还是指针 [ ] 都是可以的

当传入的是指针数组的数组名,那么这时候就要用到二级指针了,指向指针的地址了。

二维数组:

 在用二维数组传参的时候,和之前初始化的时候一样,列数是一定要给的,不然就是错误的。

而 int *arr [ ] 错误的原因是这是一个指针数组,里面的元素都是指针,所以肯定是错误的。

int *arr 错误是因为二维数组的首元素是一个行,用一个指针来是接收不了一行的内容的。 

用二级指针接收肯定也是,错误的,因为传来的是元素的地址,而元素是整形。

   

5. 函数指针

函数指针是用来存放函数的地址的一种指针。

形式为:返回值类型+(*数组名)(函数参数类型)

void (*pf)(int , int);

为什么要用()让*和函数名优先结合呢?原理是和数组指针相同的,因为()的优先级更高,会优先和参数结合,这样就变成函数了。

其中参数的名字写不写无所谓的。

 

 

 在使用的时候,这个*是可有可无的,图中划横线的两行效果一样。甚至你可以用******都是可以的。 

 

6. 函数指针数组

 一个数组中存放的全是函数指针,那么这个数组就是函数指针数组。

 上面代码可以看出。

为什么要把 [ ] 放在括号里面呢?因为他的性质是一个数组,所以名字是要和 [ ] 先结合的。

 

7. 指向函数指针数组的指针

最下面这一行就是指向函数指针数组的指针。

怎么理解这一行呢?我们先拆解他

他首先是一个(*ppfarr),那么他的性质是一个指针,然后外面是 [ ] 其次他的性质是一个数组,然后再和外面的*结合,那么我们可以理解为,这是一个指针,指向一个数组,数组里面存放的是函数的指针。

  

8. 回调函数

回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一
个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该
函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或
条件进行响应。
其中这里的 int_cmp 函数就是回调函数,下面的的qsort函数通过使用它的函数指针来调用它。
 
 感谢观看!

  • 14
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值