C語言詳解函數(shù)與指針的使用
一、函數(shù)類型
C 語言中的函數(shù)有自己特定的類型
函數(shù)的類型由返回值,參數(shù)類型和參數(shù)個(gè)數(shù)共同決定,如 int add(int i, int j)的類型為 int(int, int)
C 語言中通過 typedef 為函數(shù)類型重命名
typedef type name(parameter list)
如
typedef int f(int, int);
typedef void p(int);
二、函數(shù)指針
函數(shù)指針用于指向一個(gè)函數(shù)
函數(shù)名是執(zhí)行函數(shù)體的入口地址
可通過函數(shù)類型定義函數(shù)指針:FuncType* pointer;
也可以直接定義: type (*pointer)(parameter list);
- pointer 為函數(shù)指針變量名
- type為所指函數(shù)的返回值類型
- parameter list 為所指函數(shù)的參數(shù)類型列表
下面看一個(gè)函數(shù)指針使用的代碼:
#include <stdio.h> typedef int(FUNC)(int); int test(int i) { return i * i; } void f() { printf("Call f()...\n"); } int main() { FUNC* pt = test; void(*pf)() = &f; printf("pf = %p\n", pf); printf("f = %p\n", f); printf("&f = %p\n", &f); pf(); (*pf)(); printf("Function pointer call: %d\n", pt(2)); return 0; }
輸出結(jié)果如下:
注意:
1.FUNC* pt = test; 是合法的,test 這個(gè)函數(shù)名代表的是函數(shù)的入口地址,
2.對(duì)于函數(shù)名來說,取不取地址沒有區(qū)別,例如上面代碼中的 FUNC* pt = test; 也可以寫成FUNC* pt = &test;
3.(*pf)(); 相當(dāng)于 f();
如果我們把void(*pf)() = &f; 改成void(*pf)() = 0x8048400; 直接利用函數(shù)指針跳轉(zhuǎn)到 0x8048400 這個(gè)地址來執(zhí)行,結(jié)果照樣也能正常輸出:
面試小問題:如何使用 C 語言直接跳轉(zhuǎn)到某個(gè)固定的地址開始執(zhí)行?
答案:通過函數(shù)指針
三、回調(diào)函數(shù)
回調(diào)函數(shù)是利用函數(shù)指針實(shí)現(xiàn)的一種調(diào)用機(jī)制
回調(diào)機(jī)制原理
- 調(diào)用者不知道具體事件發(fā)生時(shí)需要調(diào)用的具體函數(shù)
- 被調(diào)函數(shù)不知道何時(shí)被調(diào)用,只知道需要完成的任務(wù)
- 當(dāng)具體事件發(fā)生時(shí),調(diào)用者通過函數(shù)指針調(diào)用具體函數(shù)
回調(diào)機(jī)制中的調(diào)用者和被調(diào)函數(shù)互不依賴
下面看一個(gè)回調(diào)函數(shù)的使用示例:
#include <stdio.h> typedef int(*Weapon)(int); void fight(Weapon wp, int arg) { int result = 0; printf("Fight boss!\n"); result = wp(arg); printf("Boss loss: %d\n", result); } int knife(int n) { int ret = 0; int i = 0; for(i=0; i<n; i++) { printf("Knife attack: %d\n", 1); ret++; } return ret; } int sword(int n) { int ret = 0; int i = 0; for(i=0; i<n; i++) { printf("Sword attack: %d\n", 5); ret += 5; } return ret; } int gun(int n) { int ret = 0; int i = 0; for(i=0; i<n; i++) { printf("Gun attack: %d\n", 10); ret += 10; } return ret; } int main() { fight(knife, 3); fight(sword, 4); fight(gun, 5); return 0; }
輸出結(jié)果如下:
四、小結(jié)
- C 語言中的函數(shù)都有特定的類型
- 可以使用函數(shù)類型定義函數(shù)指針
- 函數(shù)指針是實(shí)現(xiàn)回調(diào)機(jī)制的關(guān)鍵技術(shù)
- 通過函數(shù)指針可以在 C 程序中實(shí)現(xiàn)固定地址跳轉(zhuǎn)
到此這篇關(guān)于C語言詳解函數(shù)與指針的使用的文章就介紹到這了,更多相關(guān)C語言 函數(shù)與指針內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
c語言?數(shù)據(jù)存儲(chǔ)與原碼?反碼?補(bǔ)碼詳細(xì)解析
不知道你是否和我一樣好奇,學(xué)習(xí)編程語言的同時(shí)想,各個(gè)數(shù)據(jù)類型是怎樣在我們的內(nèi)存中儲(chǔ)存的呢,如果你仔細(xì)深入了解的話,你會(huì)了解其中的樂趣,了解科學(xué)家們的偉大,了解c語言2022-02-02C語言中輸入函數(shù)(scanf()、fgets()和gets())的區(qū)別詳解
這篇文章主要給大家介紹了關(guān)于C語言中三種輸入函數(shù)(scanf()、fgets()和gets())區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11Qt使用TabWidget實(shí)現(xiàn)多窗體功能
Qt 是一個(gè)跨平臺(tái)C++圖形界面開發(fā)庫,利用Qt可以快速開發(fā)跨平臺(tái)窗體應(yīng)用程序,在Qt中我們可以通過拖拽的方式將不同組件放到指定的位置,本章將重點(diǎn)介紹TabWidget標(biāo)簽組件的常用方法及靈活運(yùn)用,需要的朋友可以參考下2023-12-12