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