memset 與 memcpy
1. memset
需要的頭文件 在C中 <string.h>
在C++中 <cstring>
原型:
void *memset(void *s, int ch, size_t n);
用法:
memset是計算機中C/C++語言函數。將s所指向的某一塊內存中的前n個字節的內容全部設置為ch指定的ascii值, 第一個值為指定的內存地址,塊的大小由第三個參數指定,這個函數通常為新申請的內存做初始化工作, 其返回值為指向s的指針。
函數解釋:將s中當前位置後面的n個字節 (typedef unsigned int size_t )用 ch 替換並返回 s 。
memset:作用是在一段內存塊中填充某個給定的值,它是對較大的結構體或數組進行清零操作的一種最快方法。
以我們一開始提出的問題為例:
#include<string.h>
int main(void)
{
int a[5] = {1, 2, 3, 4, 5};
memset(a, 0, sizeof(a));
}
就這樣就成功清零了,是不是很方便。
註意:
如果是字符數組的話,memset可以隨便用,但是如果是其他類型的數組,一般只用來清零,如果是填充數據就不合適了,如:
memset(a, 1, sizeof(a));
想用這個來把a所有元素設置為1,是不成功的,為什麽呢?
因為memset函數每次填充的數據長度為一個字節,即為0x01,而a的一個元素長度為4個字節,即0x00000000,如果把0x01填充進去,則填充的結果是0x01010101,而不是我們期待的0x00000001,所以是不合適的,但是用來清零真是一級棒!
2. memcpy
所需頭文件#include <string.h>
原型:
void *memcpy(void *dest, const void *src, size_t n);
用法:
memcpy函數是內存拷貝函數,功能是從源src所指的內存地址的起始位置開始拷貝n個字節到目標dest所指的內存地址的起始位置中。
因為這個函數是直接操作內存的。
例子1:
1 #include<string.h>
2
3 int main(void)
4 {
5 int a[5] = {1, 2, 3, 4, 5}, b[5];
6 /*第一個參數是要保存的位置的起始地址,所以我們直接放b
7 *第二個參數是源數據的起始地址,所以我們把a放上去
8 *第三個參數是要復制的內存塊的長度,為a的長度sizeof(a)*/
10 memcpy(b, a, sizeof(a));
11 }
就這樣一行的代碼,就能代替我們之前的for循環,是不是簡潔高效了許多。這個函數的作用不僅僅是這樣,它還可以用與兩個字符串的復制,內存塊的復制等,各種數據類型都能復制。
例子2:
#include <stdio.h> #include <string.h> #define BUF1 ("Hello world!") #define BUF2 ("My name is snail!") int main() { char str[512]; memset(str, 0, 512); memcpy(str, BUF1, strlen(BUF1)); printf("str = %s\n", str); memcpy(str + strlen(BUF1), BUF2, strlen(BUF2)); printf("str = %s\n", str); return 0; }
PS:
memcpy用來做內存拷貝,你可以拿它拷貝任何數據類型的對象,可以指定拷貝的數據長度;
例:char a[100],b[50];
memcpy(b, a, sizeof(b));
//註意如用sizeof(a),會造成b的內存地址溢出。
strcpy就只能拷貝字符串了,它遇到‘/0‘就結束拷貝;
例:char a[100],b[50];
strcpy(a,b);
如用strcpy(b,a),要註意a中的字符串長度(第一個‘/0’之前)是否超過50位,如超過,則會造成b的內存地址溢出。
參考: http://www.cnblogs.com/king-ding/p/memset_mencpy.html
http://blog.csdn.net/yf210yf/article/details/9074821
memset 與 memcpy