1. 程式人生 > >當結構體遇上巨集定義,以及函式指標的高階寫法(結構體中能用巨集定義一個函式?)

當結構體遇上巨集定義,以及函式指標的高階寫法(結構體中能用巨集定義一個函式?)

一、結構體中可以定義一般的巨集定義
如:

struct aaa
{
   #define STATUS_1 100
   #define STATUS_2 200
   #define STATUS_3 300
   ........
};
   首先,這裡的巨集定義是在預編譯階段完成的,編譯器此時並不知道什麼結構體,所以這些巨集是全域性可見的。
   一個巨集定義,如果寫在結構體之內,即使與結構體之外的巨集定義名字重複了最多是編譯警告。可是如果不在結構體之內,名字重複可肯定是error。(未證實,可以做實驗,而且可以把兩處的巨集定義成不同的值,會是什麼情況?)
    定義在結構體之內的巨集在結構體內可以隱藏定義在結構體之外定義的巨集,如果都在結構體之外定義,那麼就是定義了兩個相同的巨集,而一個在內,一個在外,則結構體內只看到內部定義的巨集,而結構體外只看到外部定義的巨集,跟變數的隱藏類似。
   巨集的處理是在編譯的預處理階段完成的。前處理器根本就不認識什麼結構體,在C語言編譯器編譯這個C檔案中的結構體時,這個define語句已經不存在了。 相應的,用到這個巨集的地方,巨集本身也已經替換成巨集的值(這個巨集展開)。大家可以用gcc -E命令來只做預處理而不編譯,看看出來後的檔案。
至於為什麼在結構體裡頭#deifne,是因為這個巨集一般用於定義該結構體裡頭的標誌位變數的可能的值,和結構體的這個變數密切相關。放在一起從邏輯上比較容易理解。

二、同理結構體中用巨集定義一個類似於函式的東西(類似於C++行內函數)
如:

#define NETIF_INIT_SNMP(netif, type, speed) \
  /* use "snmp_ifType" enum from snmp.h for "type", snmp_ifType_ethernet_csmacd by example */ \
  netif->link_type = type;    \
  /* your link speed here (units: bits per second) */  \
  netif->link_speed = speed;  \
  netif->ts = 0
; \ netif->ifinoctets = 0; \ netif->ifinucastpkts = 0; \ netif->ifinnucastpkts = 0; \ netif->ifindiscards = 0; \ netif->ifoutoctets = 0; \ netif->ifoutucastpkts = 0; \ netif->ifoutnucastpkts = 0; \ netif->ifoutdiscards = 0

同之前所述,他只是一個巨集,並不能作為結構體的成員變數,所以結構體中要使用函式,只能是吧函式指標作為成員變數。

三、結構體的高階寫法(包含巨集以及回撥函式指標),出自STM32 LwIP,可以用來參考學習

