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

news2024/12/27 15:22:46

文章目录

  • 前言
    • 一、函数是什么?
    • 二、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;
		else
			return 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;
	else
		return 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;
	else
		return Fib1(n - 2) + Fib1(n - 1);
}

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

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

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

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

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

相关文章

android软件全屏时,输入法显示的输入框位置代码

一、问题描述 在输入密码框时,点击密码输入框,会跳出软键盘,同时附带一个输入框: 这个输入框并不随输入法设置,而是一个系统自带的配置。 当这个密码以明文的方式显示时,输入网址或者ip,长按后能够打开浏览器。这是我不希望出现的。 二、探索password的TextView 根据…

Ubuntu 在更新内核后 Virtual Box 不能为虚拟电脑打开一个新任务

前言 我也不知道啥时候自动给我更新了内核&#xff0c;重启电脑之后我的内核升级成6.5.0-14-generic&#xff0c;导致Virtual Box无法找到内核文件。 解决方法 方法1 sudo apt update sudo apt install linux-headers-generic build-essential dkms sudo apt remove virtua…

甜蜜而简洁——深入了解Pytest插件pytest-sugar

在日常的软件开发中,测试是确保代码质量的关键步骤之一。然而,对于测试报告的生成和测试结果的可读性,一直以来都是开发者关注的焦点。Pytest插件 pytest-sugar 以其清晰而美观的输出,为我们提供了一种愉悦的测试体验。本文将深入介绍 pytest-sugar 插件的基本用法和实际案…

Vue-26、Vue内置指令v-cloak与v-once以及v-pre

1、v-cloak 本质上是一个特殊属性&#xff0c;Vue实例创建完毕并接管容器后&#xff0c;会删掉v-cloak属性使用css配合v-cloak可以解决网速慢时页面展示出{{xxx}}的问题 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF…

vue二次封装ant-design-vue中的Modal弹窗组件,实现拖拽,全屏两种功能,原有参数属性不变

在我们的项目的有的地方需要用弹框的拖拽&#xff0c;以及弹窗自定义全屏显示的需求&#xff0c;所以再次将二次合一&#xff0c;同时弹框里面内容自适应屏幕高度 在ant-design-vue中&#xff0c;已经实现了拖拽&#xff0c;全屏的功能&#xff0c;下面是ant官网的示例 自定义…

【JavaEE进阶】 关于应用分层

文章目录 &#x1f38b;序言&#x1f343;什么是应⽤分层&#x1f38d;为什么需要应⽤分层&#x1f340;如何分层(三层架构)&#x1f384;MVC和三层架构的区别和联系&#x1f333;什么是高内聚低耦合⭕总结 &#x1f38b;序言 在我们进行项目开发时我们如果一股脑将所有代码都…

零售EDI:Babylist EDI 项目案例

Babylist 与各种不同的品牌和零售商合作&#xff0c;包括婴儿用品、玩具、衣物和其他相关产品的制造商。用户可以在 Babylist 上浏览各种不同的产品&#xff0c;并根据自己的需求和喜好选择适合的项目。本文将为大家介绍对接Babylist 的EDI项目案例。 Babylist EDI 需求 传输协…

升级8.0:民生手机银行的“内容解法”

数字化浪潮&#xff0c;滚滚来袭。 随着数字中国建设的持续推进&#xff0c;数字经济正在蓬勃发展。中商产业研究院分析师预测&#xff0c;2023年中国数字经济市场规模将增长至56.7万亿元&#xff0c;占GDP的比重将达到43.5%。 在此浪潮下&#xff0c;数字化的触角蔓延到各行…

[C++] opencv - copyTo函数介绍和使用案例

copyTo函数介绍 copyTo函数是OpenCV库中的一个成员函数&#xff0c;用于将一个Mat对象的内容复制到另一个Mat对象中。 函数原型&#xff1a; void cv::Mat::copyTo(OutputArray m) const;void cv::Mat::copyTo(OutputArray m, InputArray mask) const; 参数说明&#xff1a;…

指向未来: 量子纠缠的本质是一个指针

