指針在c語言中的妙用

2021-01-08 電子產品世界

指針,任何一個計算機語言都少不了的好東西。特殊問題,特殊對待。函數指針就是這麼一個特殊的例子。比如:

void Run(void)

{

PORTB = ~PORTB;

}

這個函數我們可以直接在main()裡調用它,也可以使用指針。如下所示:

void (*fun)(void);

int main()

{

fun = Run;

fun();

return 0;
}

使用指針有很多優點,關於指針的基本概念可以參考的第十六課:http://www.51hei.com/mcuteach/133.html,如果我們定義了一個指針數組,就可以同時調用多個已知的函數,在不需要調用的時候再將它刪除。特別是在C++裡,如果定義了一個全局的class,那麼我們就可以在構造函數裡向指針數組添加一個指針,這個指針指向main()裡需要反覆調用的程序,那麼在編寫大型程序的時候維護起來就相當輕鬆了。下面是我在使用C++類定義的一個函數回調類,它是一個全局的類,在main()之前就已經定義了。

typedef void (*PROC)(MESSAGE_TYPE style,MESSAGE ¶m);//定義函數類型,形參為MESSAGE枚舉typedef void (*HANDLER)(void);class Delegate{protected:PROC proc[PROC_SIZE];HANDLER pRun[PROC_SIZE];static void NULLFUNCTION0(void){}static void NULLFUNCTION2(MESSAGE_TYPE style,MESSAGE ¶m){}public:bool add(PROC fun)//添加回調函數{char i;for(i = 0 ; i PROC_SIZE ; i++){if(proc[i] == NULLFUNCTION2){proc[i] = fun;return true;}}return false;}bool add(HANDLER fun)// 添加實時運行函數{char i;for(i = 0 ; i PROC_SIZE ; i++){if(pRun[i] == NULLFUNCTION0){pRun[i] = fun;return true;}}return false;}void clearProc()//清除函數指針{char i;for(i = 0; i PROC_SIZE ; i++){proc[i] = NULLFUNCTION2;}}void clearRun(){char i;for(i = 0; i PROC_SIZE ; i++){pRun[i] = NULLFUNCTION0;}}bool remove(PROC fun)//刪除最後一個匹配的回調{char i;i = PROC_SIZE ;while( i-- ){if(proc[i] == fun){proc[i] = NULLFUNCTION2;return true;}}return false;}bool remove(HANDLER fun)// 刪除最後一個匹配的回調{char i;i = PROC_SIZE ;while( i-- ){if(pRun[i] == fun){pRun[i] = NULLFUNCTION0;return true;}}return false;}bool removeAll(PROC fun)//刪除所有匹配的回調{char i;bool deled = false;for(i = 0; i PROC_SIZE; i++){if(proc[i] == fun){proc[i] = NULLFUNCTION2;deled = true;}}return deled;}void selectProc(PROC fun)// 選擇回調{clearProc();add(fun);}void selectRun(HANDLER fun)// 選擇回調{clearRun();add(fun);}void send(MESSAGE_TYPE type,MESSAGE param = WM_NULL)// 發送消息{char i;for(i = 0 ; i PROC_SIZE ; i++){if(proc[i] != NULLFUNCTION2){proc[i](type,param);if(param == WM_HANDLED)return ;}}}void Run()//運行{char i;for(i = 0 ; i PROC_SIZE ; i++){if(pRun[i] != NULLFUNCTION0){pRun[i]();}}}void operator = (PROC fun){selectProc(fun);}void operator = (HANDLER fun){selectRun(fun);}void operator += (PROC fun){add(fun);}void operator += (HANDLER fun){add(fun);}void operator -= (HANDLER fun){remove(fun);}void operator -= (PROC fun){remove(fun);}Delegate(){clearProc();clearRun();}};Delegate dg;

把它重命名為一個delegate.h;

接下來我們編寫另外一個h文件,很簡單。

void TEST_out();

class TEST

TEST()

{

dg += TEST_out;

DDRB = 0xFF;

}

void out()

{

PORTB = ~PORTB;

}

};

TEST a;

void TEST_out()

{

a.out();

}

把它保存為test.h;要保存到編譯器的默認路徑,我使用的是IAR編譯器,默認路徑為C:\Program Files\IAR Systems\Embedded Workbench 4.0\avr\inc\

接下來編寫main()函數;

#include iom8.h>

#include delegate.h>

