精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何判斷一段字符串的長度

魚鷹談單片機 ? 來源:魚鷹談單片機 ? 2024-08-12 17:42 ? 次閱讀

來源:公眾號【魚鷹談單片機

作者:魚鷹Osprey

ID :emOsprey

這周課上介紹斷言實現的時候,莫名其妙被斷言的真真假假搞暈了。

起因是看到一段關于判斷一段字符串的長度,使用了 ASSERT 方式,原文大概是這樣寫的:

#define AES256_KEY                      "0123456789ABCDEF0123456789ABCDEF"  /* 必須等于 32 字節 */
#define AES256_IV                       "0123456789ABCDEF"                  /* 必須等于 16 字節 */
extern void Assert_Failed(uint8_t *func, uint32_t line);
#define ASSERT(expr)            ((expr) ? (void)0U : Assert_Failed((uint8_t *)__func__, __LINE__))
voidfunc()
{
  ASSERT(sizeof(AES256_KEY) != 32);
     ASSERT(sizeof(AES256_IV) != 16);
}

一開始總以為這種寫法沒問題,畢竟這么簡單,模擬調試的時候確實也不會報錯(打開了斷言情況下)。

為了課上測試一下靜態編譯報錯的效果,卻發現始終有些問題,不該報錯的時候報錯了。

#define STATIC_ASSERT(...)      extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(__VA_ARGS__)])]

為了方便,魚鷹直接用 MDK 測試了 sizeof 字符串的結果,發現確實也是16(0x10)

285aa6f4-4d44-11ef-b8af-92fbcf53809c.png

然后我就困在了這兩個前提上,STATIC_ASSERT 報錯始終有問題。

#define AES256_KEY                      "0123456789ABCDEF0123456789ABCDEF"  /* 必須等于 32 字節 */
#define AES256_IV                       "0123456789ABCDEF"                  /* 必須等于 16 字節 */
extern void Assert_Failed(uint8_t *func, uint32_t line);
#define ASSERT(expr)            ((expr) ? (void)0U : Assert_Failed((uint8_t *)__func__, __LINE__))


#define STATIC_ASSERT(...)      extern char (*_do_assert(void)) [sizeof(char[1 - 2*!(__VA_ARGS__)])]
void func()
{
     ASSERT(sizeof(AES256_KEY) != 32);
     ASSERT(sizeof(AES256_IV) != 16);
STATIC_ASSERT(sizeof(AES256_IV)!=16);
}

286bd05a-4d44-11ef-b8af-92fbcf53809c.png

調試的時候,STATIC_ASSERT ,但是 ASSERT不報錯

這讓魚鷹百思不得其解,一開始以為兩個宏邏輯相反,不都是邏輯值為假時報錯。

但是通過分析宏發現,都是假的時候報錯。

那肯定哪里分析有問題了。

因為編譯器如果能得到結果為真,ASSERT可能無法形成代碼,即為空(void)0U。

因此魚鷹使用了一個變量作為中間值,強行讓編譯器生成斷言相關的代碼,才算是發現了問題。

void func()
{
uint32_tsize = sizeof(AES256_IV); 

    ASSERT(sizeof(AES256_KEY) != 32);
    ASSERT(size!=16);
    STATIC_ASSERT(sizeof(AES256_IV) != 16);
}

這個size 的值竟然是 17,而不是 16,難怪初始代碼不報錯,17 != 16,當然為真,當然不報錯。

但寫代碼的人是希望這個字符串的長度為始終是16(不包含null的情況下),而明顯代碼中使用sizeof 時計算了 null 的長度。

所以代碼應該這樣寫才對:

void func()
{
ASSERT(sizeof(AES256_KEY)==32);
ASSERT(sizeof(AES256_IV)==16);
STATIC_ASSERT(sizeof(AES256_IV)==16);
}

但是又因為代碼的sizeof 會計算null,因此需要去除這個數:

void func()
{
ASSERT(sizeof(AES256_KEY) - 1==32);
ASSERT(sizeof(AES256_IV) - 1==16);
STATIC_ASSERT(sizeof(AES256_IV) - 1==16);
}

2884bafc-4d44-11ef-b8af-92fbcf53809c.png

這樣 STATIC_ASSERT 可以在編譯階段就可以判斷這個字符串的長度是否符合要求,多一個、少一個字符都不行。

