精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

周立功教你學C語言編程:結構體,使程序設計更方便——內置函數指針和嵌套結構體

AGk5_ZLG_zhiyua ? 來源:未知 ? 作者:電子大兵 ? 2017-09-06 09:27 ? 次閱讀

第二章為程序設計技術,本文為2.2.3 內置函數指針和2.2.4 嵌套結構體

我們知道,數組和指針是相同類型有序數據的集合,但很多時候需要將不同類型的數據捆綁在一起作為一個整體來對待,使程序設計更方便。在C語言中,這樣的一組數據被稱為結構體。

>>>2.2.3內置函數指針

面對一系列數據,真正重要的不是如何存儲數據,而是如何使用數據。實際上,一個結構體的成員可以是數據,還可以是包含操作數據的函數指針。為了支持這種風格,在這里不妨引入一個新的概念——方法是作為某個結構體的一部分聲明的,有了方法就可以操作存儲在結構體中的數據。

1.類型與變量

當函數指針作為結構體的成員時,即將校驗參數和調用校驗器的函數指針封裝在一起,形成了一個新的結構體類型。有了類型就可以定義一個該類型的變量,然后就可以用這個變量引用校驗參數和調用校驗器函數。

為了支持這種風格,C允許將方法作為某個結構體的一部分來聲明,那么操作存儲在結構體中的數據就很容易了,詳見程序清單2.18。

程序清單 2.18 范圍值校驗器接口

接下來需要設計一個判斷value值是否符合范圍值要求的validateRange()接口函數,其具體的實現詳見程序清單2.19。

程序清單 2.19 范圍值校驗器接口函數的實現

同理,偶校驗器OddEvenValidator和變量oddEvenValidator的定義詳見程序清單2.20。

程序清單 2.20 偶校驗器接口

接下來同樣需要設計一個判斷value值是否符合偶校驗要求的validateOddEven()接口函數,其具體的實現詳見程序清單2.21。

程序清單 2.21 偶校驗器接口函數的實現

顯然,無論是什么校驗器,其共性是value值合法性判斷,因此可以共用一個函數指針,即特殊的函數指針類型RangeValidate和OddEvenValidate被泛化成了一般的函數指針類型Validate。其次,由于每個函數都有一個指向當前對象的pThis指針,因此特殊的結構體類型struct _RangeValidator*和struct _OddEvenValidator *被泛化成了void *類型,即可接受任何類型數據的實參。比如:

這就是范型編程,校驗器泛化接口的實現詳見程序清單 2.22。由于pRangeValidator與pThis的類型不同,因此必須對pThis指針強制類型轉換才能引用相應結構體的成員。

程序清單 2.22 通用校驗器接口的實現(validator.c)

由此可見,當將方法作為結構體的一部分聲明時,就直接將方法和數據打包成為了一個新的數據類型RangeValidator。有了RangeValidator類型,就可以創建一個該類型的變量rangeValidator,即可通過rangeValidator引用該結構體的數據,并調用相應的處理函數。真正想強化的是由方法定義結構體的思想,而不是實現結構體時碰巧用到的那些數據。

2.初始化

使用名為newRangeValidator的宏將結構體初始化:

其中,validateRange為范圍值校驗器的函數名,使用方法如下:

宏展開后如下:

其相當于:

如果有以下定義:

即可通過pValidator引用RangeValidator的min和max。校驗函數的調用方式如下:

以上調用形式的前提是已知pValidator指向了確定的結構體類型,如果pValidator將指向未知的校驗器,顯然以上調用形式無法做到通用,那么將如何調用?

雖然pValidator與&rangeValidator.validate的類型不一樣,但它們的值相等,因此可以利用這一特性獲取validateRange()函數的地址。比如:

其調用形式如下:

3.接口與實現

為了便于閱讀,如程序清單2.23所示詳細地展示了通用校驗器的接口。

程序清單 2.23 通用校驗器接口(validator.h)

以范圍值校驗器為例,調用validateRange()的rangeCheck()函數的實現如下:

rangeCheck()函數的調用形式如下:

由此可見,rangeCheck()函數的實現不依賴任何具體校驗器。 注意,在這里,作者并沒有提供完整的代碼,請讀者補充完善。

>>>2.2.4嵌套結構體

1.重構

隨著添加一個又一個功能,處理一個又一個錯誤,代碼的結構會逐漸退化。如果對此置之不理,這種退化最終會導致糾結不清,難以維護的混亂代碼,因此需要經常性地重構代碼扭轉這種退化。

