C语言之【函数】篇章以及例题分析

文章目录

  • 前言
    • 一、函数是什么?
    • 二、C语言中函数的分类
      • 1、库函数
      • 2、自定义函数
    • 三、函数的参数
      • 1、实际参数(实参)
      • 2、形式参数(形参)
    • 四、函数的调用
      • 1、传值调用
      • 2、传址调用
      • 3、专项练习
        • 3.1 素数判断
        • 3.2 闰年判断
        • 3.3 二分查找
        • 3.4 修改数值
    • 五、函数的嵌套调用和链式访问
      • 1、嵌套调用
      • 2、链式访问
    • 六、函数的声明和定义
      • 1、函数声明
      • 2、函数定义
    • 七、函数递归
      • 1、什么是函数递归?
      • 2、函数递归的两个必要条件
      • 3、题目的展开与剖析
        • 3.1 例题1:打印数字
        • 3.2 例题2:求字符串长度
        • 3.3 例题3:阶乘求解
        • 3.3 例题4:斐波那契数列
    • 八、函数栈帧的创建的销毁

前言

在C语言中,这个函数时必不可少的,没有函数没有灵魂,要不然代码就会乱成一团,所以我们要学函数,接下来就开始函数之旅~~

一、函数是什么?

  • 数学中我们其实就见过函数的概念,比如:一次函数y=kx+b ,k和b都是常数,给一个任意的x,就得到一个y值。其实在C语言也引入函数(function) 的概念,有些翻译为:子程序,子程序这种翻译更加准确一些。C语言中的函数就是一个完成某项特定的任务的一小段代码

  • 这段代码是有特殊的写法和调用方法的。C语言的程序其实是由无数个小的函数组合而成的,也可以说:一个大的计算任务可以分解成若干个较小的函数(对应较小的任务)完成。同时一个函数如果能完成某项特定任务的话,这个函数也是可以复用的,提升了开发软件的效率。

  • 在C语言中我们一般会见到两类函数:

    • 库函数
    • 自定义函数

二、C语言中函数的分类

1、库函数

  • C语言标准中规定了C语言的各种语法规则,C语言并不提供库函数;C语言的国际标准ANSI C规定了一些常用的函数的标准,被称为标准库,那不同的编译器厂商根据ANSI提供的C语言标准就给出了一系列函数的实现。这些函数就被称为库函数。

我们前面内容中学到的printf 、scanf 都是库函数,库函数的也是函数,不过这些函数已经是现成的,我们只要学会就能直接使用了。有了库函数,一些常见的功能就不需要程序员自己实现了,一定程度提升了效率;同时库函数的质量和执行效率上都更有保证。

  • 各种编译器的标准库中提供了一系列的库函数,这些库函数根据功能的划分,都在不同的头文件中进行了声明。
  • 库函数相关头文件:https://zh.cppreference.com/w/c/header

有数学相关的,有字符串相关的,有日期相关的等,每一个头文件中都包含了,相关的函数和类型等信息,库函数的学习不用着急一次性全部学会,慢慢学习,各个击破就行。

  • C语言常用的库函数都有:
  • IO函数
  • 字符串操作函数
  • 字符操作函数
  • 内存操作函数
  • 时间/日期函数
  • 数学函数
  • 其他库函数

接下来,我会参照文档,给大家将两个常用的库函数,来教会大家如何入阅读英文文档

  • 首先我们看函数原形:

strcpy

char * strcpy ( char * destination, const char * source );

在这里插入图片描述

  • 再到代码中来看看它的实际应用场景,在使用这个函数的时候需要引入头文件 【string.h】
  • 那么怎么看一个库函数改引入什么头文件呢?可以打开上面那个网站,搜索库函数,然后在左面就会有

在这里插入图片描述

#include<stdio.h>
#include<string.h>
int main()
{char arr1[] = "###########";char arr2[] = "hello word";//strcpy在拷贝的时候'\0'也会被拷贝过来strcpy(arr1, arr2);printf("%s", arr1);return 0;
}
  • 再来看看运行结果

在这里插入图片描述

在这里插入图片描述


接下去再来看一库函数【memset】

memset

void * memset ( void * ptr, int value, size_t num );

在这里插入图片描述

  • 一样来看一下代码该如何书写