struct netif {
  /** pointer to next in linked list */
  struct netif *next;
  /** IP address configuration in network byte order */
  struct ip_addr ip_addr;
  struct ip_addr netmask;
  struct ip_addr gw;
  /** This function is called by the network device driver
   *  to pass a packet up the TCP/IP stack. */
  err_t (* input)(struct pbuf *p, struct netif *inp);
  /** This function is called by the IP module when it wants
   *  to send a packet on the interface. This function typically
   *  first resolves the hardware address, then sends the packet. */
  err_t (* output)(struct netif *netif, struct pbuf *p,
       struct ip_addr *ipaddr);
  /** This function is called by the ARP module when it wants
   *  to send a packet on the interface. This function outputs
   *  the pbuf as-is on the link medium. */
  err_t (* linkoutput)(struct netif *netif, struct pbuf *p);
#if LWIP_NETIF_STATUS_CALLBACK
  /** This function is called when the netif state is set to up or down
   */
  void (* status_callback)(struct netif *netif);
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK
  /** This function is called when the netif link is set to up or down
   */
  void (* link_callback)(struct netif *netif);
#endif /* LWIP_NETIF_LINK_CALLBACK */
  /** This field can be set by the device driver and could point
   *  to state information for the device. */
  void *state;
#if LWIP_DHCP
  /** the DHCP client state information for this netif */
  struct dhcp *dhcp;
#endif /* LWIP_DHCP */
#if LWIP_AUTOIP
  /** the AutoIP client state information for this netif */
  struct autoip *autoip;
#endif
#if LWIP_NETIF_HOSTNAME
  /* the hostname for this netif, NULL is a valid value */
  char*  hostname;
#endif /* LWIP_NETIF_HOSTNAME */
  /** number of bytes used in hwaddr */
  u8_t hwaddr_len;
  /** link level hardware address of this interface */
  u8_t hwaddr[NETIF_MAX_HWADDR_LEN];
  /** maximum transfer unit (in bytes) */
  u16_t mtu;
  /** flags (see NETIF_FLAG_ above) */
  u8_t flags;
  /** descriptive abbreviation */
  char name[2];
  /** number of this interface */
  u8_t num;
#if LWIP_SNMP
  /** link type (from "snmp_ifType" enum from snmp.h) */
  u8_t link_type;
  /** (estimate) link speed */
  u32_t link_speed;
  /** timestamp at last change made (up/down) */
  u32_t ts;
  /** counters */
  u32_t ifinoctets;
  u32_t ifinucastpkts;
  u32_t ifinnucastpkts;
  u32_t ifindiscards;
  u32_t ifoutoctets;
  u32_t ifoutucastpkts;
  u32_t ifoutnucastpkts;
  u32_t ifoutdiscards;
#endif /* LWIP_SNMP */
#if LWIP_IGMP
  /* This function could be called to add or delete a entry in the multicast filter table of the ethernet MAC.*/
  err_t (*igmp_mac_filter)( struct netif *netif, struct ip_addr *group, u8_t action);
#endif /* LWIP_IGMP */
#if LWIP_NETIF_HWADDRHINT
  u8_t *addr_hint;
#endif /* LWIP_NETIF_HWADDRHINT */
#if ENABLE_LOOPBACK
  /* List of packets to be queued for ourselves. */
  struct pbuf *loop_first;
  struct pbuf *loop_last;
#if LWIP_LOOPBACK_MAX_PBUFS
  u16_t loop_cnt_current;
#endif /* LWIP_LOOPBACK_MAX_PBUFS */
#endif /* ENABLE_LOOPBACK */
};

相關推薦

結構巨集定義以及函式指標高階寫法結構巨集定義一個函式

