C语言笔记(23)冒泡排序与strcopy等知识

冒泡排序:只能排整数

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语言设置的一个全局的错误码存放变量

  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千度vea

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值