函數指針與指針函數、陣列指針與指針陣列的區別

2020-08-13 10:22:28

函數指針與指針函數

1.指針函數

指針函數是一個函數,只不過它的返回值是一個指針(地址值)。
– 普通函數定義:int fun(int a);
– 指針函數定義:int * fun(int a);
小括號的優先順序比 ’ * ’ 高,所以這裏的 ’ * ’ 是與 int 結合的,所以函數返回值是 int * 的指針型別(地址)。

typedef struct data_test{
	int a;
	char b;
}Data;

//指針函數
Data* fun(int a,char b){
	Data* data=(Data *)calloc(1,sizeof(Data));
	data->a = a;
	data->b = b;

	return data;
}
int main(int argc,char *argv[])
{
	Data* d=fun(1,'h');
	printf("a=%d,b=%c\n",d->a,d->b);

	return 0;
}

測試結果如下:
在这里插入图片描述

2.函數指針

– 函數指針定義:int (* fun) (int a);
函數指針新增了小括號,將 ‘ * ’ 與函數名優先結合,所以函數指針本質上是一個指針,這個指針指向了一個函數。

給函數指針賦值時,要將函數地址賦給它,但是由於函數名本身就是函數的入口地址,所以地址符&不是必須的。

int x;
//函數指針定義
int (*fun)(int a);
//普通函數
int fun2(int a)
{
 	return a;
}
int main(int argc,char *argv[])
{
	//給函數指針賦值 兩種方法
	fun = fun2;//fun2是函數fun2的入口地址
	//fun = &fun2;

	//函數指針呼叫 兩種方法
	x=fun(6);
	printf("a=%d\n",(*fun)(5));

	printf("x=%d\n",x);
	return 0;
}

測試結果如下:
在这里插入图片描述

C++類別成員函數指針與C語言中的不同

宣告: typedef 返回值 (類名 :: * 指針型別名)(參數列表);
賦值: 指針型別名 指針名 = &類名 :: 成員函數名;
呼叫: (類物件 .* 指針名)(參數列表);或者(類指針 ->* 指針名)(參數列表);

class TestClass{
public:
    //非靜態函數
    int add(int a,int b){
        return a+b;
    }
};

//typedef 返回值 (類名::*指針型別名)(參數列表);
typedef int (TestClass::*Func)(int,int);

int main(){
    //類成員函數的地址賦值 這裏‘ & ’不能省略,不加 ‘ & ’ 編譯器會呼叫成員函數
    Func funcAdd = &TestClass::add;

    TestClass *p = new TestClass;
    int ret = (p->*funcAdd)(2,3);

    TestClass t;
    int ret2 = (t.*funcAdd)(2,3);

    cout << "ret=" << ret << endl;
    cout << "ret2=" << ret2 << endl;

    return 0;
}

陣列指針與指針陣列

1.陣列指針(行指針)

陣列指針本質是指針,該指針指向了一個數組
例:int ( *p )[5];這裏加了( ),將 * 先與p結合,所以指針p指向了有五個int 型元素的陣列。p++跳過了二維陣列的一行。

#include <iostream>
using namespace std;

int main()
{
    //一維陣列
    int arr1[5]={0};
    //二維陣列
    int arr2[3][5]={0};

	//陣列指針
    int *ptr1 = arr1;//指向一維陣列
    int (*ptr2)[5] = arr2;//指向二維陣列

    //列印一下陣列地址和陣列指針的值
    cout << "arr1= " << arr1 << " *ptr1= " << *ptr1 << endl;
    cout << "arr2= " << arr2 << " **ptr2= " << **ptr2 << " *ptr2= " << *ptr2 << endl;

    //第1行
    cout << "arr2[1]= " << arr2[1] << " *(ptr2+1)= " << *(ptr2+1) << " *ptr2[1]= " << *ptr2[1] << endl;
    return 0;
}

結果如下:在这里插入图片描述

注:陣列指針也叫行指針,或者指向一維陣列的指針,通常在二維以上的數組裏說討論陣列指針纔有意義

2.指針陣列

指針陣列本質是陣列,陣列元素是指針型別
例:int * p[5]; 這裏[ ]的結合優先順序高於 * ,所以可以看成( int * )p[5]; 也就是說陣列p有5個元素,每個元素是 int * 型。p是陣列名,是首元素地址,p++跳過一個元素。
在这里插入图片描述

#include <iostream>
using namespace std;

int main()
{
    //指針陣列
    int * p_arr[5];

    //每個元素是指針型別 32位元平臺固定4位元組大小
    cout << "total size of array is " << sizeof(p_arr) << endl;
    cout << &p_arr[0] << " " << &p_arr[1] << " " << &p_arr[2] << " " << &p_arr[3] << " " << &p_arr[4] << endl;
    cout << p_arr << " " << p_arr+1 << " " << p_arr+2 << " " << p_arr+3 << " " << p_arr+4;

    return 0;
}


結果如下:
在这里插入图片描述