//9 – 7 – 1 pointer parameter passing
//指传参 函数的址传递
#include <iostream>
using namespace std;
//函数的值传递 value transport in function
void swap(int a, int b) {
cout << “函数的值传递:” << endl;
cout << “the address of a after calling the function” << &a << endl;
cout << “the address of b after calling the function” << &b << endl;
int temp = a;
a = b;
b = temp;
}
//函数的址传递 address transport in function
void swap(int *a, int *b) {
cout << “函数的址传递:” << endl;
cout << “the address of a after calling the function” << a << endl; //if we add & before a, we will get a pointer’s address
cout << “the address of b after calling the function” << b << endl;
cout << “————” << endl;
int temp = *a;
cout << “the value of a after calling the function= ” << *a << endl; //if we add & before a, we will get a pointer’s address
cout << “the value of b after calling the function= ” << *b << endl;
cout << “the value of temp after calling the function= ” << temp << endl;
cout << “————” << endl;
*a = *b;
cout << “the value of a after calling the function= ” << *a << endl; //if we add & before a, we will get a pointer’s address
cout << “the value of b after calling the function= ” << *b << endl;
cout << “the value of temp after calling the function= ” << temp << endl;
cout << “————” << endl;
*b = temp;//temp is a temporarily variable, which will be destroied after the calling over
cout << “the value of a after calling the function= ” << *a << endl; //if we add & before a, we will get a pointer’s address
cout << “the value of b after calling the function= ” << *b << endl;
cout << “the value of temp after calling the function= ” << temp << endl;
}
int main() {
int a = 1;
int b = 2;
cout << “the address of a before calling the function” << &a << endl;
cout << “the address of b before calling the function” << &b << endl;
cout << “————” << endl;
swap(a, b);
cout << “————” << endl;
swap(&a, &b);//函数重载
cout << “————” << endl;
cout << “a = ” << a << endl;
cout << “b = ” << b << endl;
cout << “————” << endl;
return 0;
}
//9 – 7 – 2 pointer function
//指针函数
#include <iostream>
using namespace std;
int* func() {
return NULL;
}
int* getArray(int a, int d, int n) {
//function is getArray, return value is an int pointer, the pointer is actually an address
int* ret = new int[n];//apply a new dynamic RAM space
//use the array as the type of first address
/*
ret [0]=a;
ret [1]=a + d;
…
ret [i]=a + i*d ;
*/
for (int i = 0; i < n; ++i) {
ret[i] = a + i * d;
}
return ret;//return the array’s first address
}
int main() {
int* ans = getArray(5, 3, 6);//首项 5,公差3,6个元素
for (int i = 0; i < 6; ++i) {
cout << *(ans+i) << endl; //指针偏移 pointer shift and getting the value in the array
}
for (int i = 0; i < 6; ++i) {
cout << ans[i] << endl; //pointer better not used like this
}
return 0;
}
//9 – 7 – 3 function pointer
//函数指针
//遇到这种概念,先看最后两个字 指针
#include <iostream>
using namespace std;
double (*ptr)(int a, int b, int c);
void (*ptr1)(int a, int b);
double func(int a, int b, int c) {
cout << a << “,” << b << “,” << c << endl;
return 0.0;
}
void func1(int a, int b) {
cout << a << “,” << b << endl;
}
int main() {
ptr = func;
ptr(4, 5, 6);
//ptr = func1; //error
//函数指针赋值时 参数要匹配, 返回值也要匹配
ptr1 = func1;
ptr1(5, 6);
return 0;
}
AI:
好问题~这个是 C 语言学习里一个经典又容易混淆的点 👍
在我们开始解释前,我想先确认一下:你现在大概对「指针」和「函数」本身都已经了解了吗?比如知道什么是指针变量、会写普通函数?
(我问这个是为了决定要从多基础讲起,还是直接讲语法和区别。)
先简单预告一下区别:
名称 意思 举例 重点
指针函数 返回值是“指针”的函数 int *func(); “函数→返回一个指针”
函数指针 指向函数的“指针变量” int (*pfunc)(); “指针→指向一个函数”
但要真正理解这两个,最好先从语法结构和用法一点点推。
所以我想先确认你:
👉 你希望我从「指针函数」和「函数指针」的语法差异讲起,还是从它们在内存和调用上的区别讲起?
太好啦 ❤️~那我们就专注讲语法差异!
⸻
🧩 一、指针函数(Function returning pointer)
定义:
函数的返回值是一个指针。
语法结构:
类型 *函数名(参数列表);
例子:
int *getNum() {
static int a = 10;
return &a;
}
📘解释:
• 这是一个函数 getNum();
• 它返回 int*(指向整型的指针);
• 所以叫“指针函数”。
📌 小技巧:
把“*”看作修饰返回值类型的标志。
int *f(); // f 是函数,返回 int*
⸻
🧠 二、函数指针(Pointer to function)
定义:
一个指针变量,用来指向一个函数的入口地址。
语法结构:
返回类型 (*指针名)(参数列表);
例子:
int add(int a, int b) {
return a + b;
}
int (*p)(int, int); // 定义一个函数指针
p = add; // 让指针指向函数
int result = p(3, 5);
📘解释:
• p 是一个指针;
• (*p)(int, int) 表示 p 指向一个参数为 (int,int)、返回值为 int 的函数;
• 调用时 p(3,5) 和 add(3,5) 一样。
📌 小技巧:
括号里有 * 的一般是“函数指针”;
括号外面有 * 的一般是“指针函数”。
⸻
🔍 三、对比记忆口诀
区别 指针函数 函数指针
本质 函数 指针变量
定义 返回一个指针的函数 指向函数的指针
写法 int *f(); int (*f)();
括号位置 * 在函数名右边 * 在函数名外层括号里
调用方式 直接 f() 可通过指针 pf() 调用
⸻
如果你想更牢一点记忆这个,我可以帮你出几道“判断写法属于哪一种”的练习题(比如让你区分 int *f(int); 和 int (*f)(int);),要不要我帮你做几道练习题? ❤️
太棒啦~(๑>◡<๑)💕
那我们来玩个小小的练习游戏:我先出题,你先判断它是「指针函数」还是「函数指针」,然后我帮你讲解理由~
⸻
🌟 题目 1
int *fun1();
👉 你觉得它是 指针函数 还是 函数指针?
⸻
🌟 题目 2
int (*fun2)();
👉 它是 指针函数 还是 函数指针?
⸻
🌟 题目 3
char *getName(int id);
👉 这个是 指针函数 还是 函数指针?
⸻
🌟 题目 4
void (*signal(int, void (*)(int)))(int);
👉 这个比较难,它是 指针函数 还是 函数指针?
⸻
先试着回答前 3 题(第 4 题我等你答完后再一起拆开讲 👀)
你来试试看~
哇~👏👏全都答对啦!你太棒啦~✨✨
(第 4 题也答对真的厉害,这题很多大学期末都能考倒人呢 🧠)
下面我给你逐题解释一下,让你彻底吃透它们的语法结构👇
⸻
🩵 题目 1:
int *fun1();
✅ 指针函数
📖 解释:
• fun1 是一个函数;
• 函数返回 int*(指向 int 的指针)。
👉 所以是“函数 → 返回一个指针”。
⸻
💜 题目 2:
int (*fun2)();
✅ 函数指针
📖 解释:
• fun2 是一个指针(*fun2);
• 这个指针指向的对象是一个函数(() 表明它是函数);
• 这个函数的返回类型是 int。
👉 所以是“指针 → 指向函数”。
⸻
💚 题目 3:
char *getName(int id);
✅ 指针函数
📖 解释:
• getName 是一个函数;
• 参数是 (int id);
• 返回值是 char*(字符串指针)。
👉 这是典型的指针函数。
⸻
❤️ 题目 4:
void (*signal(int, void (*)(int)))(int);
✅ 函数指针
📖 拆解:
• 外层结构是 signal(…),所以它是一个函数;
• 但这个函数返回的类型是:void (*)(int);
→ 意思是:返回一个“指向 void f(int) 函数”的指针。
👉 所以这是一个 返回函数指针的函数(函数指针函数 😂)。
可以理解成:
typedef void (*handler)(int);
handler signal(int, handler);
是不是立刻清晰多啦~✨
⸻
要不要我帮你出第二组题,这次难度稍微提升一点(带参数和 typedef 的混合写法)?
可以用来训练你一眼识别语法结构的感觉~
//9 – 7 – 4 Function pointer type definition
//函数指针类型定义
#include <iostream>
using namespace std;
//the definition of definiting the function pointer
//函数指针的定义
void (*fptr1) (int a, int b, int c, float d, char e);
void (*fptr2) (int a, int b, int c, float d, char e);
//如果我还想定义一个函数指针,那就改一下名字
void func1(int a, int b, int c, float d, char e) {
cout << “func1” << endl;
}
//函数指针类型定义
// 这样子不用重复写新的函数指针
//Function pointer type definition
typedef void (*fptr) (int a, int b, int c, float d, char e);
//一旦有颜色说明是一种类型
int main() {
fptr1 = func1;
fptr1(1, 2, 3, 4, 5);
fptr2 = func1;
fptr2(9,8,7,6,5);
fptr fp1 = func1;
//通过这个类型定义一个变量 然后初始化 把func1 赋值过去
//跟int x =6;格式类似
fp1(5, 6, 7, 8, 9);
return 0;
}
//9 – 7 – 5 array of function pointer
//函数指针数组
//实际上是一个数组,数组中每一个元素都是函数指针
//[函数指针1,函数指针2,……,]
//定义函数指针类型
//typedef void (*fptr) (int a, int b, double c, float d, char e);
//加上[] 立马变 函数指针数组类型
//定义函数指针数组方式1:[]中括号写定义里
typedef void (*fptrs[50]) (int a, int b, double c, float d, char e);
//typedef void (*fptrs[]) (int a, int b, double c, float d, char e);
//定义函数指针数组方2:[]中括号不写定义里,在后面使用时才写
typedef void (*fptr) (int a, int b, double c, float d, char e);
#include <iostream>
using namespace std;
void func1(int a, int b, double c, float d, char e) {
cout << “func1” << endl;
}
void func2(int a, int b, double c, float d, char e) {
cout << “func2” << endl;
}
void func3(int a, int b, double c, float d, char e) {
cout << “func3” << endl;
}
int main() {
//很像int a[] = {1,2,3};
fptrs fps = {func1,func2,func3};
//{func1,func2,func3,…,NULL}后面的都是NULL
cout << fps[0] << endl;
cout << fps[1] << endl;
cout << fps[2] << endl;
cout << fps[3] << endl;
fptr fp[] = { func1,func2,func3 };
//没报错就可以
cout << fp[0] << endl;
cout << fp[1] << endl;
cout << fp[2] << endl;
return 0;
}