同事用void把我给秀翻了!
1、聊一聊
今天跟大家推薦的這首歌最近應該挺火的,不過沒辦法插入AGA的原版歌曲,大家覺得不錯可以去找找原版歌曲收錄一下。
昨天建立了"最后一個bug"技術交流群,由于群成員超過200就無法直接通過群二維碼加入,如果大家想加入掃描下面作者的個人微信號然后拉你入群。
2、簡單認識一下void
今天跟大家介紹的知識是C語言中的void關鍵字的用法,void在大部分小伙伴的程序中都只是用于函數無參數傳入,或者無類型返回。
然而我們平時所定義的變量都會有具體的類型,int,float,char等等,那是否有void類型的變量呢?大家可以動手實驗一下,答案是:不行,編譯會出錯。
上圖很明顯編譯器不允許定義void類型的變量,變量都是需要占用一定內存的,既然void表示無類型,編譯器自然也就不知道該為其分配多大的內存,于是造成編譯失敗。
雖然void不能直接修飾變量,但是其可以用于修飾指針的指向即無類型指針void*,無類型指針那就有意義了,無類型指針不是一定要指向無類型數據,而是可以指向任意類型的數據。
3、void * 基本操作?
大家其實在使用動態內存分配的使用就已經遇到了void *的使用,來我們一起看看如下幾個標準函數的原型定義:
? ??
上面這些函數都是與內存操作有關的函數,可能一些小伙伴使用過也不一定知道每個參數的具體類型是什么,這些void*部分的形參所傳入的實參都是不需要進行強制類型轉化的,所以根本就不需要關注傳入指針所指向的具體類型,然而函數所返回的void *一般都需要通過強制類型轉化為對應的具體類型,除非你最后所傳遞的變量也是void*類型。
參考void*用法:
1#include?<stdio.h>2#include?<stdlib.h>3#include?<malloc.h>?45#define?NUM?106/*************************************7?*?Fuction:了解一下void*的使用?8?*?Author?:?(公眾號:最后一個bug)?9?*************************************/ 10int?main(int?argc,?char?*argv[])?{ 11????int?*p1?=?(int?*)malloc(NUM*sizeof(int));? 12????int?*p2?=?(int?*)malloc(NUM*sizeof(int));? 13????int??i?=?0; 14 15????//初始化p1? 16????for(i?=?0;i?<?NUM;i++)? 17????{ 18????????*(p1+i)?=?i; 19????} 20????//進行內存copy? 21????memcpy(p2,p1,NUM*sizeof(int)); 22 23????//輸出另外一個分配的內存? 24????for(i?=?0;i?<?NUM;i++)? 25????{ 26???????printf("%d,",*(p2+i));? 27????}??? 28????//釋放內存? 29????free(p1); 30????free(p2); 31????return?0; 32}運行結果:
4、使用void * 實現無類型數據封裝
為了保持文章的完整性,也許這里才是作者最想跟大家介紹的,void*既然如此的靈活一定大有用處,如果僅僅只是用來簡單的傳遞參數似乎有點大材小用,我們得把其用到上層的軟件設計上來。
在一些項目中經常看到有小伙伴把數據類型轉來轉去,甚至有時候為了一個數據類型的變化還得重新寫一個僅僅數據類型不同的函數,這樣的代碼上萬行代碼指日可待,按下面我們以一個例子來跟大家介紹一種辦法能夠減少數據類型變化所帶來的程序重復代碼的增加。
參考實例:
1#include?<stdio.h>2#include?<stdlib.h>3/**********************************?4?*?Fuction?:?add5?*?descir?:??加法的相關數據及處理辦法?6?*?Author?:?(公眾號:最后一個bug)7?**********************************/?8typedef?struct?_tag_Add9{ 10????int?a; 11????int?b; 12????int?result; 13}sAdd; 14 15void?Add(void?*param) 16{ 17????sAdd?*p?=?(sAdd?*)?param; 18????p->result?=?p->a?+?p->b; 19} 20/**********************************? 21?*?Fuction?:?add 22?*?descir?:??乘法的相關數據及處理辦法? 23?*?Author?:?(公眾號:最后一個bug) 24?**********************************/? 25typedef?struct?_tag_Mul 26{ 27????float?a; 28????float?b; 29????float?result; 30}sMul; 31 32void?Mul(void?*param) 33{ 34????sMul?*p?=?(sMul?*)?param; 35????p->result?=?p->a?*?p->b; 36} 37 38/*************************************? 39?*?Fuction?:?sCal 40?*?descir?:??公共的調用接口? 41?*?Author?:?(公眾號:最后一個bug) 42?************************************/? 43void?sCal(void?*param,void?*fuc) 44{ 45????((void?(*)(void*))fuc)(param); 46} 47 48/**********************************? 49?*?Fuction?:?main 50?*?descir?:?應用接口實例? 51?*?Author?:?(公眾號:最后一個bug) 52?**********************************/?? 53int?main(void) 54{ 55????sAdd?stAdd; 56????sMul?stMul; 57 58????//數據初始化? 59????stAdd.a?=?10; 60????stAdd.b?=?20; 61 62????stMul.a?=?5; 63????stMul.b?=?5; 64????//接口直接用? 65????sCal(&stAdd,Add); 66????sCal(&stMul,Mul); 67????//對應的輸出? 68????printf("a?+?b?=?%d\n",stAdd.result); 69????printf("a?*?b?=?%f\n",stMul.result); 70????printf("公眾號:最后一個bug\n"); 71????return?0; 72?}?運行結果:
分析一下:
上面的例子可能還是無法完全彰顯void*的強悍之處了,不過其主要的作用就是為了隱藏數據類型,大家也可以理解為一種數據類型的抽象處理,這也是面向對象編程的一種體現。
4、最后小結
對于void這個關鍵字的使用bug菌就先講這么多吧!大家一定要記得對于一些編程技巧一定要嘗試著去使用,可能達到項目目標的方式有很多種,但是一些好的設計不僅僅會讓你的代碼增色不少,同時也會讓同事們覺得你是一個喜歡專研技術的人。
推薦閱讀:
專輯|Linux文章匯總
專輯|程序人生
專輯|C語言
我的知識小密圈
關注公眾號,后臺回復「1024」獲取學習資料網盤鏈接。
歡迎點贊,關注,轉發,在看,您的每一次鼓勵,我都將銘記于心~
總結
以上是生活随笔為你收集整理的同事用void把我给秀翻了!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: IAR 8.3 for Arm 安装与注
- 下一篇: KNN算法实现knn完成iris数据集分