char arr[] = "hello bit";
memset(arr, 'x', 5);
printf("%s\n", arr);
  • 来看一下上面这段代码的执行结果。

在这里插入图片描述

注:
但是库函数必须知道的一个秘密就是:使用库函数,必须包含 #include 对应的头文件。
这里对照文档来学习上面几个库函数,目的是掌握库函数的使用方法。

如何学会使用库函数?

需要全部记住吗?
No 需要学会查询工具的使用:
MSDN(Microsoft Developer Network)
en.cppreference.com【英文版】
zh.cppreference.com【中文版】


2、自定义函数

  • 如果库函数能干所有的事情,那还要程序员干什么?
  • 所以更加重要的是【自定义函数
  • 自定义函数和库函数一样,有函数名,返回值类型和函数参数。但是不一样的是这些都是我们自己来设计。这给程序员一个很大的发挥空间

函数的组成:

ret_type fun_name(para1, * )
{statement;//语句项
}
  • ret_type 返回类型
  • fun_name 函数名
  • para1 函数参数

我们首先来举一个例子:

写一个函数可以找出两个整数中的最大值。

int Get_Max(int x, int y)
{return (x > y ? x : y);
}
int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int max = Get_Max(a, b);printf("二者中的较大值为:%d\n", max);return 0;
}
  • 然后给大家讲解一下这个函数
    在这里插入图片描述

  • 接下去我们再来举一个例子,也是函数这一块最经典的案例:【数值交换】

  • 将交换两个数这个逻辑单独封装成了一个函数,因为它是作为一个功能出现的

void swap(int x, int y)
{int t = x;x = y;y = t;
}
int main()
{int a = 10;int b = 20;printf("交换前:a = %d, b = %d\n",a, b);swap(a, b);printf("交换后:a = %d, b = %d\n", a, b);return 0;
}
  • 来看一下运行结果。可以看到两个数并没有发生交换

在这里插入图片描述

  • 那有小伙伴就很诧异,这是为什么呢?我们一起来调试分析一下

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

结论: 形参实例化之后其实相当于实参的一份临时拷贝

  • 上面这一个,叫做【传值调用】,函数内部形参的修改是不会影响实参的,接下来我们来讲讲【传址调用】~~

  • 先看一下代码,然后我们再通过DeBug来展开分析一下

void swap(int* px, int* py)
{int t = *px;*px = *py;*py = t;
}

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  • 最后来看一下运行结果,已经交换成功了~~

在这里插入图片描述

三、函数的参数

1、实际参数(实参)

  • 真实传给函数的参数,叫实参

  • 对于实参而言,它可以是【常量】、【变量】、【表达式】、【函数】等。我们到VS里来测试一下

  • 无论实参是何种类型的量,在进行函数调用时,它们都必须有确定的值,以便把这些值传送给形参

2、形式参数(形参)

  • 形式参数是指函数名后括号中的变量,因为形式参数只有在函数被调用的过程中才实例化(分配内存单元),所以叫形式参数。形式参数当函数调用完成之后就自动销毁了。因此形式参数只在函数中有效。

所以我们可以总结出来一句话:

函数调用时,实参传递给形参,形参是实参的一份临时拷贝,形参的改变不影响实参

四、函数的调用

  • 这里我们再来说一下函数的【传值调用】和【传址调用】

1、传值调用

函数的形参和实参分别占有不同内存块,对形参的修改不会影响实参

在这里插入图片描述

2、传址调用

  • 传址调用是把函数外部创建变量的内存地址传递给函数参数的一种调用函数的方式。
  • 这种传参方式可以让函数和函数外边的变量建立起真正的联系,也就是函数内部可以直接操作函数外部的变量。

在这里插入图片描述

3、专项练习

3.1 素数判断
  • 【素数】又叫质数。素数,指的是大于1的整数中,只能被1和这个数本身整除的数
  • 知道了规则,那代码就好写了。我们来输出一下100~200的所有素数。在外部写一个循环,就可以获取100 - 200之间的数字了,然后对于素数的求解,可以单独封装为一个函数

  • 首先来思考需要传入哪些参数,很明显:只需要传入被判断的数字即可,然后就要去思考这个函数的返回值,可以这样设定:在函数内部若是判断出其为素数,那么就返回1,否则就返回0,然后在主函数外部进行一个判断即可
