字符串认知:
1、字符串就是首字符的地址
字符串定义的形式:
2、字符串函数:
字符串比较函数 strcmp strncmp
字符串拷贝函数 strcpy strncpy
字符串长度函数 strlen
字符串连接函数 strcat strncat
字符串清空函数 mensrt bzero
“helloworld”保存在数据段的or段;该数据不能被修改;
char * str = (char *) malloc(sizeof(char) * 100);
注:一定要检查malloc是否分配成功
strcpy:
自己制作my_strcpy函数实现功能:
char * my_strcpy(char * dest,char *src)
{
if(dest == NULL || src ==NULL)
{
return NULL;
}
char *temp = dest;
while(src != '\0')
{
* temp = * src;
src++;
temp++;
}
*temp = '\0';
return dest;
}
**strcat:**连接两个字符串
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
size_t my_strlen(const char *s)
{
size_t len = 0;
if(NULL == s)
{
return 0;
}
while (*s != '\0')
{
len++;
s++;
}
return len;
}
char * my_strcpy(char *dest, char *src)
{
if(dest == NULL || src == NULL)
{
return NULL;
}
char *temp = dest;
while(*src != '\0')
{
*temp = *src;
src++;
temp++;
}
*temp = '\0';
return dest;
}
char * my_strncpy(char *dest, char *src, size_t n)
{
if(dest == NULL || src == NULL)
{
return NULL;
}
int i;
char *temp = dest;
for(i = 0; (i < n) && (*src != '\0'); i++)
{
*temp = *src;
temp++;
src++;
}
for(; i < n; i++)
{
*temp = '\0';
temp++;
}
//*temp = '\0';
return dest;
}
char * my_strcat(char *dest, char *src)
{
if(dest == NULL || src == NULL)
{
return NULL;
}
char *temp = dest;
while(*temp != '\0')
{
temp++;
}
while(*src != '\0')
{
*temp = *src;
temp++;
src++;
}
*temp = '\0';
return dest;
}
char * my_strncat(char *dest, char *src, size_t n)
{
if(dest == NULL || src == NULL)
{
return NULL;
}
char *temp = dest;
while(*temp != '\0')
{
temp++;
}
for(int i = 0; (i < n) && (*src != '\0'); i++)
{
*temp = *src;
temp++;
src++;
}
*temp = '\0';
return dest;
}
int main(int argc, char *argv[])
{
char *ptr = "hello world";
char src[100] = "hello world";
char *dest = (char *)malloc(sizeof(char) * 5);
if (NULL == dest)
{
printf("malloc error!\n");
exit(1);
}
strcpy(dest, "hello");
int len = my_strlen(src);
size_t len1 = strlen("hello world");
printf("len = %d\n", len);
//printf("len1 = %ld\n", strlen(src));
//char *temp = strcpy(dest, src);// strcpy_s(char *dest, int len, char *src);
//char *temp = my_strncpy(dest, src, 100);
// if(NULL == temp)
// {
// printf("my strcpy is error!\n");
// exit(1);
// }
char *temp = my_strncat(dest, src, 5);
printf("dest = %p\n", dest);
printf("temp = %p\n", temp);
printf("dest = %s\n", dest);
printf("temp = %s\n", temp);
return 0;
}
**strcmp:**比较字符串
int my_strcmp(char *s1, char *s2)
{
if (s1 == NULL && s2 != NULL)
{
return -1;
}
if (s1 != NULL && s2 == NULL)
{
return 1;
}
if (s1 == NULL && s2 == NULL)
{
return 0;
}
while ((*s1 != '\0') && (*s2 != '\0'))
{
if (*s1 > *s2)
{
return 1;
}
if (*s1 < *s2)
{
return -1;
}
s1++;
s2++;
}
if (*s1 == '\0' && *s2 == '\0')
{
return 0;
}
if (*s1 != '\0' && *s2 == '\0')
{
return 1;
}
if (*s1 == '\0' && *s2 != '\0')
{
return -1;
}
}
**题目:输入一个字符串,计算字符串中子串出现的次数
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 100
int count_sub_str(char *sub, char *src)
{
int count = 0;
int s_len = strlen(sub);
while (*src != '\0')
{
if (strncmp(sub, src, s_len) == 0)
{
count++;
src = src + s_len;
}
else
{
src++;
}
}
return count;
}
int main(int argc, char *argv[])
{
char *sub;
char src[MAX_SIZE];
printf("Please input src:\n");
scanf("%s", src);
sub = (char *)malloc(sizeof(char) * MAX_SIZE);
if (NULL == sub)
{
printf("malloc sub is error!\n");
exit(1);
}
printf("Please input sub:\n");
scanf("%s", sub);
int count = count_sub_str(sub, src);
printf("sub str count = %d\n", count);
return 0;
}
strchr:
strpbrk:查找字符串中第一个出现的指定字符
野指针
what(是什么)
指针变量里保存的地址对应空间无访问权限(指针所指向的地址空间无访问权限)
why(为什么出现)
1.定义后未初始化的指针
2、释放结束之后的指针
3、越界访问的指针(指向分配空间之后的指针)
野指针出现产生的问题
内存泄露
运行时错误
内存错误(段错误)
how(怎么避免)
养车良好的编码习惯
1、定义变量时必须初始化
当指针变量作为指向工具时,定义初始化NULL
当指针变量指向的空间赋值时,需要动态申请空间
2、使用时
检查内存空间是否分配成功
初始化内存空间(清零内存)
防止越界访问
3、使用结束
必须释放空间
一定将指针再次置为NULL
NULL是什么
简单理解0,但不等于0,NULL用于指针和对象,0用于数值,因为NULL大多数情况下指向0,所
以#defined NULL 0;但并不是说NULL=0
内存空间分配
1、分配方式
静态方式:开销小,但是空间利用率不高
动态分配:开销大,提高空间利用
malloc
malloc只开辟空间,不进行类型检查,返回一个无类型指针,必须加强制类型转换
指针自身 = (指针类型*)malloc(sizeof(指针类型)*数据数量)
int *p = NULL;
int n = 10;
p = (int *)malloc (sizeof(int) * n);
长度:sizeof(类型)*数量
多次申请空间时系统是如何做到空间的不重复使用?
在使用malloc开辟一段空间之后,系统会在这段空间之前做一个标记(0或1),当malloc函数开辟
空间如果遇到标记为0就在此开辟,如果为1说明此空间正在被使用
calloc
开辟空间时,对空间进行初始化
用法:void*calloc(元素的数目,每个元素的大小)
调用成功后,malloc和calloc都返回分配空间的首地址
realloc
更改已配置空间的内存大小
用法:realloc(更改指针名,更改成的大小)
内存减小时:直接减,如果原来的空间位置内容未被修改,依旧可以打印原来的数
内存增大
当前内存段后有足够的内存空间大小,直接扩展,realloc()将返回原指针
当前内存后的空间不够,就使用堆中第一个满足要求的内存块,将目前数据复制到新的位置,并将
原来的数据块释放掉,放回新的内存块位置
如果申请失败,讲返回NULL,此时,原来指针依旧有效
free函数
释放malloc calloc realloc函数给指针变量分配的内存空间时注意要使用时添加函数库
(#include<stdlib.h>) 要在堆空间内开辟内存