动态内存的另一个常见用途是让函数申请并返回一个指向内存块的指针。掌握这个技巧很重要,尤其是在你打算使用由别人编写的库文件时。
如果不知道这个技巧,就只能让函数返回一个简单的标量值,如整型、浮点型或字符型。换句话说,它既不能返回一个以上的值,也不能返回数组之类比较复杂的数据结构。
可以这样说,只要你想让函数返回的东西不是一个简单的值,就需要学习本讲内容。
这个技巧的基本思路并不复杂:
在函数里调用new语句为某种对象或某种基本数据类型分配一块内存,再把那块内存的地址返回给程序的主代码,主代码将使用那块内存并在完成相关操作后即可释放。
例子:
#include <iostream>
int *newInt(int value);
int main()
{
int *x = newInt(20);
std::cout << *x;
delete x;
x = NULL;
return 0;
}
int *newInt(int value)
{
int *myInt = new int;
*myInt = value;
return myInt;
}
这里讲了一个新的注释的方法,就是用宏指令#if 0 和#endif
这是绕开变量作用域的一种手段,在某些场合是必要的。
注意:任何一个函数都不应该把它自己的局部变量的指针作为它的返回值!因为局部变量在栈里,函数结束会自动释放。
如果你想让一个函数在不留下任何隐患的情况下返回一个指针,那它只能是一个动态分配的内存块的基地址,因为动态分配的是在堆里的,只有delete语句才能释放。
函数指针
指向函数首地址的指针称为函数指针,例子
#include <iostream>
int fun(int x, int y);
int main()
{
int i, a, b;
int(*p)(int x, int y); //声明函数指针
std::cin >> a;
p = fun; //给函数指针p赋值,使它指向函数fun
std::cout << "请输入10个数字:" << std::endl;
for (i = 0; i < 10; i++)
{
std::cin >> b;
a = (*p)(a, b); //通过指针p调用函数fun
}
std::cout << "最大的数字是:" << a << std::endl;
return 0;
}
int fun(int x, int y)
{
int z;
z = (x > y) ? x : y;
return(z);
}
注意,视频里有一点有问题,就是那个int(*p)(int x, int y),他后面直接是写了一个空括号,不行,要和上面那个int fun(int x, int y)格式一样才行。
指针函数
一个函数可以带回一个整型数据的值,字符类型值和实型类型的值,还可以带回指针类型的数据,使其指向某个地址单元。其实也就是上面第一个函数的例子
最重要的区别
指针函数是int *newInt(int value),函数指针是int(*p)(int x, int y),就是看那个有没有括号,要是有括号的话就是一个指针了,就不是函数了。