這個坑你們遇到過嗎?

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 字符串
    +關注

    關注

    1

    文章

    577

    瀏覽量

    20488
  • 編譯器
    +關注

    關注

    1

    文章

    1618

    瀏覽量

    49057
  • 編譯
    +關注

    關注

    0

    文章

    654

    瀏覽量

    32813

原文標題:被斷言罷了一道

文章出處:【微信號:emOsprey,微信公眾號:魚鷹談單片機】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    請問各位大神一段只讀亂序字符串能否排序輸出嗎

    請問各位大神一段只讀亂序字符串能否排序輸出嗎
    發表于 05-14 12:45

    Labview之字符串長度函數

    Labview之字符串長度函數,很好的Labview資料,快來下載學習吧。
    發表于 04-19 10:43 ?0次下載

    清華集訓2017模擬之字符串

    一個字符串的權值是這個包含的不同字符個數。 給定長度為n的字符串,把它分為k個連續非空字段
    發表于 11-28 16:33 ?1385次閱讀

    字符串移位包含的問題解決方案

    問題:給定字符串s和t,判斷是否字符串t能通過將s移位后的字符串所包含。 方法 最簡單的方法就是將s進行循環移位,再
    發表于 11-29 10:05 ?1039次閱讀

    教你7個Python判斷字符串是否包含子的方法

    教你7個Python判斷字符串是否包含子的方法
    的頭像 發表于 08-17 10:52 ?5056次閱讀
    教你7個Python<b class='flag-5'>判斷</b><b class='flag-5'>字符串</b>是否包含子<b class='flag-5'>串</b>的方法

    什么是復制字符串?Python如何復制字符串

    連續幾篇文章都在寫 Python 字符串,這出乎我的意料了。但是,有的問題,不寫不行,特別是那種靈機動想到的問題,最后你發現,很多人根本不懂卻又誤以為自己懂了。那就繼續刨根問底,探究個明白吧
    發表于 11-25 10:32 ?2994次閱讀

    C語言總結_字符串全方位練習

    C語言字符串全方位練習,涉及知識點:字符串解析、大小寫判斷字符串插入、字符串刪除、字符串排序、
    的頭像 發表于 08-14 09:41 ?1452次閱讀

    文詳解JavaScript字符串

    JavaScript字符串是原始值。此外,字符串是不可變的。這意味著如果你修改一個字符串,你總是會得到個新的字符串。原始
    的頭像 發表于 12-08 16:36 ?1166次閱讀

    字符串的格式化輸入和輸出

    字符串是內存中一段連續的char空間,以’\0’(數字0)結尾。
    的頭像 發表于 02-24 14:34 ?1335次閱讀
    <b class='flag-5'>字符串</b>的格式化輸入和輸出

    字符串的相關知識

    TCL 中的數據類型只有種:字符串。這些字符串可以是字母、數字、布爾值、標點符號等特殊字符的組合。在某些特殊命令的作用下,字符串可以向其他
    的頭像 發表于 03-29 11:41 ?1102次閱讀

    Python 如何判斷字符串是否包含子

    方法 使用 字符串 對象的 find 方法,如果有找到子,就可以返回指定子字符串中的出現位置,如果沒有找到,就返回 -1 >> > "hello, python" . find
    的頭像 發表于 11-02 10:55 ?471次閱讀

    mysql字符串包含某個字符串

    MySQL是種開源的關系型數據庫管理系統,被廣泛用于構建Web應用程序和其他大型數據驅動的應用。在進行MySQL數據庫查詢時,經常需要使用字符串包含操作,即判斷一個字符串是否包含另
    的頭像 發表于 11-16 14:52 ?3689次閱讀

    python輸出固定長度字符串

    Python 是種強大而靈活的編程語言,具有許多用于處理字符串的功能。在 Python 中,有多種方法可以輸出固定長度字符串。下面將詳細介紹這些方法。 方法
    的頭像 發表于 11-22 10:41 ?3191次閱讀

    oracle判斷字符串包含某個字符

    字符串操作是任何編程語言中都非常重要的部分,Oracle數據庫作為目前最常用的關系型數據庫之,也提供了豐富的字符串操作函數和方法。在本文中,我們將詳細解析如何在Oracle中
    的頭像 發表于 12-06 09:53 ?1.5w次閱讀

    labview中常用的字符串函數有哪些?

    在LabVIEW中,常用的字符串函數廣泛覆蓋了對字符串的各種操作,包括但不限于格式化、搜索、替換、連接、計算長度等。以下是些常用的字符串
    的頭像 發表于 09-04 15:43 ?542次閱讀