電子產(chǎn)業(yè)一站式賦能平臺

PCB聯(lián)盟網(wǎng)

搜索
查看: 21|回復(fù): 0
收起左側(cè)

C語言如何判斷結(jié)構(gòu)體相等?

[復(fù)制鏈接]

359

主題

359

帖子

3318

積分

四級會員

Rank: 4

積分
3318
跳轉(zhuǎn)到指定樓層
樓主
關(guān)注+星標(biā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è)大掃蕩。接下來,就讓咱們詳細(xì)瞅瞅這兩種辦法咋實(shí)現(xiàn)的,還有它們的小毛病。
逐成員比較逐個(gè)成員比較,這法子簡單又好用。比如說有這么一個(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庫函數(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)體對齊:由于結(jié)構(gòu)體可能存在內(nèi)存對齊的情況,會填充一些字節(jié),此時(shí)直接使用 memcmp 可能會得到錯(cuò)誤的結(jié)果。
  • 浮點(diǎn)數(shù)比較:浮點(diǎn)數(shù)的存儲方式特殊,直接使用 memcmp 比較可能會導(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,但是在存儲格式中的符號位卻不相同,從而存儲在在內(nèi)存中的數(shù)據(jù)不同,所以判斷為兩個(gè)結(jié)構(gòu)體不相等,跟我們期待的結(jié)果相悖。
    總結(jié)要是結(jié)構(gòu)體里有浮點(diǎn)型數(shù)據(jù)或者指針類型的數(shù)據(jù),咱們就用逐個(gè)成員比較的辦法,簡單好用。要是就一些簡單的整形數(shù)據(jù),使用memcmp也能偷偷懶。
    為了程序的可擴(kuò)展性,還是建議使用逐一成員比較。
    聲明:本文素材來源網(wǎng)絡(luò),版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請與我聯(lián)系刪除。------------ END ------------



    ●專欄《嵌入式工具
    ●專欄《嵌入式開發(fā)》
    ●專欄《Keil教程》
    ●嵌入式專欄精選教程

    關(guān)注公眾號回復(fù)“加群”按規(guī)則加入技術(shù)交流群,回復(fù)“1024”查看更多內(nèi)容。
    點(diǎn)擊“閱讀原文”查看更多分享。
  • 發(fā)表回復(fù)

    您需要登錄后才可以回帖 登錄 | 立即注冊

    本版積分規(guī)則


    聯(lián)系客服 關(guān)注微信 下載APP 返回頂部 返回列表