函數指針
注:該彙編使用intel格式,及與AT&T相反的操作方式
0x01 指針無法區分數據還是代碼
1. 我們知道c/c++之所以偉大是因爲很多方面,其中就是因爲指針可以操作內存中的任意數據,理論上只要是在內存中,都可以操控。
2. 那麼指針可以指向操作碼嗎???這個就可以打開潘多拉的魔盒了。其實是可以的,而且還可以打印機器碼,因爲操作指令是存在內存中的,然而寄存器算是和cpu最緊密的了,但是也只是常數。直接給cpu計算的,所以彙編當中的一條指令都會被壓縮成一串數字,其中包括cpu行爲,需要做的動作,如 mov a,$5 0x0040D788: C7 05 34 7E 42 00 05 00 00 00 ---->如果有興趣可以在文章最後看見延伸。
0x02 函數指針的使用
我們都知道,指針操作數據的例子,int *p = &a ,這是們寫過很多次的代碼,然後我們開始介紹指針使用__代碼__
int func(int a)
{
return 1;
}
int (*p)(int) = func; //
0x03 函數指針實現類重載
直接附上代碼–注意void intergal(double a, double b, double (*fun)(double, double)) 函數
#include "stdio.h"
#include "math.h"
//intergal(x^2)
double func1(double a , double b)
{
double sum = 0.0;
double length = 0.000001;
double x = a;
while(x < b)
{
sum += x*x*0.000001;
x+=0.000001;
}
return sum;
}
//intergal(sinx)
double func2(double a , double b)
{
double sum = 0.0;
double length = 0.000001;
double x = a;
while(x < b)
{
sum += sin(x)*0.000001;
x+=0.000001;
}
return sum;
}
//intergal(e^(x^-2))
double func3(double a , double b)
{
double sum = 0.0;
double length = 0.000001;
double x = a;
while(x < b)
{
sum += exp(sqrt(x))*0.000001;
x+=0.000001;
}
return sum;
}
void intergal(double a, double b, double (*fun)(double, double))
{
double result = 0.0;
result = (*fun)(a, b);
printf("%g\n", result);
}
void main()
{
printf("計算x^2在0~1上的定積分結果:");
integral(0.0, 1.0, func1);
printf("計算sinx在0~π上的定積分結果:");
integral(0.0, 3.141593, func2);
printf("計算e^(x^-2)在0~1上的定積分結果:");
integral(0.0, 1.0, func3);
}
//---------引自代碼揭祕--------------//
void intergal(double a, double b, double (*fun)(double, double)) 該函數不就是類似於重載的的函數嗎??一個函數名,傳入參數不同實現不同的邏輯,只需要將功能放入被指向的函數
0x04 奇葩的語法 int ((*p)(int,int)[10])(int);
當初看到這個真的是想吐,足足看了我半個小時,查資料看相視的函數才解決
int (*p)(int) ----這個就不說了嗷,大家都會
//接下來開始變形
int *(*p)()() //聲明一個函數指針,該函數返回值爲一個函數,返回函數的返回值爲int *
int (*(*p)()()) //聲明一個函數指針,該函數返回值爲一個指針,該指針指向一個函數,該函數的返回值爲int
int (*(*p)()[10])() //明一個函數指針,該函數返回值爲一個指針數組,數組裏的每一個指針都指向一個函數,該函數的返回值爲int
//終極版
int *(*(*p)(int,int)[10])(int); //聲明一個函數指針,該函數有兩個int型參數該返回值爲一個指針,指向一個數組,該數組裏的每一個元素都是一個指針,指向一個函數,參數爲int,返回值爲int*
昨天晚上看到這個差點把我氣哭了,天吶,這哪是語法啊,給我的感覺就像是,只要語法合理它可以一直跑下去,然後函數裏面調用函數,函數裏面返回指針的那種,雖然沒有應用場景
附上
好了,解決了今日問題,該說說我進一步理解指針與內存了,
現附上一張圖片,注意看地址和操作碼!!!
然後就會驚奇的發現 0xE1216F - 0xE12168 剛好等於 c7 45 F8 00 00 00 00 等於7
驚奇吧!!
所以此時指針這樣做, int * p = (int *)0x00E12168 然後16進制打印,就會出現 c7 45 F8 00 00 00 00
ps:有時候真理一直都在,你看不見是因爲你知識積累不夠,當然也有可能是你想不到hahahahah~~