欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++ memset方法的誤區(qū)

 更新時(shí)間:2021年04月15日 09:05:17   作者:李春港  
memset 作為對(duì)內(nèi)存初始化的函數(shù),還是有不少坑和誤區(qū)的,今天就來(lái)對(duì)這個(gè)函數(shù)作一個(gè)總結(jié)。避免后期使用不當(dāng)踩入坑,需要的朋友可以參考下

一、函數(shù)作用

最簡(jiǎn)單的調(diào)用就是將一個(gè)數(shù)組清零,代碼如下:

const int maxn = 1024;
int a[maxn];
memset(a, 0, sizeof(a)); // 結(jié)果:a[0]=a[1]=a[...]=0;
  • 這里 sizeof(a) = maxn * 4 = 4096;
  • 表示的是將數(shù)組首地址 a 開(kāi)始往后的 4096 個(gè)字節(jié),都設(shè)置為 0;

二、效率對(duì)比

直接調(diào)用 memset 接口清零 和 調(diào)用循環(huán)進(jìn)行清零,進(jìn)行一個(gè)測(cè)試后如下:

對(duì)長(zhǎng)度為 10000000 的數(shù)組,執(zhí)行100次調(diào)用;

模式 memset for
debug 375ms 2156ms
release 343ms 329ms

  • 因?yàn)?release 版本會(huì)做各種優(yōu)化,編譯器發(fā)現(xiàn)重復(fù)執(zhí)行無(wú)效邏輯就會(huì)跳過(guò),所以不太好造數(shù)據(jù)測(cè)試,研究時(shí)間效率的時(shí)候還是參考 debug 版本(當(dāng)然,軟件發(fā)布的時(shí)候肯定用的是 release 版本)。
  • memset 無(wú)論從時(shí)間效率,還是代碼整潔來(lái)看都是由于 for 循環(huán)的,當(dāng)然也帶來(lái)了一些容易引起誤解的地方。

三、誤區(qū)總結(jié)

1、按字節(jié)設(shè)置

memset 實(shí)現(xiàn)原理是根據(jù)字節(jié)來(lái)設(shè)置的,比如對(duì)于字節(jié)數(shù)組char a[100],將所有字節(jié)都設(shè)置為5,就可以調(diào)用:

memset(a, 5, sizeof(a));

但是,對(duì)于int b[100],也采用這種方法,就會(huì)導(dǎo)致錯(cuò)誤:

memset(b, 5, sizeof(b));
  • 得到 b 數(shù)組中元素的值為 84215045;
  • 為什么呢?
  • 我們把這個(gè)數(shù)組轉(zhuǎn)換成二進(jìn)制,得到:
  • ( 00000101 00000101 00000101 00000101 ) 2 (00000101 \ 0000 0101 \ 0000 0101 \ 0000 0101)_2 (00000101  00000101  00000101  00000101)2
  • 因?yàn)?i n t int int 占據(jù)了 4 4 4 個(gè)字節(jié),把每個(gè)字節(jié)都設(shè)置成了5,所以最后轉(zhuǎn)成十進(jìn)制就變成了 84215045;
  • 同理,當(dāng)類型是 short(二字節(jié)整數(shù)),或者 long long(八字節(jié)整數(shù))都會(huì)有類似問(wèn)題,總結(jié)表格如下:

總結(jié)表格如下:

 

memset值 char short int long long
0 0 0 0 0
-1 -1 -1 -1 -1
5 5 1285 84215045 361700864190383365

  • 表格中,只有0 和 -1是正常的,因?yàn)?0 的二進(jìn)制表示中,所有位都為0;-1 的二進(jìn)制表示中,所有位都為 1;
  • 特別的,當(dāng)需要設(shè)置的數(shù),對(duì)應(yīng)類型的每個(gè)字節(jié)都是同一個(gè)數(shù)的時(shí)候,也可以采用 memset,比如:int 類型的 252645135(十六進(jìn)制表示為:0x0f0f0f0f);

2、設(shè)置的值只有最低字節(jié)有效

memset(a, 0x05ffffff, sizeof(a));
memset(a, 0xffffff05, sizeof(a));
memset(a, 0xffffff08, sizeof(a));
memset(a, 0x12345678, sizeof(a));

設(shè)置值的時(shí)候,只會(huì)采用最低的字節(jié)作為賦值用,通俗的講,就是以上四句話調(diào)用,等價(jià)于:

memset(a, 0xff, sizeof(a));
memset(a, 0x05, sizeof(a));
memset(a, 0x08, sizeof(a));
memset(a, 0x78, sizeof(a));

3、堆內(nèi)存不可直接 sizeof 取首地址

在堆上申請(qǐng)了一個(gè)數(shù)組空間,并且想要給它初始化,調(diào)用如下:

const int maxn = 1024;
int *p = new [maxn];
memset(p, 0, sizeof(p));
  • 這里進(jìn)入了另一個(gè)誤區(qū),因?yàn)?p p p 在這里雖然是數(shù)組首地址,但是它扮演的角色更多的,其實(shí)是個(gè)指針,所以在進(jìn)行 sizeof 運(yùn)算符操作的時(shí)候,取得的值并不是 4096,而是指針的大?。?/li>
  • 32位機(jī)子上,指針大小為4,;64位機(jī)子上,指針大小為 8;
  • 正確做法是:
const int maxn = 1024;
int *p = new [maxn];
memset(p, 0, maxn * sizeof(int));

4、傳參數(shù)組不可直接 sizeof 取首地址

