本人有關C語言中結構體一點不簡單的理解

2021-10-08 16:24:51 字數 3419 閱讀 2483

在將結構體之前,首先咱們還得嘮嘮指標這個東西

如果你只是簡單地會呼叫個函式啊什麼的,那程式的執行過程中的資料運算對你來說就如同是乙個黑盒子,借一句古語 「知其然也,而不知其所以然也」 ,特別是對於mcu這樣的精準控制暫存器的東西,這種現象是極其致命的。

舉個栗子,你有一大串的數字,你肯定不會每次都直接呼叫這個一大串的數字,這不現實,相信也沒有人會蠢得這麼做,一般情況下,我們都是先定義乙個變數名, 如:int a;隨後,給這個 a 賦值,a = 12345;

其實,在這句話裡面,a就代表乙個指標;ok,既然他是 指 針,那他指向的是什麼?答案就是12345

emmmmm,象徵點說,a就相當於乙個小房子,房子裡面放著什麼呢,自然是放著12345這個數字。

懂了這個,我們就可以更深入一點了,假如說,我定義了乙個變數,但是這個變數的型別有點特殊:int* 型別變數,而且,這個變數的數字也有點特殊:int* b = &a;

這就有點糊塗了吧,其實倒也不難理解,* 在c語言中就表示這是乙個指標,而&在c語言中是取位址的意思(表示我要將與我緊挨著的變數名位址取出來);專業一點來說就是:我要定義乙個int型別的乙個指標變數b,這個b裡面放的是a的位址。

上邊說到,a是乙個小房子,那既然有房子,肯定會有門牌號,int* b = &a的意思就是將a這個房子的門牌號取出來,然後,告訴給b。

在程式運算的時候,mcu執行到b這裡,結果發現b只是乙個位址名(指標型變數),mcu是乙個比較死板的東西,既然這是乙個位址,那我肯定得按照位址來繼續找下去;於是,按照位址,mcu就找到了a在哪,緊接著,就獲取到了12345這個數字。

假如說,我的程式中需要很多相類似的資料,那我們需要怎麼做?申請好多個變數,然後給變數乙個乙個的賦值?然後乙個乙個的使用?

no no no,我們有乙個很簡單快捷的方式——陣列;我們使用他就可以在同一時刻中創造很多很多的變數元素,並且借助迴圈語句(for while)來使用。

如:int c [ 5 ] = 0; 在這一句程式中,我不僅可以同時建立5個變數(c[0],c[1],c[2],c[3],c[4]①),並且把這5個變數設定為0。

怎麼理解呢?你可以把c這個陣列看成是一棟大樓,c就是這個大樓的名稱;大樓內部肯定有很多層吧;那麼在定義這個陣列的時候,[ 5 ] 就代表這棟名字叫做c的大樓有5層這麼高;這棟樓的第一層,正常咱們的叫法就是c大樓第一層,而在c語言中,c[ 0 ]就代表這個大樓的第一層,即c這個陣列的第乙個元素,c [ 1 ]就代表第二層,代表第二個元素;

(c語言定義以0為起始)②

c語言中,陣列之間的成員在記憶體中的儲存位址是連續的,假如c [ 0 ] 的位址為0x00000000,那麼 c [ 1 ] 的位址就為0x00000000 + 4 = 0x00000004(位址數值相加值根據編譯器決定)③;

注意:

① c語言中,定義乙個陣列的時候,[ ]內的數字代表這個陣列中有多少個成員,其成員名稱最小為 c [ 0 ] ,最大為 c [ 這個數字 - 1的值 ]。

② 還有乙個要點,在c語言中,&c 只會取到c [ 0 ] 的位址,只有 &c [ 3 ] 才會真正的獲取到 c [ 3 ] 的位址。

③ 依據程式編譯器的不同,int定義的位元組數不同。(資料占用記憶體儲器的大小不同);常用的微控制器編譯器,如keil下,51類微控制器的c語言中,int代表2個位元組(16位);如果是32位ram處理器的c語言中,則int代表4個位元組(32位);pic微控制器的picc中8位系列微控制器的c語言裡int表示2個位元組(16位);而不少pc端軟體的編譯器則會根據作業系統或處理器(如64位xp)把int定義為8位元組(64位)。

//c語言給陣列各個元素賦值的簡單方式

//使用for迴圈賦值

for(int num =

0;num < 陣列元素個數;num ++) c[ num ]=0

;//while語句進行賦值

int num =

0;while(num < 陣列元素個數)

//do while語句進行賦值

int num =

0;do

while(num < 陣列元素個數)

現在,明白了指標是什麼,也明白陣列是什麼後,可以很簡單的聊一下結構體了。瞎幾把扯了一大通,終於返回正題了

使用結構體的好處就是可以精簡**結構,特別是在乙個函式的輸入引數較多的狀態下,舉個栗子,stm32的dma的配置:

void

dma1_init

(void

)

想想吧,如果不使用結構體,那真的會是乙個**災難,同時輸入好幾個引數,**的可讀性極其低下。

首先,在mcu程式設計中,定義結構體最主要需要用到兩個關鍵字struct&typedef,這兩個字的用法也很簡單,struct表示結構體,而typedef表示重新定義。

以stm32的gpio初始化結構體為例:

typedef

struct

gpio_inittypedef;

這一串**表示了我使用typedef重新定義了乙個struct型別的結構體,這個新的結構體的名字叫做gpio_inittypedef(類似經常使用的typedef unsigned int u32;這個**),而這個新結構體中的成員有三個,分別是gpio_pin,gpio_speed,gpio_mode;這個重定義結構體的具體使用方法可以參考gpio初始化函式:

void

gpioc_init()

在了解到stm32庫函式中結構體的用法後,懵懵懂懂的對結構體有了一點了解。

假設,我需要乙個結構體,這個結構體的,名字叫做s,這個s裡面三個int型別的引數,x,y,z(當然,你也可以放置其他型別的引數 ①)。

按照stm32的庫檔案的做法,那麼我就可以這樣做:

//方法1

typedef

struct

s;

這段**的通俗一點講就是,我建立了乙個村子,村子這個概念就是s,然後這個村子裡面只有三個住戶,x,y,z;假如說,我想要去z的家裡拿東西或者放東西,那我首先需要知道村子的名稱,然後,我得知道z的位址,然後,我才能在z的家裡訪問東西。
//方法1的賦值方式

s s_1; //假如說需要使用s型別的結構體,那麼,我需要使用s來建立乙個名為s_1的變數,裡面包含x,y,z,然後再對z賦值

s_1.z =

2;

ok,這樣就不難理解了吧,

比較專業一點的講解可以參考c語言結構體詳解裡面的內容。

如果各位博友覺得不錯,請三連支援一下。。

關於C語言結構體偏移的一點思考

相信大家在c語言程式開發的過程一定都使用過結構體,那麼不知你對結構體中成員變數偏移這塊是如何理解的?本文將和大家一起分享下,本人最近關於c語言中結構體偏移的一些思考和總結。另外這篇博文還可以幫你更好的理解這個問題c語言中兩種巨集定義的區別,關於這個思考有哪些方面的意義,細心的你可能發現本文所屬的類別...

C語言中關於巨集定義的一點總結

1 常見的巨集定義語句有不帶引數的巨集定義和帶引數的巨集定義兩種 2 帶引數的巨集定義,在比較複雜時,往往通過 字元進行換行分割,來使其更加清晰。比如 include include define func a,b printf the add of a and b is d n a b int m...

C語言中關於巨集 的使用,注意一點

文章 首先已知 define a hello define b world 如何使用巨集a,b表示出字串 helloworld 答案1 define c a b 答案2 define c a,b a b define c a,b c a,b 答案1驗證 例如使用巨集預編譯案例 include def...