Static与函数指针 转
所謂函數(shù)指針就是一個指向函數(shù)的指針,也就是說我們定義一個函數(shù)指針量后,這個變量所在的空間要保存一個函數(shù)的地址。那么函數(shù)指針除了作為回調(diào)函數(shù)的傳參之外還有什么作用呢?這里我們就結(jié)合staitc的作用來探討一下函數(shù)指針是如何作為間諜的。
首先討論一下static的作用,static從本質(zhì)來講就兩個作用:
第一、 限定存儲域:被static修飾的變量無論是局部變量還是全局變量都將被編譯器存放在靜態(tài)區(qū)。而實際上在gcc編譯完生成的ELF格式文件中并沒有靜態(tài)區(qū)這個概念,所謂靜態(tài)區(qū)是我們在概括討論程序數(shù)據(jù)段的一種泛稱。實際上編譯器會根據(jù)具體情況把被static修飾的變量分為兩類:當變量被定義并初始化為非零值的時候,變量將放在.data段;當否則為初始化或初始化為零的時候?qū)⒎旁?bss段。我們在不深入討論的時候暫且可以將此兩段概括為靜態(tài)區(qū)。而放在靜態(tài)區(qū)的變量由于存儲域的原因?qū)е律芷诤荛L,長度為程序(確切講應該是該程序運行后的進程)的一次運行過程,而普通局部變量由于在運行過程中被系統(tǒng)分配在棧區(qū)所以生命周期只是一次函數(shù)的調(diào)用過程。
第二、 限定作用域:由于靜態(tài)還是普通局部變量本身的作用域就是函數(shù)內(nèi)部,因此static的作用域主要是對全局變量和函數(shù)的限定。被staitc修飾的全局變量或函數(shù)都被編譯器標記為僅在本文件中使用,由于編譯器在編譯過程中是以.c結(jié)尾的源文件為單位依次生成以.o結(jié)尾的目標文件,所以最后連接器在連接過程中將不允許被static修飾的變量或函數(shù)的地址對外鏈接。這樣既可以防止全局變量或函數(shù)的重名問題,又可以防止由于無關(guān)的全局變量誤操作引起的程序邏輯問題。因此static就限定了變量或函數(shù)的作用域。
那么被static修飾的函數(shù)就真的只能在本文件中使用了嗎?答案是否定的,由于C語言的精華——指針的強大功能讓我們很輕松的利用函數(shù)指針就可以實現(xiàn)在文件外部調(diào)用被static修飾的函數(shù)。
首先來看一段實驗代碼(詳見圖1):
?
圖1
代碼中編寫了兩個源文件分別為main.c和global_fun.c。
其中main.c中定義了一個被static修飾的函數(shù)int local_fun(void);
global_fun.c中定義了global_fun()函數(shù);
兩個函數(shù)都只打印了一句話說明自己是哪個函數(shù)。由于static的限定作用導致global_fun中想要調(diào)用local_fun函數(shù)是不可能的,編譯器會在連接期間報錯(詳見圖2):
?
圖2
接著修改程序,將global_fun函數(shù)定義為帶有一個參數(shù)為函數(shù)指針的函數(shù),并且在main函數(shù)中定義一個函數(shù)指針p指向被static修飾的靜態(tài)函數(shù)local_fun,接著調(diào)用global_fun函數(shù)并給其傳遞參數(shù)p(詳見圖3):
?
圖3
這時候編譯運行,一切正常(詳見圖4):
?
圖4
總結(jié):指針是C語言的精華所在,指針的靈活實用將使你的開發(fā)工作變得游刃有余事半功倍。因此熟練掌握指針的操作對于一位從事C開發(fā)的程序員來說是不可或缺的基本功。而正因為指針的靈活多變導致我們在使用指針操作數(shù)據(jù)的時候要格外謹慎,一不小心將會導致致命的程序錯誤。但是C語言再強大終究只是一門工具,只要理解操作系統(tǒng)的原理熟悉C語言的規(guī)則然后嚴密謹慎地使用這門工具,那么你將會越發(fā)感受到C編程的樂趣。
原文鏈接:
轉(zhuǎn)載于:https://www.cnblogs.com/GUK0/p/4574551.html
總結(jié)
以上是生活随笔為你收集整理的Static与函数指针 转的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 我的Linux随笔目录
- 下一篇: WPF月视图控件