malloc
malloc
是在堆上面动态开辟内存,它的函数原型void *malloc(size_t size)
,意思是分配所需的内存空间,并返回一个指向它的指针。使用malloc
前,需要在程序开始包含它的头文件#include <stdlib.h>
。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = (char *)malloc(1); //这里为指针p开辟了1个字节(char)的空间大小,p有了具体指向
*p = 'c';
puts(p); //这里输出 c
return 0;
}
strcpy
strcpy是把一段数据复制到另一个内存空间里。它的函数原型是char *strcpy(char *dest, const char *src);
,参数里面的dest
是复制之后要放的目的地,src
是要复制的数据。使用strcpy
前,需要在程序开头包含#include<string.h>
。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = (char *)malloc(1); //这里为指针p开辟了1个字节(char)的空间大小,p有了具体指向
*p = 'c';
//这里需要把上面申请的1个字节的空间给free掉,因为整段代码只有一个指针p,下面又申请了10个字节的指针存放一段字符串。
//因此指针又指向下面的空间,与上面的空间断开了,上面的内存空间悬挂了。
//普通数组,普通变量等是在栈空间里面的,函数调用结束后就释放内存了。
//malloc是在堆上面开辟空间,它会在整个程序结束才释放内存,如果是死循环的malloc,它会不断地消耗计算机堆上面的内存,因此需要free释放内存。
free(p); //这里指针p变成野指针了
p = (char *)malloc(5); //申请了5个字节空间,又具体指向空间,p指针又不野了
strcpy(p,'Hello'); //向指针p存下这个字符串
puts(p); //这里输出 Hello
puts("end");
return 0;
}
下面是通过自己写函数实现复制功能:
char* mystrcpy(char *desk,char *src)
{
if(desk == NULL || src == NULL){
printf("NULL\n");
return NULL;
}
char *bak;
bak = desk; //因为下面的desk++,所以先把desk的首地址给bak保存一下,最后返回bak,也就是desk的首地址
while(*src !='\0'){
*desk++ = *src++;
}
*desk = '\0';
return bak;
}
free
C库函数void free(void *ptr)
释放之前调用calloc,malloc,realloc
所分配的内存空间。使用free
前,需要在程序开始包含它的头文件#include <stdlib.h>
,它的作用有:
- 释放,防止内存泄露
- 防止悬挂指针(野指针)
realloc
当需要在原先开辟的malloc内存里存放更多数据,但是内存空间不足,这个时候realloc函数就可以在原先的内存开辟更多空间了。realloc的函数原型void *realloc(void *ptr, size_t size)
,意思是重新调整之前调用的malloc或calloc所分配的ptr所指向的内存块的大小。使用realloc
前,需要在程序开始包含它的头文件#include <stdlib.h>
。
#include <stdio.h>
#include <stdlib.h>
int main()
{
char *p;
p = (char *)malloc(5); //申请了5个字节空间,又具体指向空间,p指针又不野了
strcpy(p,'Hello'); //向指针p存下这个字符串
printf("扩容前的地址:%p\n",p);
int len = strlen("Hello0123456789"); //计算总长
int newlen = len - 5 + 1; //新的数据长度减去原先的数据长度,+1是保存'\0'
realloc(p,newlen); //扩大了newlen个长度空间
printf("扩容前的地址:%p\n",p); //扩容前后地址不变,因为在原空间上扩容
strcpy(p,'Hello0123456789');
puts(p); //这里输出 Hello0123456789
puts("end");
return 0;
}
memset
menset
是将一段指针空间void *str
内的n
个数据,初始化成c
,它的函数原型是void *memset(void *str, int c, size_t n);
,一般用于malloc开辟空间后,将这段空间初始化成'\0'
。使用memset
前,需要在程序开始包含它的头文件#include <string.h>
。
#include <stdio.h>
#include <string.h>
int main()
{
char *p;
p = (char *)malloc(10);
menset(p,'\0',10); //将指针p的10个字节全部初始化为'\0'
strcpy(p,"0123456789");
puts(p);
return 0;
}
strncpy
strncpy
的原型char *strncpy(char *dest, const char *src, size_t n);
,拷贝n
个长度的src
的数据到dest
里面。使用strncpy
前,需要在程序开始包含它的头文件#include <string.h>
。
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "Hello0123456789";
char str[10];
strncpy(str,p,5); //把p指针前五个数据拷贝来str里
printf("%s",str);
return 0;
}
下面是通过自己写函数实现按需要拷贝:
char* mystrncpy(char *desk,char *src,int len)
{
if(desk == NULL || src == NULL){
printf("NULL\n");
return NULL;
}
char *bak;
bak = desk; //因为下面的desk++,所以先把desk的首地址给bak保存一下,最后返回bak,也就是desk的首地址
while(*src !='\0' && len>0) //加了长度
{
*desk++ = *src++;
len--;
}
if(len> 0) //如果先判断遇到了'\0',就进入一下while循环
{
while(len> 0)
{
len--;
*desk++ = '\0'; //把接下来的每一位赋值成'\0'
}
return desk;
}
*desk = '\0';
return bak;
}
strcat
strcat
是用来拼接的,它的原型是char *strcat(char *desk, const char *src);
,把src
所指向的字符串(包括'\0'
)复制到desk
所指向的字符串后面(删除 *desk
原来末尾的'\0'
)。要保证 *desk
足够长,以容纳被复制来的 *src
。*src
中原有的字符不变。返回指向desk
的指针。使用strcat
前,需要在程序开始包含它的头文件#include <string.h>
。。
int main()
{
char *p = " ,zhuangpangzi";
char desk[200] = "Dazhonglian";
char *p2;
p2 = Strcat(desk,p);
strcat(desk,p);
puts(desk);
puts(p2);
return 0;
}
下面由自己写函数实现字符串拼接:
char* myStrcat(char *desk,char *src)
{
char *bak=desk;
while(*desk != '\0'){
desk++; //先把desk的指针移动至desk的尾部
}
while((*desk++ = *src++) != '\0'); //在desk的尾部拼接
*desk = '\0';
return bak;
}
strcmp
strcmp
比较两个字符串,它的原型是int strcmp(const char *str1, const char *str2)
,若str1
=str2
,则返回0;若str1
<str2
,则返回负数;若str1
>str2
,则返回整数。使用strcmp
前,需要在程序开始包含它的头文件#include <string.h>
。
#include <stdio.h>
#include <string.h>
int main()
{
char *p1 = "Dazhongliana";
char *p2 = "Dazhonglianb";
int ret = Strcmp(p1,p2);;
if(ret == 0){
printf("相同\n");
}
printf("ret = %d",ret); //输出为1,按ASCII 编码,b大于a
return 0;
}