int main()
{for (int i = 100; i <= 200; ++i){if (IsPrime(i) == 1){printf("%d是素数\n", i);}}return 0;
}
  • 接下去我们来看看函数的部分

  • 如果i能够被**2, sqrt(i)**之间的任意数据整除,则i不是素数

  • 原因:如果 m 能被 2 ~ m-1 之间任一整数整除,其二个因子必定有一个小于或等于 sqrt(m),另一个大于或等于 sqrt(m)。

  • 注意: 在使用sqrt的时候需要引入头文件【math.h】

/*素数判断*/
int IsPrime(int n)
{int j = 0;for (int j = 2; j < sqrt(n); j++){if (n % j == 0)return 0;}return 1;
}
  • 然后我们来看一下运行结果

在这里插入图片描述

3.2 闰年判断
  • 【闰年】公历年份是4的倍数,且不是100的倍数,为普通闰年。公历年份是整百数,且必须是400的倍数才是世纪闰年
  • 一样,我们先将主函数写好。需求是输出一下1000~2000之间的所有闰年
for (int i = 1000; i <= 2000; ++i)
{if (Isleap(i) == 1){printf("%d ", i);}
}
  • 然后的各方面条件和上面是一样的,便不做详解,我们来看看函数体~~
  • 这一块我给出两种方法,第一种就是直接了当一些,若是能被4整数但是不能被100整数,或者可以被400整数的数,那就是一个闰年,此时返回1即可,反之返回0,利用到了【逻辑操作符
int Isleap(int year)
{if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){return 1;}return 0;
}
  • 第二种方法就是一个if的嵌套判断,这里要注意的一点是对400取余的条件外面要写成【if】,不要写成【else if】,否则两个判断条件就只会进去一个了,那就回漏掉几个年份
int Isleap(int year)
{if (year % 4 == 0){if (year % 100 != 0){return 1;}}if (year % 400 == 0)return 1;
}
  • 第三种方法是可以直接return(year % 4 == 0 && year % 100 != 0) || (year % 400 == 0),如果为真,就返回1,如果为假,就返回0
return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);
  • 来看一下运行结果~~

在这里插入图片描述

3.3 二分查找
  • 首先我们需要设定一个有序数组,因为二分查找只能在序列有序的情况下才可以进行
int arr[] = { 1,2,3,4,5,6,7,8,9 };
int sz = sizeof(arr) / sizeof(arr[0]);
int k = 7;
  • 可以看到,上面除了设定数组以外,我还求出这个数组的元素个数,因为在进行函数传参的时候需要使用到
int pos = BinarySearch(arr, sz, k);
  • 来看如何传值以及接收返回值,首先我们需要将这个数组的【首元素地址】传入
  • 除了要传入数组的首元素地址之外,还需要传入我在上面求出来的【sz】,也就是数组的个数
//int BinarySearch(int* a, int n, int k)   //指针接收地址
int BinarySearch(int a[], int n, int k)	   //数组接收数组
{int left = 0;int right = n - 1;while (left <= right){int mid = left + (right - left) / 2;if (k > a[mid])left = mid + 1;else if (k < a[mid])right = mid - 1;elsereturn mid;}return -1;
}
3.4 修改数值
  • 通过函数内部的修改带动函数外部数组的修改,这里就要使用到我们上面所说的【传址调用】
void change(int* px)
{(*px)++;
}
int num = 0;
change(&num);
printf("num = %d\n", num);
  • 在函数外部,我传入了num值的地址,然后在函数体的形参中使用指针来进行接收,此时对这个指针进行解引用就可以获取到外部的实参,就可以直接对其进行修改了
  • 这里主要写成(*px)++,不能写成*px++,因为【++】的优先级比【*】来得高,所以会先对这个指针变量进行一个++,然后再对其进行一个解引用的操作,但是当这个指针后移的时候,就已经变成了野指针,此时再去访问这个野指针就会出现问题

在这里插入图片描述

  • 但是我们上*px外的括号去掉再看看

在这里插入图片描述

五、函数的嵌套调用和链式访问

1、嵌套调用

