一、字符串、字符、字节
1、size_t为无符号整数类型,在表达式中使用无符号数可能导致不可预料的结果
int main()
{
char *p = "abcdef";
char *q = "abc";
if (strlen(q) - strlen(p) >= 0)
{
printf("q<p\n");
}
else
{
printf("q >= p\n");
}
system("pause");
return 0;
}
永远返回q>=p,因为strlen函数返回值为size_t,所以永远大于0,应该改为if(strlen(x)>=strlen(y))
2、不受限制的字符串函数
(1)strcpy函数
功能:
使用的时候的注意事项:1)dst所指的空间>src所指的空间
2)dst不能是常量,例如:char *p="asdfg"
附:查询gets函数的功能
(2)strcat
功能:
使用的时候的注意事项:1)dst所指的空间>src所指的空间
2)dst不能是常量,例如:char *p="asdfg"
3)不能给自己追加
(3)strcmp比较函数
功能:
使用的时候的注意事项:1)dst所指的空间>src所指的空间
2)dst不能是常量,例如:char *p="asdfg"
3)可以自己比较自己
3、长度受限制的函数
(1)字符串函数
a)strncpy
b)strncat
c)strncmp
(2)内存管理函数
a)memmove
b)memcmp
4、字符串查找基础
(1)查找一个字符
a)strchar:查找第一个字符
b)strchr:查找最后一个字符
(2)查找任意个字符
strbtk函数
注意:(1)有可能返回NULL,输出前先做判断
(3)查找一个子字符串:strstr
注意:返回第一次出现的位置
5、高级字符串查找
(1)查找一个字符串前缀
strspn(char const *str,char const *group);起始作用
strcspn(char const *str,char const *group);不予匹配
(2)查找标记
a)strtok
注意:1、会改变原字符串
2、如果源字符串,不能被修改,那么就对被查找的字符串做一份临时的拷贝
3、传值比较特殊,第一次传tmp,第二次传NULL(这个函数可以传NULL,我想应该保存了全局和静态变量)
使用方法:
#include <stdio.h>
#include <string.h>
int main()
{
char *p = "192.168.0.1";
char tmp[20];
strcpy(tmp, p);
char *token;
for (token = strtok(tmp, ".");
token != NULL;
token = strtok(NULL, "."))
{
printf("%s\n", token);
}
system("pause");
return 0;
}
运行结果:
(2)strerror
功能:返回错误代码所对应的信息
使用方法:接受int,返回字符指针,strerror(errno),其中errno为当前错误码
注意事项:定义在#include<errno.h>,相当于工具->错误查找(有可能不是C语言的)
6.内存操作
思考:为什么有了字符串操作函数,还要内存操作函数
答案:可以处理内存块,而不管其中间的类型
(1)内存拷贝
a)memove
b)memcmp
(2)msmset初始化函数,往往在动态内存开辟中用
二、动态内存开辟
1、malloc开辟内存块,动态内存管理
使用方法:
#include<stdio.h>
#include <stdio.h>
int main()
{
int arr[10];
int i = 0;
int n = 0;
scanf("%d", &n);
int *p = (int *)malloc(n*sizeof(int));
if (p == NULL)//判断内存是否开辟成功
{
printf("out of memory\n");
return -1;
}
for (i = 0; i < n; i++)
{
p[i] = i; *(p + i);
}
for (i = 0; i < n; i++)
{
printf("%d\n", p[i]);
}
free(p);//可以收回空指针
system("pause");
return 0;
}
注意事项:1、内存泄漏(自己用不上,别人也用不上)
程序结束后自动收回,没有泄漏
2、对NULL进行解应用
2、calloc开辟内存并初始化为"0",所以更低效
3、realoc调整空间大小
4、malloc写成#define MALLOC形式,封装为上层
a)test.c中
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include "alloc.h"
int main()
{
int *p = malloc(10);
int *p = (int *)malloc(10 * sizeof(int));
int i = 0;
p=realloc(p, 80);
for (i = 0; i < 20; i++)
{
p[i] = i;
}
free(p);
system("pause");
return 0;
}
B)alloc.h文件
#ifndef __ALLOC_H__
#define __ALLOC_H__
#include <stdio.h>
void *alloc(int sz);
#define MALLOC(NUM, TYPE) \
(TYPE*)alloc(NUM * sizeof(TYPE))
#define malloc 不能使用malloc
#endif //__ALLOC_H__
c)alloc.c文件
#define _CRT_SECURE_NO_WARNINGS 1
#include "alloc.h"
void *alloc(int sz)
{
#undef malloc
void *p = malloc(sz);
if (p == NULL)
{
printf("out of memory\n");
exit(1);
//return NULL;
}
return p;
}
6、内存开辟的过多不收回,有可能系统会崩溃
#include <stdio.h>
int main()
{
int count = 0;
while (malloc(1 << 20))//开辟一兆空间
{
count++;
}
printf("%d\n", count);
system("pause");
return 0;
}
5、relloc,要用其指针接受其返回值(因为返回值有可能会变)
例如:int *q=(int *)realloc(p,80)
6、不是开辟的物理空间,是虚拟地址,认为自己开辟的相当于all computer
7、free只能释放动态开辟的空间
char *p只能是malloc,relloc,calloc,才能free(p)
8、free可以释放空指针NULL,不能释放动态内存的某一部分
9、free函数不能将p置成空,是野指针
8、模拟开辟二维数组
10、改编电话本,将电话本实现为动态增长的
11、结构体的动态开辟问题(详情请看C语言深度剖析 5.3)
部分问题请看如下程序:
#include<stdio.h>
#include <stdio.h>
typedef struct Stu
{
//char name[20];*****************
char *name;
int age;
}Stu, *pStu;
int main()
{
//struct Stu stu = { 0 };*******************
//stu.name = "abcdef"; 这时的*********这时的name为数组名,不能赋值
pStu pstu = (pStu)malloc(sizeof(Stu));
pstu->name = (char *)malloc(12);
strcpy(pstu->name, "abcdef");//同时一定要给*name开辟空间,要
pstu->age = 20; //不然name美欧指定空间
//同时注意给字符串开辟空间一定要预留'\0'
printf("%s\n", pstu->name);
free(pstu->name);
free(pstu);
pstu->name = NULL;
pstu = NULL;
system("pause");
return 0;
}
注意事项:结构体假如先释放结构体后释放name,就会永远内存泄漏
12、模拟实现strstr
#include<stdio.h>
#include<stdlib.h>
char *my_strstr(const char *str1, const char *str2)
{
const char *ptr = str1;
const char *p1 = NULL;
const char *p2 = NULL;
while (*ptr)
{
p1 = ptr;
p2 = str2;
while (*p1 == *p2)
{
p1++;
p2++;
if (*p2 == '\0')
return (char *)ptr;
}
ptr++;
}
return NULL;
}
int main()
{
char *p = "bcd";
char*q = "bcd";
char *ptr = my_strstr(p, q);
printf("%s\n", ptr);
system("pause");
}
转载于:https://blog.51cto.com/10742910/1719654