指針函數與函數指針
對於沒有系統的學習過C++的同學來說,指針彷彿是一個難以逾越的鴻溝,但是其實指針沒那麼複雜,或者可以這麼說,
我們選擇性的忽略指針,比如說就把指針當做一個實例對象
例如 類Person
有兩種實例化方法
1. Person p; //在棧裏分配內存,作用域內有效,自動釋放
2. Person *p = new Person(); //在堆內分配內存,需要手動調用 delete p; 來釋放
其實在這裏,完全可以拋棄指針的概念,就認爲兩個都是對象,只是調用成員函數成員變量的方法不同,還有作用域不同就可以了。
之所以提到這些,就是引出今天要談的一個概念,那就是指針函數和函數指針的概念,這兩個概念,相信很多人都不明白。
今天我們就簡單探討一下。
1.指針函數
在C語言這種面向過程的語言中,整個程序都是通過函數調用來一步一步實現的,對於函數,相信大家都再熟悉不過了。
例如:
void func();
int func();
float func();
char func();
char* func();
int * func();
float *func();
我們看到前四個函數的返回類型,是標準的系統類型,void ,int ,float,char。這個毫無疑問,後三個則返回值都是指針類型,
C語言函數的返回類型,可以是指針類型。這就稱之爲指針函數,概念很簡單。再簡單地說就是返回一個地址指針。
類型:
類型名 *函數名(函數參數列表);
2.函數指針
函數指針是本文介紹的重點,什麼是函數指針,說白了就是一個指向函數的指針。首先它是一個指針,它指向的是一個函數的入口地址,
函數的入口地址在哪裏呢,函數就是內存中的一片區域,函數有一個入口地址,函數指針就是指向的這個入口地址。
例如:
void func();
void func(int a);
void func(int a,char b);
函數指針的作用是什麼呢,有兩方面,一個是爲了調用函數提供另一種途徑,二是可以把函數當做一個變量來傳遞,起到回調的作用。
個人認爲後一點很重要,在實際的編碼中用到很多,可節省不少工作量。
上述三個函數,我們可以寫成如下形式:
void (*Func1)();
void (*Func2)(int a);
void (*Func3)(int a,char b);
這樣在調用的時候就可以用如下方法:
(*Func1)();
(*Func2)(1);
(*Func3)(1,'a');
下面進行下一步操作,我們把它們聲明成一種類型:
typedef void (*Func1)();
typedef void (*Func2)(int a);
typedef void (*Func3)(int a,char b);
這是就可以定義 Func1,Func2,Func3類型的變量了,我們就可以把函數當做參數傳遞了。
下面附上代碼
//
// main.cpp
// Test
//
// Created by 王猛 on 13-11-15.
// Copyright (c) 2013年 wangmeng. All rights reserved.
//
#include <iostream>
typedef void (*Func1)();
typedef void (*Func2)(int a);
typedef void (*Func3)(int a,char b);
void func1()
{
printf("%s call\n",__FUNCTION__);
}
void func2(int a)
{
printf("%s call a=%d\n",__FUNCTION__,a);
}
void func3(int a,char b)
{
printf("%s call a=%d,b=%c\n",__FUNCTION__,a,b);
}
void callBack1(Func1 f)
{
(*f)();
}
void callBack2(Func2 f, int a)
{
(*f)(a);
}
void callBack3(Func3 f, int a, char b)
{
(*f)(a,b);
}
int main(int argc, const char * argv[])
{
callBack1(func1);
callBack2(func2, 1);
callBack3(func3, 1, 'b');
func1();
func2(1);
func3(1, 'b');
return 0;
}
輸出結果是: