平台:stm32f103rct6+mdk
筆者在除錯時發現,結構體不同型別成員的定義順序對於程式執行過程中的取值可能會產生很大的bug
開始時定義:
/***********************輸入引數結構體**********************/
typedef struct inputstruct;
inputstruct inputpara=;
在以上的定義中,編譯無警告無錯誤,程式正常執行,但是在整個程式裡面呼叫的所有float型別資料都不會是定義時候的值!即使有的float資料不是在本結構體變數中定義的,呼叫的值也會異常!而其他的不管是字元型,整型或者列舉型別都不會有錯誤
經過漫長的debug,終於定位問題所在:
將
float pressrange; //壓力範圍 kpa
u8 handtemp; //手工溫度 ℃
交換位置
結構體定義和變數定義修改為:
/***********************輸入引數結構體**********************/
typedef struct inputstruct;
inputstruct inputpara=;
奇怪的是,在另乙個結構體定義中,float的順序並沒有對整個程式造成影響:
debugstruct debugpara=;
對於float變數,記憶體中的儲存方式是以指數方式儲存的,這是浮點數與其他型別資料在記憶體上的儲存區別。所以筆者猜測,在定義結構體時,由於偶爾的一次排序差別導致float資料在記憶體上偏移了n個位元組,mcu在取值時每次都取了錯誤的float資料,導致取值與原本的值有很大差別。
而有時候在定義成員時,由於成員之間的排列順序正好彌補了本該產生的位元組對不齊(如筆者舉的第二個例子)所以會「負負得正」正好沒有出現問題。
由於該問題沒有乙個確切的產生時機,所以在每次出現這種bug時無法精確定位到關鍵所在,目前的辦法是,定義變數時不對變數賦初值,定義好變數之後再對各個成員進行賦初值,這樣不會產生bug:
inputstruct inputpara;
int main(void)
以上這種辦法就可以不考慮結構體成員的排序問題,也不會產生錯誤。 stm32埠初始化
今天上課,點亮數碼管,gpio初始化後,數碼管上有一段亂碼。要讓這亂碼消失掉,需要改變gpio初始化的順序。在gpio埠使能後,要加odr 埠暫存器 控制 gpio inittypedef gpio initstructure 定義乙個結構體 rcc apb2periphclockcmd rcc a...
結構體變數初始化
main.c c語言學習 include int main int argc,const charchar argv 初始化的4種方式 1.定義的同時初始化 struct person p1 2.先定義再逐個初始化 struct person p2 p2.name ykd p2.age 18 p2....
go結構體初始化 Go語言初始化結構體的成員變數
結構體在例項化時可以直接對成員變數進行初始化,初始化有兩種形式分別是以字段 鍵值對 形式和多個值的列表形式,鍵值對形式的初始化適合選擇性填充欄位較多的結構體,多個值的列表形式適合填充欄位較少的結構體。使用 鍵值對 初始化結構體 結構體可以使用 鍵值對 key value pair 初始化字段,每個 ...