memset

将buffer所指的内存区域的前count个字节用字符ch替换,对于较大的结构体或者数组清零是个不错的操作

#include <string.h>

void *memset(void *s, int ch, size_t count);

实际上作用就是在一段内存块中填充某个给定的值,比如下面小例子:

#include <stdio.h>
#include <string.h>

#define MAXSIZE 5

int main(){
    char buffer[MAXSIZE] = "hi";
    memset(buffer, '1', sizeof(buffer));
    printf("%s\n", buffer);
    return 0;
}
[lihui@localhost ~]$ ./a.out 
11111

从这个小例子首先可以看出sizeof和strlen的差别,一个是数据类型,数据所占内存的字节数,一个是字符串的长度

这里buffer是字符数组,每一个字符都占1字节,正好memset也是按字节来进行赋值,因而能正常输出;下面这个例子就不行了:

#include <stdio.h>
#include <string.h>

#define MAXSIZE 5

int main(){
    int buffer[MAXSIZE];
    memset(buffer, 1, sizeof(buffer));
    int i;
    for (i = 0; i < MAXSIZE; i++)
        printf("%d", buffer[i]);
    printf("\n");
    return 0;
}
[lihui@localhost ~]$ ./a.out 
1684300916843009168430091684300916843009

首先瞄了下,奇形怪状,由5个16843009组成

这里的buffer是整型数组,可memset依旧按字节赋值,这里的memset(buffer, 1, 20)会对buffer指向的内存20个字节进行赋值,每个字节都用ASCII为1的字符来填充,转换成二进制1就是00000001,占一个字节,而一个整型int占了4个字节,合在一起就是00000001 00000001 00000001 00000001,转换成16进制就是0x01010101,进而变成10进制就是16843009,而这里一共有5个字节需要赋值,因此最终打印5个16843009

还有一点,在memset清空的时候,第二个参数0和’\0’其实是一样的,因为他们的ASCII值一样,而与’0’不一样,下面一个比较弱的例子可以说明这点

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#define MAXSIZE 10

int main(int argc, char *argv[]){
    char buffer[MAXSIZE] = "Hello";
    if ('\0' == 0)
        if (!strcmp(argv[1], "1")){
            memset(buffer, '0', sizeof(buffer));
            printf("memset '0': %s\n", buffer);
        } else if (!strcmp(argv[1], "2")){
            memset(buffer, 0, sizeof(buffer));
            printf("memset 0: %s\n", buffer);
        } else if (!strcmp(argv[1], "3")){
            memset(buffer, '\0', sizeof(buffer));
            printf("memset \\0: %s\n", buffer);
        } else {
            printf("no argv!\n");
            exit(1);
        }
    return 0;
}
[lihui@localhost ~]$ ./a.out 1
memset '0': 0000000000
[lihui@localhost ~]$ ./a.out 2
memset 0:
[lihui@localhost ~]$ ./a.out 3
memset \0:

发表回复