函数和函数之间可以根据实际的需求进行组合的,也就是互相调用的

  • 首先来看第一个例子~~
void print()
{printf("haha\n");
}void three()
{for (int i = 0; i < 3; ++i){print();}
}
int main()
{three();return 0;
}

在这里插入图片描述

函数可以嵌套调用,但是不能嵌套定义

2、链式访问

把一个函数的返回值作为另外一个函数的参数

  • 这里我先介绍一下【strlen】这个函数

在这里插入图片描述

  • 我们到代码里面来用一下
char a[] = "hello world";
int len = strlen(a);
printf("len = %d\n", len);

在这里插入图片描述

  • 这里要注意一点的是strlen()去求字符串长度的时候是不算’\0’的

  • 接着再来介绍一个函数【strcat】

在这里插入图片描述

  • 接下去我们来看看如何做到链式访问
char a[10] = "hello";
int len = strlen(strcat(a, "bit"));
printf("len = %d\n", len);

在这里插入图片描述

  • 接下去再来看一下链式访问的例子。你知道这句代码输出的结果是多少吗
printf("%d", printf("%d", printf("43")));

在这里插入图片描述

  • 为什么这句代码的输出是【4321】呢,我们来看一下【printf】这个函数

在这里插入图片描述

  • 可以看到对于printf的返回值是输出字符的个数,那这就可以解释通了:对于内层的 printf("43")输出的字符个数有2个,然后再看外层的printf("%d", printf("43"))便会在输出一个2,它的返回值就是输出了一个字符,那么整体的这个printf("%d", printf("%d", printf("43")))就会在输出一个1,作为返回值

六、函数的声明和定义

1、函数声明

  1. 告诉编译器有一个函数叫什么,参数是什么,返回类型是什么。但是具体是不是存在,函数
    声明决定不了。
  2. 函数的声明一般出现在函数的使用之前。要满足先声明后使用。
  3. 函数的声明一般要放在头文件中的
  • 来看一下代码
int Add(int x, int y);int main()
{int a = 0;int b = 0;scanf("%d %d", &a, &b);int sum = Add(a, b);printf("sum = %d\n", sum);return 0;
}int Add(int x, int y)
{return x + y;
}

在这里插入图片描述

2、函数定义

函数的定义是指函数的具体实现,交待函数的功能实现

  • 对于上面的代码,我们可以对其做一个分解,将【add】这个功能单独放到一个.c的文件中,然后再写一个.h的文件去声明一下这个函数。因为在日常的项目工程中,是有很多程序员一起写代码的,但是他们不可能在一个.c文件中一起书写,也不能等一个人写好之后另一个人再接着写,这样就会降低开发效率
  • 所以我们就有一个分模块编写的说法,也就是在一个头文件中先写好函数的声明和各种库函数的引用和定义,然后每个程序员都可以创立自己的.c文件,然后去书写自己的那段逻辑,最后将大家的代码进行一个整合,就完成了整个项目

在这里插入图片描述

七、函数递归

接下去我们来说说函数递归,这也是函数这一块最难理解的内容

1、什么是函数递归?

程序调用自身的编程技巧称为递归( recursion)
只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量
递归的主要思考方式在于:把大事化小

2、函数递归的两个必要条件

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续。
  • 每次递归调用之后越来越接近这个限制条件

3、题目的展开与剖析

3.1 例题1:打印数字
  • 【要求】:输入1234,打印1 2 3 4

  • 在之前我们学习分支和循环的时候有做过类似的题目,那个时候我们是利用取余【%】和整除【/】倒着打印一个数字的每个数位,也就是下面这段代码

void print1(int num)
{while (num > 0){printf("%d ", num % 10);num /= 10;}
}int main()
{print1(1234);return 0;
}

运行结果如下

在这里插入图片描述

  • 现在我们要顺着将这个数的每一个数位进行一个打印,这该怎么去做呢?我们来分析一下
  • 我们在屏幕上通过scanf输入一个数,然后通过封装好的一个函数传入print(num),即print(1234),那既然上面讲到了这个分割数字的思路,这里我们也可以使用这个思路来完成,
  • 对于print(1234)我们可以拆成print(123) 4
  • 对于print(123)又可以拆成print(12) 3
  • 对于print(12)又可以拆成print(1) 2
  • print(1234)就被拆成了print(1) 2 3 4,也就是当这个num < 10为一个个位数时,就做一个打印,否则的话就不断将其以十分之一倍得进行缩小。我们将其转化为代码的形式就【一目了然】了
  • 可以看到,这里是使用到了一个递归的逻辑,上面说到递归都是具有结束条件的,若是不符合的话就层层递归下去,知道当前传入的num值为个位数为止才进行一个回调