一、結構體中可以定義一般的巨集定義 如: struct aaa { #define STATUS_1 100 #define STATUS_2 200 #define STATUS_3 300 ........ }; 首先

“資訊機器人”“商業智“AI”“BI”會有怎樣的火花?

人工智能寫作 人工智能編輯 人工智能采集 新技術的誕生,往往是為了更好的服務人類,而這一過程,則離不開商業。何為商業智能?把企業中現有數據轉化為知識,幫助企業做出明智的業務經營決策的工具。 人工智能誕生後,在1958年,商業智能馬上進入人們的視野。但在過去,商業智能不能給出決策方案,也不能自動處理

光明日報:教育區塊鏈會擦出什麼火花

說起現在最火的新興技術,區塊鏈必是處在風口上的答案之一。日前,京津冀大資料教育區塊鏈試驗區成立,為“區塊鏈+教育”的融合發展之路,提供了一個新的視窗。   當傳統的教育行業與區塊鏈相遇,究竟能為我們帶來什麼?又會擦出怎樣的火花?   推動科研共享和教育可持續發展

【斑馬體育】說多都是淚小個球員巨人球童原來最囧的竟然是TA!

綠茵場上列隊出場、奏響國歌或主題曲的儀式,最讓球員尷尬,又能令現場球迷忍俊不禁,電視機前的觀眾甚至樂得開懷的一幕是什麼?那就是當小個球員遇上巨人球童。 今天凌晨英格蘭和瑞士在皇權球場一戰,原本只是一場普通平常的友誼賽。然而開場一路跟隨攝像機的鏡頭,竟然發現兩隊

知識圖譜文字智慧處理會擦出怎樣的火花?

目前以理解人類語言為入口的認知智慧成為了人工智慧發展的突破點,而知識圖譜則是邁向認知智慧的關鍵要素。達觀資料在2018AIIA人工智慧開發者大會承辦的語言認知智慧與知識圖譜公開課上,三位來自企業和學術領域的專家分別從不同角度講述的知識圖譜的應用和發展。文字根據達觀資料副總裁王文廣演講內容《知識圖

C++-Typedef結構指標

  繼Typedef遇上結構體陣列後,我們又產生了新的疑問。   上一期地址:https://www.cnblogs.com/lemaden/p/10122929.html     昨天一位朋友又問我了,說結構體陣列遇上typedef我懂了,就是陣列擁有三個特性:1.首地址 2.陣列的長度 3. 陣列的步

大資料人工智慧企業轉型需要從基礎能力入手:資料科學平臺kesci科賽網更名為和鯨科技

2019年元旦,資料科學平臺科賽網(Kesci.com)對外宣佈,因公司戰略升級,品牌正式更名為“和鯨科技”。作為資料分析和人工智慧領域的基礎服務公司,科賽網的品牌更新,彷彿給烈火烹油的人工智慧產業添置了一個新柴輸送器。   2015年成立的科賽網,是國內最早的資料科學

基因編輯藝術家CRISPR是否還令人害怕?

會有 圖片 發現 快樂 創業公司 完成 人的 事情 能力 說起 CRISPR 基因編輯技術,大家腦子裏的第一個反應是什麽?可以說不少人是既期待又害怕,但更多的可能是似懂非懂。 矽谷洞察再簡單介紹一下 CRISPR 技術。CRISPR 是存在於細菌中的一種基因組,其中的一些基

餐飲大資料嗯真香!

之前去開了一場會,主題是「餐飲領袖新零售峰會」。認真聽完了餐飲前輩和新秀們的分享,覺得獲益匪淺,把腦子裡的核心紀要整理了一下,今天

.NET 5 OpenTelemetry會碰撞出怎樣的火花?

![](https://blog-1259586045.cos.ap-shanghai.myqcloud.com/clipboard_20210202_055208.png) # OpenTelemetry 介紹 我在之前的幾篇文章都介紹了 OpenTelemetry, 你可以在這裡找到 [OpenTe

小白Linux運維

沒有 最大 多多指教 inux運維 最大的 水平 基礎 都沒有 建議 如果您正準備學習Linux運維,以下是本人對Linux運維的一些看點,希望可以對您有所幫助 一:如果您一點基礎都沒有,首先建議您先

模組化多渠道

本文已授權微信公眾號:鴻洋(hongyangAndroid)在微信公眾號平臺原創首發。 最近在研究Android模組化開發的一些東西, 網上大多數模組化的文章都是僅僅從一個demo的角度去看待的, 其實對於在真實專案中使用還有很多坑需要去踩, 今天就來聊聊我在模組化探索

小樣本機器學習 few shot learning

https://blog.csdn.net/mao_feng/article/details/78939864     [1] G Koch, R Zemel, and R Salakhutdinov. Siamese neural networks for

傳統現代科技大資料和人工智慧的醫療應用【楚才國科】

近年來,人工智慧已經成為熱詞,從製造業、智慧家居、交通,教育到醫療,人工智慧的迅速發展已經不斷在提高人們的生活水平。在多檔科技節目的推動下,如《機智過人》、人工智慧交流群 862729908《我是未來》等等,包括青少年都在關注! 那麼將大資料和人工智慧與我們中醫相結合,這又會擦出怎樣的火花呢

店慶雙11買書的最大優惠來了!

                                          &

程式設計師騙子?

    說起程式設計師,大家肯定都不陌生,隨著社會的不斷髮展,人們的生活水平也在逐漸提高,而許多人都知道程式設計師那也是在網上的技術都很高超,如果見到一些不法分子或者騙子的,那麼會通過一些別的手段來看看騙子到底是什麼人,有的手段讓民警都覺得佩服。

SQL Server 表分割槽唯一約束轉載

一、前言 我已經在高興對伺服器建立了表分割槽並且獲得良好效能和自動化管理分割槽切換的時候,某一天,開發人員告訴我,某表的兩個欄位的資料不唯一,需要為這兩個欄位建立唯一索引的時候,這一切就變得不完美了。列的唯一,這個實際上是一個唯一索引。使用關鍵字unique建立。     二、

虛擬篩選高通量篩選

  新葯研究屬於高科技領域,世界各國對新葯研究的投入逐年增加。據統計,1981年全世界對R&D投入為52億美元,至1996 年已達到450億美元。雖然新葯研究開發的投入逐年增加,但每年上市的新的一類新葯(NCE)卻逐年減少,60年代初期,每年上市的NCE約100 個,1996年

jquery ajax401請求的解決方法

前言 jquery ajax是個很常用介面,而在請求時候,可能存在響應401的情況(身份認證過期或未登入),比較容易出現在混合應用上,如何進行身份認證,重發失敗請求,還是值得注意的。 敘述 一般遇到401的問題,都是因為身份認證不成功的原因,所以我們新增身份認

Unity 2D橫版通關 小遊戲-悟空熊本(Unity 5.6)C#

2D橫版通關小遊戲,美術資源原創自合作美工,這是我學unity遊戲開發做的第一個小demo,學到了很多東西。從什麼都不會到自己上手學習Unity軟體的基本操作  _(:з」∠)_  ,給主角加剛體,碰撞器,標籤,實現主角移動,跳躍,幀合成動畫,發射子彈,特效磚塊,頂一