#include test.h>

int main()

{

while(1)

{

dg.Run();

}

return 0;

}

主函數裡幾乎什麼也沒有寫,可是你知道這個程序在單片機上運行是什麼結果嗎?OH,你答對了就是PORTB埠會一直不停的翻轉。沿著這個思路,我們可以把TEST改為數碼管的驅動,可以多定義幾個h文件,通過指針將它們連接起來,這樣,我們在main裡幾乎不用做太多的事情就能解決一切。是不是感覺很爽呢。

相關焦點

  • C 語言程序設計---指針
    上次 C 語言寫到了數組,有些書是先講指針,有些書是先講函數,按照我以前學習 C 語言的順序,以及對 C 語言的理解,學習的順序是這樣的:數組--->指針--->函數,所以本篇文章講解 C 之指針。C 語言是值得好好學習的一門語言,是一門基礎語言,更是我編程入門的語言,其中很多編程思想,至今影響著我,在工作中對我的幫助很大。
  • c語言指針與字符數組
    ,字符串的使用在C語言中也是非常重要的,常常會遇到一些操作,如字符串的修改、拷貝、字符串長度等,在物聯網的應用中也尤為突出,物聯網應用中所用的模組,大多是需要使用AT指令的,這就需要對字符串的操作。pc中的值是數組c的首元素地址100
  • 為什麼指針被譽為 C 語言靈魂?
    所以,要想徹底理解指針,首先要理解 C 語言中變量的存儲本質,也就是內存。在 C 語言中我們會這樣定義變量:int a = 999;char c = 'c';當你寫下一個變量定義的時候,實際上是向內存申請了一塊空間來存放你的變量。
  • 入門C語言中的數組,字符串常量與指針
    MAX_SIZE + 1];C數組開始於元素0,所以像陣列定義 int a[3];將創建三個int元件,可尋址如a[0],a[1],和a[2]請注意,即使定義很難說a[3],也沒有名為a[3]與其他變量一樣,全局和靜態數組元素默認情況下初始化為0,並且自動數組元素填充有垃圾值可以使用大括號中的一個或多個值來初始化數組
  • C語言簡明教程(九)指針(二)
    在 C 語言中只有字符變量,沒有字符串變量。以下語句 printf("%s\n",string);中 %s 是輸出字符串時所用的格式,在輸出項中給出字符指針變量名 string,則系統會輸出 string 所指向的字符串第一個字符,然後自動使 string 加 1,使之指向下一個字符,再輸出該字符...如此直到遇到字符串結束標誌 '\0',因此再輸出是能確定輸出的字符到何時結束。
  • C語言指針詳解
    先聲明幾個指針放著做例子:例一:(1)int *ptr;(2)char *ptr;(3)int **ptr;(4)int (*ptr)[3];(5)int *(*ptr)[4];如果看不懂後幾個例子的話,請參閱我前段時間貼出的文章 如何理解c和c++的複雜類型聲明>&
  • c語言的指針真的很有趣
    指針是一個很有趣的東西,想要成為一個出色的程式設計師,那麼指針就要學的好,指針涉及到內存分配的問題。每一個變量都有自己的內存,可以使用&來訪問變量存儲的位置。ta就是一個地址。這語句中用*來指定指針變量int *ip; /* 一個整型的指針 */double *dp; /* 一個 double 型的指針 */float *fp; /* 一個浮點型的指針 */
  • C語言陷阱與技巧31節,都說void*指針是「萬能指針」,它萬能在哪
    在C語言程序開發中,一些比較成熟的庫函數常常會被使用。畢竟,如果手邊就有不錯的「輪子」可以用,沒有程式設計師願意再花費精力憑空造一個輪子出來。因為 void 類型是一個特殊的類型,常被稱作「空類型」,C語言中沒有 void 類型的變量,所以在遇到 void 指針時,編譯器根本不知道如何解釋接下來的內存,甚至編譯器都不知道接下來多少內存屬於它。
  • C 語言指針詳解
    指針pp為指向指針p的指針定義指針變量C語言中,定義變量時,在變量名 前 寫一個 * 星號,這個變量就變成了對應變量類型的指針變量。必要時要加( ) 來避免優先級的問題。引申:C語言中,定義變量時,在定義的最前面寫上typedef ,那麼這個變量名就成了一種類型,即這個類型的同義詞。
  • 為什麼有人說指針是 C 語言的精髓?
    4) 兩個指針變量可以相減。如果兩個指針變量指向同一個數組中的某個元素,那麼相減的結果就是兩個指針之間相差的元素個數。 5) 數組也是有類型的,數組名的本意是表示一組類型相同的數據。在定義數組時,或者和 sizeof、& 運算符一起使用時數組名才表示整個數組,表達式中的數組名會被轉換為一個指向數組的指針。
  • C語言 | 指向指針的指針
    「要成為絕世高手,並非一朝一夕,除非是天生武學奇才,但是這種人…萬中無一」這道理放在C語言學習上也一併受用
  • C語言函數指針之回調函數
    如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。回調函數不是由該函數的實現方直接調用,而是在特定的事件或條件發生時由另外的一方調用的,用於對該事件或條件進行響應。2 為什麼要用回調函數?
  • 深入淺出剖析C語言函數指針與回調函數(一)
    定義是如果你把函數的指針(地址)作為參數傳遞給另一個函數,當這個指針被用來調用其所指向的函數時,我們就說這是回調函數,確實,有所不同,但道理是一樣的,我們接下來再來看一個例子。我們把函數的指針(地址),這裡也就是add_ret,作為參數int add(int a , int b , int (*add_value)()) , 這裡的參數就是int(*add_value)() , 這個名字可以隨便取,但是要符合C語言的命名規範。當這個指針被用來調用其所指向的函數時,我們就說這是回調函數。
  • C語言是C++的母語,萬變不離指針,指針是C語言的一大法寶!
    我們來看看C語言如何借鑑類的三大特性來更好的組織代碼。 1、繼承 C語言沒有嚴格意義上的繼承,可以藉助結構體嵌套實現類似於繼承的形式,但始終不盡人意。
  • C語言:數組和指針
    在內存中數組不管多少維都是線性存儲的,內存地址是遞增的。對於數組可以從幾何的角度更好的理解,一維數組就是一條線,一行數據,每個元素都是一列,而二維數組是由一維數組構成的矩陣(長方形),每行都是一個一維數組,依次類推,那三維數組就可以看成是二維數組疊加而成的立方體,比如arr[5][6][7],由5個6行7列的二維數組疊加。
  • C語言基礎知識
    C 傳遞指針給函數通過傳遞指針給函數,可以直接修改原參數(實參),而不是引用實參到形參。pow(x, y)函數C 和 Python 語言的 pow(x, y) 方法都是用於返回 (x 的 y 次方) 的值,C 語言中其原型為:double pow(double x, double y)。
  • C語言的指針,簡介
    指針,是一個表示變量或函數的地址的無符號整數。指針的字節數,與CPU的位數有關,32位機是4位元組,64位機是8位元組。與高級語言的long類型的大小是一致的。所以在java的JNI庫裡,如果需要把native層的C結構體的指針保存到java層,一般是定義一個long類型的變量。指針指向的變量,可以是普通變量、數組變量、結構體變量,以及數組元素、結構體的成員變量,還可以是指針變量。指針還可以指向函數,叫做函數指針。
  • C語言中的指針和內存洩漏
    引言對於任何使用 C 語言的人,如果問他們 C 語言的最大煩惱是什麼,其中許多人可能會回答說是指針和內存洩漏
  • C語言的那些小秘密之函數指針
    我們經常會聽到這樣的說法,不懂得函數指針就不是真正的C語言高手。我們不管這句話對與否,但是它都從側面反應出了函數指針的重要性,所以我們還是有必要掌握對函數指針的使用。先來看看函數指針的定義吧。本文引用地址:http://www.eepw.com.cn/article/270442.htm  函數是由執行語句組成的指令序列或者代碼,這些代碼的有序集合根據其大小被分配到一定的內存空間中,這一片內存空間的起始地址就成為函數的地址,不同的函數有不同的函數地址,編譯器通過函數名來索引函數的入口地址,為了方便操作類型屬性相同的函數,c/c++引入了函數指針,函數指針就是指向代碼入口地址的指針
  • 「C語言指針」指針數組?數組指針?
    有些同學在在初學C語言時候喜歡鑽牛角尖,這種喜歡鑽研的精神值得肯定,但有時候反而就是因為這樣錯過了更精更深的知識點。今天帶著大家來簡單過一下數組指針和指針數組,這兩兄弟像是兩座大山,重重地壓在很多小白的心頭上。