void print2(int num)
{if (num > 9){print2(num / 10);}printf("%d ", num % 10);
}

运行结果如下

在这里插入图片描述

  • 我们通过递归展开图再来看看~~

在这里插入图片描述

3.2 例题2:求字符串长度
  • 【要求】:输入abc,输出其长度为3

  • 上面有讲到过strlen()这个函数,其可以求出一个字符串的长度,我们首先通过这个函数来试试

int main()
{char str[] = "abc";int len = strlen(str);		//利用库函数进行求解printf("len = %d\n", len);return 0;
}
  • 接下去的话我们将这个strlen()函数改成my_strlen(),我们自己来实现一下这个底层的逻辑。
  • 对于int len = my_strlen(str);,我们传入了字符数组str的首元素地址,那上面有讲到过对于地址要使用指针来进行接收,最后还要返回求出的长度,所以对于函数我们可以定义成这样
int my_strlen(char* str)
  • 对于str这个字符指针现在是指向传入字符数组的首元素地址,也就是【a】,【\0】是一个字符串的结束标志,可以让这个字符指针不断后移,每一次对其进行解引用看看是否为【\0】即可,有了思路我们就可以写出代码了

  • 在这里的话还需要设置计数器,我们我们要去求解这个字符串的长度,因此判断到它不为【\0】的时候就count++,然后让这个字符指针进行后移即可。

