c语言:基于函数指针的两个示例分析
需积分: 0 167 浏览量
更新于2020-09-05
收藏 53KB PDF 举报
在C语言中,函数指针是一种非常强大的工具,它可以让我们将函数作为参数传递给其他函数,或者存储在数据结构中以便稍后调用。本文将深入解析提供的代码示例,探讨函数指针的工作原理以及在GDB调试时观察到的现象。
来看第一个示例:
```c
#include <stdio.h>
#include <string.h>
void tell_me(int f(const char *, const char *));
int main(void);
void tell_me(int f(const char *, const char *));
int main(void) {
tell_me(strcmp);
tell_me(main);
return 0;
}
void tell_me(int f(const char *, const char *)) {
if (f == strcmp)
printf("Address of strcmp(): %p\n", f);
else
printf("Function address: %p\n", f);
}
```
在这个例子中,`tell_me` 函数接受一个函数指针 `f`,该指针期望接收两个 `const char *` 类型的参数并返回一个 `int`。在 `main` 函数中,我们传入了 `strcmp` 和 `main` 作为参数。`tell_me` 内部的条件语句 `if (f == strcmp)` 检查 `f` 是否等于 `strcmp` 的地址。
然而,在GDB中,当我们在 `if (f == strcmp)` 处设置断点并打印 `f` 和 `strcmp` 的值时,我们发现它们的地址不同。这是因为 `strcmp` 是一个全局函数,它的地址在程序加载时确定,并且在内存中的位置可能与代码段的其他部分不同。`f` 是在运行时赋值的,因此它指向 `strcmp` 或 `main` 的地址。
在GDB的输出中,我们看到 `f` 和 `*f` 都指向 `strcmp@plt`。`strcmp@plt` 是动态链接表(Procedure Linkage Table, PLT)的一部分,用于处理函数调用的延迟绑定。这意味着在实际调用 `strcmp` 之前,程序并不知道其确切地址,直到第一次调用时才会查找并解析。因此,即使 `f` 在 `if` 语句中被比较时看起来指向 `strcmp`,实际上在执行 `f == strcmp` 之前,它们的地址并不相同。
在汇编代码中,我们可以看到 `main` 和 `strcmp` 被当作常量处理,它们的地址在调用 `tell_me` 时被推入栈中。`tell_me` 的参数 `f` 实际上只是用来传递这些地址的引用,而不是像变量那样在内存中有单独的存储位置。这就是为什么在汇编代码中找不到 `f` 的直接对应物。
这段代码展示了如何使用函数指针进行条件判断,并揭示了动态链接在程序执行中的作用。尽管在GDB中 `f` 和 `strcmp` 的地址在比较时看似不一致,但通过PLT,它们在运行时能够正确识别和调用相应的函数。理解和掌握函数指针以及动态链接的概念对于深入理解C语言和底层程序设计至关重要。
weixin_38572979
- 粉丝: 4
- 资源: 932
最新资源
- ASME核电建造规范对焊接热影响区韧性降低的补偿要求.pdf
- 机械设计南方航空抛光机 sw14可编辑非常好的设计图纸100%好用.zip
- 数据分析-18-Video Game Sales电子游戏销售分析(包含数据代码)
- delphi 7 解决Indy获取网页内容,UTF8编码乱码问题
- 机械设计卧式离心鼓风机igs非常好的设计图纸100%好用.zip
- 机械设计运输机器人3D模型stp非常好的设计图纸100%好用.zip
- A-TIG焊在碳钢焊接中的应用.pdf
- AWS A5.16A5.16M-2007 钛及钛合金焊接电极和焊条规范.pdf
- 机械设计室外型不锈钢垃圾箱sw14可编辑非常好的设计图纸100%好用.zip
- AWS B2.1-1-003-2002 在焊接条件下、有或没有垫板、10到18规格的镀锌钢的气体保护金属极电弧焊.pdf
- AWS B1.11-2000 中文版 焊接目视检查工作手册.pdf
- AWS B2.1-1-004-2002 在焊接条件下、有或没有垫板、10到18规格的碳钢(M1,组1)的气体保护金属极电弧焊.pdf
- AWS B2.1-1-012-2002 标准焊接程序规范.在焊接条件下、有或没有垫板、10到18规格的碳钢(M1,组1)的保护金属焊条电弧焊.pdf
- AWS B2.1-1-201-96(R2007) 主要用于管道的、在焊接条件下、(M-1/P-1/S-1,1或2组)1/8到3/4英寸厚、E6010(垂直向上)及E7018(垂直向上)碳.pdf
- AWS B2.1-1-202-96(R2007) 主要用于管道的、在焊接条件下、(M-1/P-1/S-1,1或2组)1/8到3/4英寸厚、E6010(垂直向上)及E7018(垂直向上)碳钢.pdf
- AWS B2.1-1-206-96(R2007) 主要用于管道的、在焊接或PWHT条件下(M-1/P-1/S-1,1或2组)1/8到1-1/2英寸厚、E6010(垂直向上)及E7018(垂直.pdf