網站首頁 編程語言 正文
memset簡介
memset是一個初始化函數,作用是將某一塊內存中的全部設置為指定的值。
void *memset(void *s, int c, size_t n);
- s指向要填充的內存塊。
- c是要被設置的值。
- n是要被設置該值的字符數。
- 返回類型是一個指向存儲區s的指針。
需要說明的幾個地方
一、不能任意賦值
memset函數是按照字節對內存塊進行初始化,所以不能用它將int數組出初始化為0和-1之外的其他值(除非該值高字節和低字節相同)。
其實c的實際范圍應該在0~255,因為memset函數只能取c的后八位給所輸入范圍的每個字節。也就是說無論c多大只有后八位二進制是有效的。
=================================================================================================
對于int a[4];
memset(a, -1, sizeof(a)) 與 memset(a, 511, sizeof(a)) 所賦值的結果一樣都為-1:
因為 -1 的二進制碼為(11111111 11111111 11111111 11111111);511 的二進制碼為(00000000 00000000 00000001 11111111);
后八位均為(11111111),所以數組中的每個字節都被賦值為(11111111)。
注意int占四個字節,例如a[0]的四個字節都被賦值為(11111111),那么a[0](11111111 11111111 11111111 11111111),即a[0] = -1。
二、注意所要賦值的數組的元素類型
先來看兩個例子:
例一:對char類型的數組a初始化,設置元素全為’1’
int main(){
char a[4];
memset(a,'1',4);
for(int i=0; i<4; i++){
cout<<a[i]<<" ";
}
return 0;
}
例二:對int類型的數組a初始化,設置元素值全為1
int main(){
int a[4];
memset(a,1,sizeof(a));
for(int i=0; i<4; i++){
cout<<a[i]<<" ";
}
return 0;
}
1、首先要說明的第一點
?對于第二個程序,數組a是整型的,一般int所占內存空間為4個字節,所以在使用memset賦值時,下面的語句是錯誤的:
int a[4];
memset(a,1,4);
由于memset函數是以字節為單位進行賦值的,所以上述代碼是為數組a的前4個字節進行賦值,那么所得到的執行結果就只能是:
正確的memset語句應為:
memset(a,1,16); //int所占內存為4字節的情況
memset(a,1,sizeof(a));
至于為什么不是預期得到的1,將在下面的第二點進行說明。
當然,不同的機器上int的大小可能不同,所以最好用sizeof()函數。
2、為什么第一個程序可以正確賦值1而第二個不可以?
這就又回到了剛剛說的第一個問題,memset函數中只能取c的后八位賦給每個字節。
- 第一個程序中,數組a是字符型的,字符型占據的內存大小就是1Byte,而memset函數也是以字節為單位進行賦值的,所以輸出正確。
- 第二個程序中,數組a是整型的,整型占據的內存大小為4Byte,而memset函數還是按照字節為單位進行賦值,將1(00000001)賦給每一個字節。那么對于a[0]來說,其值為(00000001 00000001 00000001 00000001),即十進制的16843009。
關于所要賦值的字符數的寫法
先來看一個示例:
#include<bits/stdc++.h>
using namespace std;
void fun1(int a[]){
memset(a,-1,sizeof(a));
}
int main(){
int a[6];
fun1(a);
for(int i=0; i<6; i++){
cout<<a[i]<<" ";
}
return 0;
}
當數組作為參數傳遞時,其傳遞的實際上是一個指針,這個指針指向數組的首地址,如果用sizeof(a)函數得到的只是指針的長度,而不是數組的長度。
解決方案:
在函數中加入數組長度參數,在傳遞前先獲取數組長度,然后將數組長度作為參數傳遞進去。
#include<bits/stdc++.h>
using namespace std;
void fun1(int a[], int len){
memset(a,-1,len);
}
int main(){
int a[6];
int len = sizeof(a);
fun1(a,len);
for(int i=0; i<6; i++){
cout<<a[i]<<" ";
}
return 0;
}
具體用法實例
初始化數組
char str[100];
memset(str,0,100);
清空結構體類型的變量
typedef struct Stu{
char name[20];
int cno;
}Stu;
Stu stu1;
memset(&stu1, 0 ,sizeof(Stu));
Stu stu2[10]; //數組
memset(stu2, 0, sizeof(Stu)*10);
此外,如果結構體中有數組的話還是需要對數組單獨進行初始化處理的。
總結
? memset函數在初始化處理時非常方便,但也有其局限性,比如要注意初始化數值,要注意字節數等等。當然,直接選擇用for循環或while循環來進行初始化也是可以的,只不過memset更快捷一些。
原文鏈接:https://blog.csdn.net/weixin_44162361/article/details/115790452
相關推薦
- 2022-11-02 利用Python+eval函數構建數學表達式計算器_python
- 2024-04-03 clickhouse報Ports are not available
- 2023-01-13 Qt中QList與QLinkedList類的常用方法總結_C 語言
- 2022-07-29 Jetpack?Compose實現列表和動畫效果詳解_Android
- 2022-11-12 Shell實現字符串處理的方法詳解_linux shell
- 2022-07-31 pycharm終端解釋器與Python解釋器配置_python
- 2022-11-03 刪除?Tomcat?webapps?目錄自帶項目方式詳解_Tomcat
- 2023-07-28 el-table 合并單元格(合并行)
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支