int my_strlen(char* str)
{int count = 0;while ((*str) != '\0'){count++;	//计数器累加str++;		//字符指针后移}return count;
}
  • 那我们现在的要求是不可以使用计数器进行求解字符串的长度
  • 一样,我们可以使用到上面的分割思想
  • 对于my_strlen(abc)我们可以拆成1 + my_strlen(bc)
  • 对于my_strlen(bc)我们可以拆成1 + my_strlen(c)
  • 对于my_strlen(c)我们可以拆成1 + my_strlen('\0')
  • my_strlen(abc)就相当于是1 + 1 + 1 + 0。也是使用字符指针去进行一个后移,若其不为【\0】时,就不断对这个字符串进行拆分,然后直到遇到【\0】时便return 0。接下去就可以写出代码了
int my_strlen(char* str)
{if (*str != '\0'){return 1 + my_strlen(str + 1);}return 0;
}
  • 然后来看一下结果吧,上面三段代码的结果都是一样的,所以一起展示了

在这里插入图片描述

  • 一样,我们来画一下递归展开图

在这里插入图片描述

3.3 例题3:阶乘求解
  • 【要求】:输入一个数,输出其求阶乘后的结果
  • 阶乘就是从从一个数开始乘,慢慢减少,一直乘到1为止,举个例子3! = 3 * (3 - 1) * (3 - 2) = 3 * 2 * 1 = 6

在这里插入图片描述

  • 也就是当【n <= 1】时,即0的阶乘和1的阶乘最后都是1,当【n >= 2】时,最后的结果就是n去乘以它减1的阶乘,于是我们就可以得出递归的代码
int Func1(int n)
{if (n <= 1)return 1;elsereturn n * Func1(n - 1);
}
  • 对于阶乘来说,不仅可以使用递归实现,还可以使用循环的方式来是实现
int Func2(int n)
{int ret = 1;for (int i = 1; i <= n; ++i){ret *= i;}return ret;
}

这里再对上面的递归实现做一个递归展开图的分析

在这里插入图片描述

3.3 例题4:斐波那契数列
  • 【要求】:输入一个数,输出从1到这个数的斐波那契数

  • 斐波那契数就是前两个数加起来等于第三个数

  • 这里给出从1~10的斐波那契数列 【1 1 2 3 5 8 13 21 34 55】,可以看出对于1,2两个数来说都是1,后面就是数就是前两个数之和,因此我们可以列出下面的公式

    在这里插入图片描述

  • 然后根据这个公式写出代码

int Fib1(int n)
{if (n <= 2)return 1;elsereturn Fib1(n - 2) + Fib1(n - 1);
}

八、函数栈帧的创建的销毁

本内容请看这篇文章——> 反汇编深挖【函数栈帧】的创建和销毁【制作中】

最后,函数的所有内容就到这里就结束了~~
如果有什么问题可以私信我或者评论里交流~~
感谢大家的收看,希望我的文章可以帮助到正在阅读的你🌹🌹🌹

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/631675.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ARM 1.16

TCP的特点 面向连接 面向连接&#xff0c;是指发送数据之前必须在两端建立连接。建立连接的方法是“三次握手”&#xff0c;这样能建立可靠的连接。建立连接&#xff0c;是为数据的可靠传输打下了基础。 仅支持单播传输 每条TCP传输连接只能有两个端点&#…

21. 合并两个有序链表(Java)

题目描述&#xff1a; 将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。 输入&#xff1a; l1 [1,2,4], l2 [1,3,4] 输出&#xff1a; [1,1,2,3,4,4] 代码实现&#xff1a; 结点类&#xff1a; public class ListNode {in…

自动化测试总结

1.什么是自动化测试 以程序测试程序&#xff0c;以代码代替思维&#xff0c;以脚本的运行代替手工测试。自动化的测试涵盖了&#xff1a;功能&#xff08;黑盒&#xff09;自动化测试&#xff0c;功能&#xff08;白盒&#xff09;自动化测试&#xff0c;性能测试&#xff0c;…

YOLOv8改进 | Conv篇 | 在线重参数化卷积OREPA助力二次创新(提高推理速度 + FPS)

一、本文介绍 本文给大家带来的改进机制是一种重参数化的卷积模块OREPA,这种重参数化模块非常适合用于二次创新,我们可以将其替换网络中的其它卷积模块可以不影响推理速度的同时让模型学习到更多的特征。OREPA是通过在线卷积重参数化(Online Convolutional Re-parameteriza…

低代码开发:解锁数字化转型新维度

在信息化浪潮中&#xff0c;企业正面临着前所未有的挑战与机遇。一方面&#xff0c;市场环境瞬息万变&#xff0c;业务需求迭代频繁&#xff0c;对快速应用开发提出了更高要求&#xff1b;另一方面&#xff0c;传统软件开发模式受限于高成本、长周期等瓶颈&#xff0c;难以满足…

【备战蓝桥杯】探索Python内置标准库collections的使用

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-q0zvWxZtAIdSGZ8R {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

用3D渲染效果图时,需要注意什么?

要用3D渲染效果图&#xff0c;您需要使用3D建模软件来创建三维模型、材质、灯光和相机等元素&#xff0c;并使用渲染引擎将它们渲染成逼真的图像。那么用3D渲染效果图需要注意什么? 在用3D渲染效果图时&#xff0c;您需要注意以下几点&#xff1a; 1、模型精度&#xff1a;模型…

【HTML】-- 01 初识HTML

HTML 1.初识HTML Hyper Text Markup Language&#xff1a;超文本标记语言 1.1 W3C标准 W3C World Wide Web Consortium(万维网联盟)成立于1994年&#xff0c;Web技术领域最权威和最具影响力的国际中立性技术标准机构http://www.w3.org/http://www.chinaw3c.org/ W3C标准包括…

如何批量修改文件名顺序编号?

如何批量修改文件名顺序编号&#xff1f;批量修改文件名顺序编号&#xff0c;指的是对多个文件名进行统一的修改&#xff0c;为每个文件名添加一个顺序编号。例如&#xff0c;将文件夹中的一组文件从"file1", "file2", "file3" 修改为 "001…

CentOS使用docker本地部署StackEdit Markdown编辑器并实现公网访问

文章目录 1. docker部署Stackedit2. 本地访问3. Linux 安装cpolar4. 配置Stackedit公网访问地址5. 公网远程访问Stackedit6. 固定Stackedit公网地址 StackEdit是一个受欢迎的Markdown编辑器&#xff0c;在GitHub上拥有20.7k Star&#xff01;&#xff0c;它支持将Markdown笔记保…

【JMeter】JMeter连OceanBase数据库

1、下载OB&#xff08;OceanBase简称&#xff0c;下同&#xff09;&#xff0c;下载地址&#xff1a;https://www.oceanbase.com/softwarecenter-enterprise 2、将下载下来的jar包放到jmeter安装目录的 lib 目录下&#xff0c;或者打开JMeter客户端&#xff0c;在测试计划中引入…

Tide Quencher 7.2 CPG 500A ,TQ7.2 CPG 500A,可以提高荧光标记物的淬灭效果

您好&#xff0c;欢迎来到新研之家 文章关键词&#xff1a;荧光淬灭剂Tide Quencher 7.2 CPG 500A&#xff0c;Tide Quencher 7.2 CPG 500A &#xff0c;TQ7.2 CPG 500A 一、基本信息 产品简介&#xff1a;The fluorescence quencher Tide Quencher 7.2 CPG 500A can quench…

如何卸载旧版docker

环境&#xff1a; Docker1.13 centos7.6 问题描述&#xff1a; 如何卸载旧版docker 解决方案&#xff1a; 1.停止Docker服务。使用以下命令停止Docker服务&#xff1a; sudo service docker stop2.卸载Docker软件包。根据您的Linux发行版&#xff0c;使用适当的包管理器来…

IP 地址如何进行动态分配?

由于 IP 地址资源的有限性&#xff0c;大部分用户上网都是使用动态 IP 地址&#xff0c;而不是静态 IP 地址。动态 IP 地址指的是在需要的时候才进行 IP 地址分配的方式&#xff0c;而静态 IP 地址是固定分配一个 IP 地址&#xff0c;每次都用这一个地址。因此&#xff0c;IP 地…

[三]H264编码和 MediaCodec

[三]H264编码和 MediaCodec 一.MediaCodec二.H264二.使用Nginx搭建自己的rtmp服务器1.nginx是什么&#xff1f;2.环境准备 三、搭建过程1.安装编译 nginx 所需要的库2.下载 nginx-1.21.6.tar.gz3.下载 nginx-rtmp-module 4.解压5.编译6.启动nginx&#xff0c;检测nginx是否能成…

使用Go语言处理Excel文件的完整指南

xcel文件是广泛用于存储和处理数据的常见文件格式。在Go语言中&#xff0c;有许多库和工具可用于处理Excel文件。本文将介绍如何使用Go语言处理Excel文件&#xff0c;包括读取、写入和修改Excel文件&#xff0c;以及处理单元格、行和列等操作。无论是从头开始创建Excel文件&…

算法练习-长度最小的子数组(思路+流程图+代码)

难度参考 难度&#xff1a;简单 分类&#xff1a;数组 难度与分类由我所参与的培训课程提供&#xff0c;但需要注意的是&#xff0c;难度与分类仅供参考。以下内容均为个人笔记&#xff0c;旨在督促自己认真学习。 题目 给定一个含有个正整数的数组和一个正整数s&#xff0c;找…

智慧门店:如何利用AI视频智能监管与存储技术让门店降本增效?

一、行业背景 TSINGSEE青犀视频智慧门店解决方案是一种集成了人工智能、大数据、物联网等技术的零售解决方案&#xff0c;目的是提高门店的运营效率、用户体验和业绩。随着数字化转型的加速&#xff0c;连锁门店需要跟上时代的步伐&#xff0c;需要利用数字化手段提高运营效率…

【记录】解决 git 仓库突然出现连接失败

问题描述 今天在 push 代码代码的时候突然发现无法 push(但是我可以正常打开 Gihub)&#xff0c;这可不行&#xff0c;我可是 git 的重度使用者&#x1f60d;&#xff0c;我所有的代码都托管在了 Github 上&#xff0c;没有它我的日子怎么活啊&#xff01;&#xff01;&#x…

Linux系统三剑客之grep和正则表达式的介绍(一)

1.正则表达式 目录 1.正则表达式 1.什么是正则表达式 &#xff1f; 2.正则表达式的使用场景 3.正则表达式字符表示 4.它们之间的区别 2.grep命令 作用&#xff1a; 语法&#xff1a; 说明&#xff1a; 选项&#xff1a;options 重点 实例 3.后面的下次再更新。 …