指向未来: 量子纠缠的本质是一个指针 概述基本概念理解量子纠缠PythonJavaC 理解波粒二象性PythonJavaC 理解量子隧穿理解宇宙常量PythonJavaC 概述 量子纠缠 (Quantum Entanglement) 是量子系统重两个或多个粒子间的一种特殊连接, 这种连接使得即使相隔很远, 这些粒子的状态也…

oracle11g的闪回技术-闪回表-时间戳

--数据库闪回表 --1创建表&#xff08;登录模式system&#xff09; CREATE table dept2 as select * from dept;--此语句如果加上where条件可用于工作中数据的临时备份 select * from dept2;--查询新建表信息 --进入sql>set time on 通过时间点闪回 记录弹出的时间点&#…

2024年linux内核开发会是程序员新的风口吗?

前言 众所周知&#xff0c;linux操作系统一直靠着稳定&#xff0c;安全&#xff0c;开源等优势占据着80%以上的服务器市场。小至私人企业&#xff0c;大至世界百强&#xff0c;都离不开它的身影。以至于无论你擅长的是哪门语言&#xff0c;面试的时候都会或多或少的涉及linux的…

物联网网关与plc怎么连接?

物联网网关与plc怎么连接&#xff1f; 物联网是当今社会中最热门的技术之一&#xff0c;而物联网网关则是连接物联网设备与云平台的核心设备之一。物联网网关在连接各种传感器和设备时起着至关重要的作用。而另一种广泛应用于工业控制和自动化领域的设备是可编程逻辑控制器&…

上海亚商投顾:沪指探底回升 大金融板块午后走强

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 指昨日探底回升&#xff0c;深成指、创业板指午后跌超1%&#xff0c;尾盘集体拉升翻红&#xff0c;北证50指数涨…

你知道怎么做好接口测试?

前言 谈起软件测试&#xff0c;就不得不说一下接口测试&#xff0c;凡是有功能的软件都离不开接口&#xff0c;没有接口的软件只是一个模具或页面&#xff0c;不具备任何功能。 什么是接口 业内常说的接口一般指两种&#xff1a; API&#xff1a;应用程序编程接口&#xff0c…

【unity】麦克风声音驱动,控制身体做出不同动作

1.在角色对象上挂在animator组件&#xff0c;并将动作控制器与其关联 2.在角色对象上挂在audio source组件。 3.新建voice control脚本&#xff0c;编写代码如下&#xff1a; using System; using System.Collections; using System.Collections.Generic; using UnityEngine;…

vue2 使用vuex状态管理工具 如何配置与搭建。

等我研究研究&#xff0c;下一期给大家出一个后台管理左侧侧边栏如何搭建的。 首先我们先下载一下 vuex包 yarn add vuex3 1.先导入我们需要的 Vue 和 vuex 2.注册vuex 3.创建vuex实例 4.导出store export default store 5.在main.js中导入并挂载到全局。 Vuex如何实…

C++编写、生成、调用so库详解(二)

我们上篇中主要讲了怎么去打包so库 C编写、生成、调用so库详解(一) 这篇我们就来说一些怎么调用so库 目录 1.调用符合JNI标准的so库 2.调用不符合JNI标准的so库 上面说了两种不同类型的so库,我们分别来看一下怎么调用这两种,在调用so库之前,我们先说一下直接调用上面写的C…

全球网络是如何互联的?

1.Internet 在之前的学习中我们知道了Internet和internet的区别&#xff0c;也知道了Internet目前是全球最大的网络&#xff0c;并且由很多规模不同的网络互联而成。到目前已经有超过90个国家接入了Internet&#xff0c;主机超过400万台&#xff0c;可以说Internet是全人类的信…

【Ubuntu18.04安装Labelme】

Ubuntu18.04安装Labelme 1 安装Anaconda并创建conda环境2 安装依赖3 安装Labelme4 安装验证 1 安装Anaconda并创建conda环境 Anaconda3安装教程&#xff1a;https://blog.csdn.net/dally2/article/details/108206234 "ctrlaltt"快捷键打开终端&#xff0c;创建conda…