重構就是在不改變代碼行為的前提下,對其進行一系列小的改進,旨在改進系統結構的實踐活動。雖然每個改進都是微不足道的,甚至幾乎不值得去做,但如果將所有的改造疊加在一起時,對系統設計和架構的改進效果是十分明顯的。

在每次細微改進后,通過運行單元測試以確保改進沒有造成任何破壞,然后才去做下一次改進。如此往復周而復始,每次改進后都要運行,通過這種方式保證在改進系統設計的同時系統能夠正常工作。

重構是持續進行的,而不是在項目結束時、發布版本時、迭代結束時、甚至每天下班時才進行。重構是每隔一個小時或半個小時就要去做的事情,通過重構可以持續地保持盡可能干凈、簡單且有表現力的代碼。

大量的實踐證明,重復可能是軟件中一切邪惡的根源,許多原則和實踐規則都是為了控制與消除重復而創建的。消除重復最好的方法就是抽象,即將所有公共的函數指針移到一個單獨的結構體中,創建一個通用的Validator類型校驗器。也就是說,如果兩種事物相似的話,必定存在某種抽象能夠統一它們,因此消除重復的行為會迫使團隊提煉出許多的抽象,進一步減少代碼之間的耦合

自從發明子程序以來,軟件開發領域的所有創新都是在不斷嘗試從源代碼中消滅重復,即DRY(Don't Repeat Yourself)原則——別重復自己,因為重復黏貼會帶來很多的問題,所以無論在哪里發現重復的代碼,都必須消除它們。

2.類型與變量

實際上,不管是范圍值校驗器還是奇偶校驗器,其本質上都是校驗器,其相同的屬性是校驗參數和待校驗的值,其相同的行為可以共用一個函數指針調用不同的校驗器。根據依賴倒置原則,將它們相同的屬性和行為抽象為一個結構體類型Validator。比如:

在這里,還是以范圍值校驗為例,在RangeValidatro結構體中嵌套一個Validator類型的結構體,即將Validator類型的變量isa作為RangeValidator結構體的成員。比如:

由于&rangeValidator與&rangeValidator.isa的值相等,因此以下關系恒成立。比如:

即可將validateRange()函數原型:

中的“void *pThis”轉換為“Validator *pThis”,validatrRange()函數原型進化為:

3.初始化

當將Validator類型的isa作為RangeValidator結構體成員時,顯然rangeValidator.isa是一個結構體變量名,可以象任何普通結構體變量一樣使用。使用Validator類型表達式:

即可引用rangeValidator變量的結構體成員isa的成員validate,即將rangeValidator.isa作為另一個點操作符的左操作符。比如:

由于點操作符的結合性是從左向右的,因此可以省略括號。其等價于:

只要將rangeValidator.isa看作一個Validator類型的變量即可。

使用名為newRangeValidator的宏將結構體初始化:

其中,validateRange為范圍值校驗器函數名,使用方法如下:

宏展開后如下:

其中,外面的{}為RangeValidator結構體賦值,內部的{}為RangeValidator結構體的成員變量isa賦值。即:

如果有以下定義:

即可用pValidator引用RangeValidator的min和max。

由于pValidator與&rangeValidator.isa不僅類型相同且值相等,則以下關系同樣成立:

因此可以利用這一特性獲取validateRange()函數的地址,即pValidator->validate指向validateRange()。其調用形式如下:

4.接口與實現

以范圍值校驗器為例,validatorCheck()函數的調用形式如下:

當然,也可以采取以下調用形式:

其效果是一樣的。

為了便于閱讀,如程序清單 2.24所示詳細地展示了通用校驗器的接口。

程序清單 2.24通用校驗器接口(validator.h)

以范圍值校驗器為例,調用validateRange()的validatorCheck()函數的實現如下:

由此可見,validatorCheck()函數的實現不依賴任何具體校驗器,通用校驗器接口的實現詳見程序清單 2.25。

程序清單 2.25 通用校驗器接口的實現(validator.c)

在這里,作者并沒有提供完整的代碼,請讀者補充完善。


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 指針
    +關注

    關注

    1

    文章

    480

    瀏覽量

    70510
  • C語言編程
    +關注

    關注

    6

    文章

    90

    瀏覽量

    21093
  • 周立功
    +關注

    關注

    38

    文章

    130

    瀏覽量

    37584
  • 結構體
    +關注

    關注

    1

    文章

    130

    瀏覽量

    10833

原文標題:周立功:結構體,使程序設計更方便——內置函數指針和嵌套結構體

文章出處:【微信號:ZLG_zhiyuan,微信公眾號:ZLG致遠電子】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    立功教你C語言編程程序設計:這樣寫函數指針數組最好用

    立功教授數年之心血之作《程序設計與數據結構》以及《面向AMetal框架與接口的編程(上)》,電子版已無償性分享到電子工程師與高校群體,在公
    的頭像 發表于 08-31 14:06 ?6857次閱讀
    <b class='flag-5'>周</b><b class='flag-5'>立功</b><b class='flag-5'>教你</b><b class='flag-5'>學</b><b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>編程</b>與<b class='flag-5'>程序設計</b>:這樣寫<b class='flag-5'>函數</b><b class='flag-5'>指針</b>數組最好用

    立功教你程序設計結構:內存對齊和基本數據類型

    我們知道,數組和指針是相同類型有序數據的集合,但很多時候需要將不同類型的數據捆綁在一起作為一個整體來對待,使程序設計方便。在
    的頭像 發表于 09-01 13:47 ?7973次閱讀
    <b class='flag-5'>周</b><b class='flag-5'>立功</b><b class='flag-5'>教你</b><b class='flag-5'>學</b><b class='flag-5'>程序設計</b><b class='flag-5'>結構</b><b class='flag-5'>體</b>:內存對齊和基本數據類型

    高手們幫忙看下這個結構嵌套程序,編譯無法通過

    ;<unnamed>" has no field "x"我查了一下C語言的相關書籍,問題是內層嵌套結構沒有變量名,由于子
    發表于 03-15 11:08

    新書創作談:立功教授數十年之心血力作《程序設計與數據結構

    整理出《程序設計與數據結構》這本書,其內容如同培訓講師的教案,是立功和團隊的讀書筆記和程序設計實踐的心得。《
    發表于 05-15 18:04

    【完整資料】《程序設計與數據結構立功數十年心血力作

    ,是立功和團隊的讀書筆記和程序設計實踐的心得。《程序設計與數據結構》重點闡述了三大方向內容。C
    發表于 05-16 16:43

    漫談C語言結構

    變量的方法代替函數(入口參數)的重新定義就表示了結構“中用”。繼續以上面的結構為例子,我們來分析。假如現在我有如下
    發表于 11-15 15:59

    單片機C語言 -- 基于結構的面向對象編程技巧

    1、Keil4 C51工程網址:2、需要一定的C語言基礎,才看得懂此文。一、面向對象單片機C語言的面向對象
    發表于 02-04 21:48

    程序設計與數據結構》【完整資料】分享!

    。 在當前工程師在C語言學習時,遇到如指針函數函數指針,如何靈活應用
    發表于 08-31 16:20

    C語言結構函數指針封裝示例

    C語言結構函數指針封裝示例示例:#include int i, j;struct DATE{
    發表于 07-15 06:18

    C語言入門教程-指向結構指針

    指向結構指針C語言中幾乎可以創建指向任何類型的指針,包括用戶自定義的類型。創建
    發表于 07-29 12:04 ?3147次閱讀

    C語言程序設計介紹

    包括:C 語言概述,算法基礎,數據類型、運算符與表達式,順序 結構程序設計,選擇結構程序設計
    發表于 02-17 15:49 ?0次下載

    C語言程序設計教程之結構與共用的詳細資料說明

    本文檔詳細介紹的是C語言程序設計教程之結構與共用的詳細資料說明主要內容包括了:1
    發表于 03-01 17:20 ?11次下載
    <b class='flag-5'>C</b><b class='flag-5'>語言</b><b class='flag-5'>程序設計</b>教程之<b class='flag-5'>結構</b><b class='flag-5'>體</b>與共用<b class='flag-5'>體</b>的詳細資料說明

    C程序設計基礎-數組與結構

    數組,結構指針C語言里面最難的部分,如果在編程中可以熟練的運用這三樣工具,會大大地提高開發
    的頭像 發表于 03-02 10:10 ?941次閱讀
    <b class='flag-5'>C</b><b class='flag-5'>程序設計</b>基礎-數組與<b class='flag-5'>結構</b><b class='flag-5'>體</b>

    C語言入門之結構指針

    C語言中,指向結構對象的指針變量既可以指向結構
    的頭像 發表于 03-24 14:59 ?996次閱讀

    結構指針的關系

    C語言中,結構(Struct)是一種用戶自定義的數據類型,它允許您將不同類型的數據項組合在一起,以便形成一個復雜的數據
    的頭像 發表于 01-11 08:00 ?943次閱讀
    <b class='flag-5'>結構</b><b class='flag-5'>體</b>與<b class='flag-5'>指針</b>的關系