|
關(guān)注+星標(biāo)公眾號(hào),不錯(cuò)過精彩內(nèi)容來源 | typedef
嵌入式編程時(shí),結(jié)構(gòu)體是我們常用的一種語法,今天就來聊聊C語言如何判斷結(jié)構(gòu)體相等?
編程中結(jié)構(gòu)體的重要性今天咱們來聊聊C語言里的結(jié)構(gòu)體。這玩意兒就像是搭積木,能把你想要的各種數(shù)據(jù)類型一塊兒湊起來,變成一個(gè)有意義的“小團(tuán)伙”。如果你還沒搞懂結(jié)構(gòu)體,那就趕緊翻翻我之前的文章吧!C語言結(jié)構(gòu)體(struct)用法詳解
說到比較兩個(gè)結(jié)構(gòu)體,咱們常用的辦法有兩種:逐個(gè)成員比一比,或者用memcmp來個(gè)大掃蕩。接下來,就讓咱們?cè)敿?xì)瞅瞅這兩種辦法咋實(shí)現(xiàn)的,還有它們的小毛病。
逐成員比較逐個(gè)成員比較,這法子簡(jiǎn)單又好用。比如說有這么一個(gè)結(jié)構(gòu)體,里面有 int、float、指針類型的數(shù)據(jù),咱們來看看怎么挨個(gè)比一比:
#include
#include
#include
#include
typedef struct {
int a;
float b;
char *d;
} MyStruct;
#define EPSILON 0.000001
bool FloatsIsEqual(float f1, float f2) {
return fabs(f1 - f2) bool compareStructs(MyStruct s1, MyStruct s2) {
if (s1.a != s2.a) return false;
if (!FloatsIsEqual(s1.b, s2.b)) return false;
if (strcmp(s1.d, s2.d) != 0) return false;
return true;
}
int main() {
MyStruct s1 = {520, 2.5f, "typedef"};
MyStruct s2 = {520, 2.5f, "typedef"};
if (compareStructs(s1, s2)) {
printf("Structures are equal");
} else {
printf("Structures are not equal");
}
return 0;
}
memcmp比較memcmp 是C庫(kù)函數(shù),用于比較兩個(gè)內(nèi)存塊的前 n 個(gè)字節(jié)。其函數(shù)原型為:
int memcmp(const void *str1, const void *str2, size_t n)
參數(shù)str1 -- 指向內(nèi)存塊的指針。str2 -- 指向內(nèi)存塊的指針。n -- 要被比較的字節(jié)數(shù)。返回值如果返回值 如果返回值 > 0,則表示 str1 大于 str2。如果返回值 = 0,則表示 str1 等于 str2。不過,用memcmp的時(shí)候可得小心:
結(jié)構(gòu)體對(duì)齊:由于結(jié)構(gòu)體可能存在內(nèi)存對(duì)齊的情況,會(huì)填充一些字節(jié),此時(shí)直接使用 memcmp 可能會(huì)得到錯(cuò)誤的結(jié)果。浮點(diǎn)數(shù)比較:浮點(diǎn)數(shù)的存儲(chǔ)方式特殊,直接使用 memcmp 比較可能會(huì)導(dǎo)致不準(zhǔn)確的結(jié)果。反面教材在這里我我親身經(jīng)歷的Bug,有一段代碼是通過逐成員方式比較兩個(gè)結(jié)構(gòu)體是否相等的,然后我就耍小聰明改為使用 memcmp 的方式,結(jié)果不出意外的情況下還是出現(xiàn)了意外。
以下是一個(gè)示例,展示了使用 memcmp 比較包含正零和負(fù)零的兩個(gè)結(jié)構(gòu)體變量:
#include
#include
typedef struct {
float value;
}FloatStruct;
int main() {
FloatStruct s1 = {0.0f}; // 正零
FloatStruct s2 = {-0.0f}; // 負(fù)零
if (memcmp(&s1, &s2, sizeof(FloatStruct)) == 0) {
printf("Structures are equal");
} else {
printf("Structures are not equal");
}
return 0;
}
雖然兩個(gè)結(jié)構(gòu)體成員在數(shù)值上是相等的,兩者都是0,但是在存儲(chǔ)格式中的符號(hào)位卻不相同,從而存儲(chǔ)在在內(nèi)存中的數(shù)據(jù)不同,所以判斷為兩個(gè)結(jié)構(gòu)體不相等,跟我們期待的結(jié)果相悖。
總結(jié)要是結(jié)構(gòu)體里有浮點(diǎn)型數(shù)據(jù)或者指針類型的數(shù)據(jù),咱們就用逐個(gè)成員比較的辦法,簡(jiǎn)單好用。要是就一些簡(jiǎn)單的整形數(shù)據(jù),使用memcmp也能偷偷懶。
為了程序的可擴(kuò)展性,還是建議使用逐一成員比較。
聲明:本文素材來源網(wǎng)絡(luò),版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請(qǐng)與我聯(lián)系刪除。------------ END ------------
c3bagmdh0jz64012511801.gif (71.87 KB, 下載次數(shù): 1)
下載附件
保存到相冊(cè)
c3bagmdh0jz64012511801.gif
2024-11-23 07:08 上傳
●專欄《嵌入式工具》
●專欄《嵌入式開發(fā)》
●專欄《Keil教程》
●嵌入式專欄精選教程
關(guān)注公眾號(hào)回復(fù)“加群”按規(guī)則加入技術(shù)交流群,回復(fù)“1024”查看更多內(nèi)容。
點(diǎn)擊“閱讀原文”查看更多分享。 |
|