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

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

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

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

[復(fù)制鏈接]

418

主題

418

帖子

4293

積分

四級(jí)會(huì)員

Rank: 4

積分
4293
跳轉(zhuǎn)到指定樓層
樓主
發(fā)表于 2024-11-21 11:52:00 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
關(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 ------------



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

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

    本版積分規(guī)則


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