冒泡排序:只能排整数
qsort使用快速排序思想实现的一个排序函数
void qsort(void* base, size_t num, size_t width)
void* base//你要排序的数据起始位置
size_t num//待排序的数据元素个数
size_t width,//待排序的数据元素大小,(单位是字节)
int(*cmp)(const void*e1, co.....*e2)
函数指针——比较函数
可以跑徐任意类型的数据
规定:e1<e2时,返回值<0; e1=e2时, 返回值=0;e1 > e2时, 返回值>0
int a = 10;
void* pv = &a;
//void*时无具体类型的指针,可以接受任意类型的地址
//void*时无具体类型的指针,所以不能解引用操作,也不能±整数。
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是有该函数的实现方直接调用,而是在特定的事情或条件发生时有另外的一方调用的,用于对该事件或条件进行相应。
str系列相关关键字:
strlen可以求字符串长度,因为遇到“\0”就会停止,但不可以用来求字符,因为字符没有“\0”作为结束标志,strlen不会停止,存的是随机值
返回值为size_t无符号整型
strcpy:将一个地址复制到另一个地址
char name[20] = {0};
strcpy(name."zhangsan");
//name = "zhangsan", //err 这种写法是错误的
//name数组名是地址,地址是一个常量值,不能被赋值
printf("%s\n", name);
错误示例:
char* p = "abcdef";
char arr[] = "bit";
strcpy(p,arr);//目标区域不可修改
strcpy要求:1.元字符须以“\0”结束
2.会将源字符串中的“\0”拷贝到目标空间
3.目标空间必须是足够大,以确保能存放源字符串
4.目标空间必须可变
5.学会模拟实现
创造性(模拟) 实现:
#include <stdio.h>
void my_strcpy(char* dest, const char* src)
{
assert(dest);
assert(src);
//char* ret = dest;
while (*src)
{
*dest++ = *src++;
//可简化char*ret = dest;
}
*dest = *src;
//return ret;
}
int main()
{
char arr1[] = "abcdef";
char arr2[20] = { 0 };
my_strcpy(arr2, arr1);
printf("%s\n", arr2);
}
字符串追加strcat(返回类型char*)
char arr1[20] = "hellow";
strcat(arr1,"world");
printf("%s\n", arr1);
1.目标空间有足够空间
2.被追加的和追加的字符串要有“\0”
3.目标空间可修改
函数实现:1.找到目标字符串结尾\0
2.拷贝-strcpy
#include <stdio.h>
char* my_strcat(char* dest, const char* src)
{
char* ret = dest;
assert(dest && src);
while (*dest != '0')
{
dest++;
}
while (*dest++ = *src++)
;
return ret;
}
int main()
{
char arr1[20] = "zhangsan";
char arr2[20] = "zhangsanfeng";
int ret = strcmp(arr1, arr2);
if (arr1 == arr2)
{
printf("==");
}
else
{
printf("!=\n");
}
}
结果: !=
原因:arr1与arr2均是数组名,数组名是数组首元素地址,地址之间没办法作比较
strcmp比较的是内容不是长度
比较两个字符串是否相等用strcmp
自己构造函数:
int my_strcmp(const char* str1, const char* str2)
{
assert(str1 && str2);
while (*str1 == *str2)
{
if (*str1 == *str2)
return 0;
str1++;
str2++;
}
if (*str1 > *str2)
return 1;
else
return -1;
}
长度不受限制的字符串函数:
strcpy, strcat strcmp
长度受限制的字符串函数:
strncpy,strncat, strncmp
char arr1[20] = "abcdef";
char arr2[ ] = "bit";
strncpy(arr1, arr2, 5);//即使大于长度也不会'\0'
strstr:查找子串的一个函数
#include <stdio.h>
int main()
{
char email[] = "zpw@ahsuai.com";
char substr[] = "shaij.com";
char ret = strstr(email, substr);
if (ret == NULL)
printf("字串不存在\n");
else
printf("%s\n", ret);
return 0;
}
情况1:一次找到
情况2:多次,一次找不到从第二位开始找
char* my_strstr(const char* str1, const char* str2)
{
assert(str1 && str2);
const char* s1 = str1;
const char* s2 = str2;
const char* p = str1;
while (*p)
{
s1 = p;
s2 = str2;
while (*s1 == *s2 && *s1 != '\0' && *s2 != '\0')
{
s1++;
s2++;
}
if (*s2 == '\0')
{
return (char*)p;
}
p++;
return NULL;
}
}
kmp算法:此算法也是用来实现在一个字符串中查找子字符串的,效率高,但实现难度很大。
strtok切割字符串
char* strtok(char* str, const char* sep);
sep参数是个字符串,定义了用作分隔符的字符集合。
第一个参数指定一个是字符串,它包含了0个活多个由sep字符串中一个或多个分隔符分割的标记。
会改变被操作的字符串,比如
zhangsan@.com @会被改成'\0',随后将zhangsan输出,所以在使用strtok函数切分的字符串一般都是临时拷贝的内容并且可以修改。
const char* sep = "@";
char email[] = "zhangsan@.com";
char cp[30] = { 0 };
strpy(cp, email);
char* ret = strtok(cp, sep);
print("%s\n", ret);
ret = strtok(NULL, sep);
print("%s\n", ret);
ret = strtok(NULL, sep);
print("%s\n", ret);
//传空指针意思是从上次保存位置继续往后找
strerror: char* strerror(int errnum);
返回错误码,所对应的错误信
C语言的库函数,再执行失败时,都会设置错误吗
FILE* pf = fopen("test.txt", "r");
if(pf == NULL)
{
printf("%s\n", strerror(errno));
}
//errno:C语言设置的一个全局的错误码存放变量