對(duì)傳參為數(shù)組的數(shù)據(jù)進(jìn)行 memset,調(diào)用如下:

void fun(int a[maxn])
{    
    memset(a, 0, sizeof(a));
}
  • 這里調(diào)用同樣是錯(cuò)誤的,因?yàn)楫?dāng)數(shù)組作為傳參的時(shí)候,這里的 a 已經(jīng)退化為指針,所以同樣不能用 sizeof 數(shù)組首地址來(lái)取大?。?/li>
  • 正確做法是:
void fun(int a[maxn]) 
{    
    memset(a, 0, maxn * sizeof(int));
}

當(dāng)然,當(dāng)傳參是結(jié)構(gòu)體指針的時(shí)候也是如此;

參考于:CSDN-英雄哪里出來(lái)https://blog.csdn.net/WhereIsHeroFrom/article/details/111660632

到此這篇關(guān)于C/C++ memset方法的誤區(qū)的文章就介紹到這了,更多相關(guān)C++ memset方法內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • C語(yǔ)言與C++中const的用法對(duì)比

    C語(yǔ)言與C++中const的用法對(duì)比

    C語(yǔ)言中的const與C++有很大的不同,在C語(yǔ)言中用const修飾的變量仍是一個(gè)變量,表示這個(gè)變量是只讀的,不可顯示地更改,而在C++中用const修飾過(guò)后,就變成常量了
    2022-04-04
  • C語(yǔ)言 深入探究動(dòng)態(tài)規(guī)劃之區(qū)間DP

    C語(yǔ)言 深入探究動(dòng)態(tài)規(guī)劃之區(qū)間DP

    這幾天在做有關(guān)dp的題,看到一個(gè)石子合并的問(wèn)題,本來(lái)以為是個(gè)貪心,后來(lái)仔細(xì)一想壓根不是貪心。貪心算法的思路是每次都取最大的,然而石子合并問(wèn)題有個(gè)限制條件就是每次只能取相鄰的,這就決定了它不是個(gè)貪心
    2022-04-04
  • C++ Boost Thread線程使用示例詳解

    C++ Boost Thread線程使用示例詳解

    Boost是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱。Boost庫(kù)是一個(gè)可移植、提供源代碼的C++庫(kù),作為標(biāo)準(zhǔn)庫(kù)的后備,是C++標(biāo)準(zhǔn)化進(jìn)程的開(kāi)發(fā)引擎之一,是為C++語(yǔ)言標(biāo)準(zhǔn)庫(kù)提供擴(kuò)展的一些C++程序庫(kù)的總稱
    2022-11-11
  • 如何基于 Blueprint 在游戲中創(chuàng)建實(shí)時(shí)音視頻功能

    如何基于 Blueprint 在游戲中創(chuàng)建實(shí)時(shí)音視頻功能

    我們?cè)诒疚南葋?lái)講講如何在 Unreal 中用 Blueprint 快速實(shí)現(xiàn)。稍后會(huì)分享基于 C++的實(shí)現(xiàn)步驟。感興趣的朋友跟隨小編一起看看吧
    2020-05-05
  • C++獲取類的成員函數(shù)的函數(shù)指針詳解及實(shí)例代碼

    C++獲取類的成員函數(shù)的函數(shù)指針詳解及實(shí)例代碼

    這篇文章主要介紹了C++獲取類的成員函數(shù)的函數(shù)指針詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • C++運(yùn)算符重載限制介紹

    C++運(yùn)算符重載限制介紹

    這篇文章主要介紹了C++運(yùn)算符重載限制,關(guān)于運(yùn)算符的重載并不是隨心所欲的。C++給出了一些限制,從而保證了規(guī)范,以及程序運(yùn)行的準(zhǔn)確性,下面來(lái)了解C++運(yùn)算符重載限制的詳細(xì)內(nèi)容吧,需要的朋友也可以參考一下
    2022-01-01
  • C語(yǔ)言求兩個(gè)字符串的最長(zhǎng)公共子串

    C語(yǔ)言求兩個(gè)字符串的最長(zhǎng)公共子串

    這篇文章主要介紹了C語(yǔ)言求兩個(gè)字符串的最長(zhǎng)公共子串,實(shí)例分析了C語(yǔ)言操作字符串的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下
    2015-02-02
  • C語(yǔ)言實(shí)現(xiàn)九大排序算法的實(shí)例代碼

    C語(yǔ)言實(shí)現(xiàn)九大排序算法的實(shí)例代碼

    這篇文章主要給大家介紹了關(guān)于C語(yǔ)言實(shí)現(xiàn)九大排序算法的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-01-01
  • C語(yǔ)言字符串左旋的兩種實(shí)現(xiàn)方法

    C語(yǔ)言字符串左旋的兩種實(shí)現(xiàn)方法

    匯編語(yǔ)言中有一種移位指令叫做循環(huán)左移(ROL),下面這篇文章主要給大家介紹了關(guān)于C語(yǔ)言字符串左旋的兩種實(shí)現(xiàn)方法,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2023-02-02
  • C++ 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)(前序/中序/后序遞歸、非遞歸遍歷)

    C++ 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)(前序/中序/后序遞歸、非遞歸遍歷)

    這篇文章主要介紹了C++ 數(shù)據(jù)結(jié)構(gòu)二叉樹(shù)(前序/中序/后序遞歸、非遞歸遍歷)的相關(guān)資料,這里提供實(shí)例代碼來(lái)幫助大家理解掌握二叉樹(shù),需要的朋友可以參考下
    2017-07-07

最新評(píng)論