【C语言】指针的“最后一站”【进阶版】

 欢迎各位看官^_^

目录

1、字符指针

2、指针数组

3、数组指针

3.1数组指针的定义

3.2数组指针的使用 

4、数组指针和指针数组的区别

5、数组参数,指针参数

5.1数组参数定义

5.2指针参数定义 

5.3一维数组传参

5.4二维数组传参

5.5一级指针传参

5.6二级指针传参 

6、函数指针

7、函数指针数组

8、指向函数指针数组的指针

9、函数指针和指针函数的差别

10、回调函数


1、字符指针

        字符指针是指一个指向字符数组(或字符串)的指针变量。 它可以用来指向一个字符串常量或动态分配的字符数组,可以通过指针来访问数组中的每一个字符。

        在C语言中,字符指针通常用于字符串的处理,可以使用字符串函数(如strcpy、strlen、strcat等)对指针所指向的字符串进行处理和操作。

char* str = "Hello";   //定义一个字符指针,指向字符串常量"Hello"
printf("%c\n", *str);  //输出字符'H'

         另一种常见的用法是动态分配一个字符数组,并使用字符指针指向该数组,例如:

char* str = (char*) malloc(10 * sizeof(char));  //动态分配一个大小为10的字符数组
strcpy(str, "Hello");   //将字符串"Hello"复制到数组中
printf("%s\n", str);    //输出字符串"Hello"

2、指针数组

        指针数组是一个数组,其元素都是指针类型。 每个指针元素都可以指向不同的内存地址,从而使整个数组成为一个指向多个不同对象的数组。 指针数组在C/C++编程中很常用,特别是在动态内存分配和字符串处理等方面。 例如,可以通过指针数组来存储多个字符串,每个指针元素都指向一个字符串的起始地址。 

        指针数组的创建方式与普通数组类似,只是数组元素类型为指针类型。 创建指针数组的步骤如下:

1.声明指针数组的变量名和类型:指针数组的类型是由元素类型和数组长度共同决定的,可以使用如下语法声明指针数组:

int* arr[10];

        上述语句表示声明了一个包含10个int指针元素的指针数组,每个数组元素可以指向一个int类型的变量或数组。

2.分配内存空间:指针数组存储的是指针类型的变量,每个数组元素需要单独分配内存空间。 可以使用如下语法来为指针数组分配内存:

for(int i=0; i<10; i++){arr[i] = (int*)malloc(sizeof(int));
}

        上述语句使用循环为每个数组元素分配了一个int类型的内存空间,并将其地址赋值给指针数组的对应元素。

3.使用指针数组:指针数组可以像普通数组一样使用,例如可以使用下标操作符[]来访问数组元素,也可以通过指针数组访问存储在其他内存位置的数据。

*arr[0] = 10;  //为第一个元素指向的内存存储赋值
int a = *arr[0]; //获取第一个元素指向的内存存储的值

3、数组指针

3.1数组指针的定义

        数组指针是一种指针类型,它指向一个数组。 它是指向数组第一个元素的指针,而不是指向数组本身。 在定义数组指针时需要指定指针类型和数组类型,并使用“*”符号来标识指针类型。 例如,定义一个int类型的数组指针:

int arr[5];
int *p = arr;

        其中,p是一个指向arr数组的指针,它指向arr[0]元素的地址。 数组指针可以用于访问数组元素,可以使用p[index]的方式来访问数组中的元素,其中index表示要访问的元素的下标。

3.2数组指针的使用 

        数组指针可以用来访问二维数组中的元素。 一个数组指针指向一个一维数组,而一个二维数组可以理解为一系列的一维数组。 因此,通过使用数组指针,可以访问这些一维数组。

例如,假设有一个二维数组:

int arr[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};

        我们可以使用指向整数的指针来定义一个指向第二行的指针:

int *p = arr[1];

        此时,p指向的是数组中的第五个元素(即arr[1][0]),我们可以使用指针运算符来访问其它的元素:

p[0]; // 5
p[1]; // 6
p[2]; // 7
p[3]; // 8

        我们还可以使用指向整型指针的指针来定义一个指向整个二维数组的指针:

int (*p2)[4] = arr;

        此时,p2指向的是整个二维数组的第一个元素,我们可以使用指针运算符来访问其它的元素:

p2[0][0]; // 1
p2[0][1]; // 2
p2[1][0]; // 5
p2[2][3]; // 12

4、数组指针和指针数组的区别

        数组指针和指针数组是两个不同的概念。

        数组指针指向一个数组,它本身是一个指针变量,只不过这个指针变量指向的是一个数组。

        指针数组是一个数组,其中每个元素都是一个指针。它本身是一个数组,只不过这个数组中的每个元素都是指针。

        在使用时,数组指针和指针数组的访问方式也不同。对于数组指针,我们可以使用指针运算符来访问数组中的元素;而对于指针数组,我们需要先访问数组中的某个元素,再使用指针运算符来访问该元素指向的对象。

举个例子,对于一个数组指针,我们可以这样访问它所指向的第一个元素:

int arr[3][4] = {{1, 2, 3, 4},{5, 6, 7, 8},{9, 10, 11, 12}
};
int (*p)[4] = arr;  //定义数组指针p,指向arr的第一行
int *p1 = *p;  //取得p指向的第一行的指针
int val = p1[0];  //访问第一个元素,即arr[0][0]

        而对于一个指针数组,我们可以这样访问它的第一个元素:

int a = 1, b = 2, c = 3;
int *arr[] = {&a, &b, &c};  //定义指针数组arr,包含3个int型指针元素
int *p = arr[0];  //访问arr的第一个元素,即&a
int val = *p;  //val的值为1,即a的值

        因此,数组指针和指针数组虽然有相似的地方,但在定义和使用上还是有较大的区别的。

5、数组参数,指针参数

5.1数组参数定义

        在C语言中,可以将数组作为函数的参数传递。传递数组参数时,可以使用以下两种方法:

1. 将数组名作为指针传递:

void func(int* array, int num_elements) {// ...
}int main() {int my_array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};func(my_array, 10);return 0;
}

2. 将数组名作为数组传递:

void func(int array[], int num_elements) {// ...
}int main() {int my_array[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};func(my_array, 10);return 0;
}

        注意:在传递数组参数时,需要同时传递数组的大小,因为C语言不支持在函数内部获取数组的大小。可以在函数参数中传递数组大小,也可以使用预定义的常量或者宏定义来传递数组大小。

5.2指针参数定义 

        在C语言中,可以通过指针参数来实现函数内部对变量值的修改,也可以通过指针参数来实现函数间的数据共享。指针参数的一般形式为:

void func(int *ptr);

        其中,`int *ptr`表示一个指向整型变量的指针,也可以理解为一个整型变量的地址。

在函数内部,可以通过`*ptr`来访问该地址对应的变量,例如:

void func(int *ptr) {*ptr = 100;  // 修改指向的变量的值为100
}

同时,也可以将该指针指向另外一个变量的地址,例如:

void func(int *ptr) {int a = 100;ptr = &a;   // 将指针指向变量a的地址
}

        但是需要注意的是,这里的指针参数只是函数内部的一个局部变量,对它的修改不会影响函数外部的指针变量。如果需要改变函数外部的指针变量,可以使用双重指针(指向指针的指针)或者引用参数等方法来实现。

5.3一维数组传参

        在C语言中,一维数组可以通过指针来进行传参。具体步骤如下:

1. 定义函数时,需要将数组参数定义为指针类型:

void myFunction(int *arr, int size);

2. 在调用函数时,直接传入数组的名称即可:

int myArray[10];
myFunction(myArray, 10);

3. 在函数中使用指针来访问数组中的元素:

void myFunction(int *arr, int size) {for (int i = 0; i < size; i++) {printf("%d ", arr[i]);}
}

        注意:数组参数在函数中仍然是指针,因此可以使用指针运算来访问数组元素。另外,由于C语言传参是值传递,因此如果需要修改数组中的元素,需要使用指针来实现。

5.4二维数组传参

        在C语言中,可以通过指针来传递二维数组。由于C语言中二维数组本质上是一维数组的数组,因此可以将其视为指向一维数组的指针。传递二维数组时,需要指定数组的行数和列数。下面是一个示例:

#include <stdio.h>void printArray(int arr[][3], int rows, int cols)
{for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {printf("%d ", arr[i][j]);}printf("\n");}
}int main()
{// 定义一个二维数组int arr[2][3] = {{1, 2, 3}, {4, 5, 6}};// 调用函数打印数组printArray(arr, 2, 3);return 0;
}

        在上面的示例中,`printArray` 函数接受一个二维数组 `arr` 和数组的行数和列数 `rows` 和 `cols` 作为参数。函数内部使用两个嵌套的循环遍历整个二维数组并打印每个元素的值。

        在 `main` 函数中,定义了一个二维数组 `arr` 并初始化。然后调用 `printArray` 函数传递数组 `arr` 和 `2` 和 `3` 作为行数和列数的参数来打印数组的值。

5.5一级指针传参

        在C语言中,可以通过一级指针来传递参数。一级指针是指指向变量的指针,可以通过指针操作符(*)来间接访问指针所指向的变量。

下面是一个例子,演示了如何在函数中使用一级指针来传参:

#include <stdio.h>// swap函数用来交换两个整数
void swap(int *a, int *b) {int tmp = *a;*a = *b;*b = tmp;
}int main() {int x = 10, y = 20;printf("Before swapping: x = %d, y = %d\n", x, y);// 传递指向x和y的指针给swap函数swap(&x, &y);printf("After swapping: x = %d, y = %d\n", x, y);return 0;
}

        在上面的代码中,我们定义了一个函数`swap()`,这个函数接受两个指向整数的指针。我们在`main()`函数中声明了两个整数变量`x`和`y`,然后通过`&`运算符来获取它们的地址,并将这些地址作为参数传递给`swap()`函数。在`swap()`函数中,我们通过指针操作符(*)来获取变量的值,并通过交换它们来实现了两个整数的交换。

        需要注意的是,当我们传递指针作为参数时,如果函数修改了指针所指向的变量的值,那么函数结束后这些修改会被保留下来。 因此,一级指针可以被用来实现类似于返回多个值的操作。

5.6二级指针传参 

        在C语言中,指针是一种非常重要的数据类型,它可以保存变量的内存地址,从而通过指针来操作变量。而二级指针则更为复杂,它可以保存指向指针变量的指针的内存地址。二级指针在传递函数参数时,可以通过该指针来改变函数外部的指针变量。

以下是C语言使用二级指针传参的示例:

#include<stdio.h>
void func(int **pp) {int a = 10;*pp = &a;
}int main() {int *p;func(&p); // 传递指向指针变量的指针printf("%d", *p); // 输出a的值,但由于a的生命周期已结束,此处输出的值不确定return 0;
}

        在上述示例中,函数`func`接收一个指向指针变量的指针,并将其指向一个局部变量`a`的地址。在`main`函数中,通过传递指向指针变量的指针`&p`来改变指针变量`p`的地址,从而使其指向了`a`的地址。但由于`a`是局部变量,当`func`函数执行完毕后,`a`的生命周期已经结束,因此输出`*p`的值是不确定的。

        需要注意的是,如果在函数`func`中不使用双重指针的方式来修改指针变量的值,则只会影响到函数内部的指针变量,无法改变函数外部的指针变量。因此在需要修改指针变量的值时,需要使用二级指针来传递参数。

6、函数指针

        C语言函数指针是指向函数的指针变量,它可以存储函数的地址并调用该函数。在C语言中,定义函数指针的方法是将函数名作为指针变量的类型,然后在使用指针变量时,用它来调用函数。

        以下是一个简单的函数指针的例子,它声明一个指向函数的指针变量,然后将函数的地址赋值给指针变量并调用该函数:

#include <stdio.h>int add(int a, int b) {return a + b;
}int main() {int (*func_ptr)(int, int) = &add;int result = (*func_ptr)(10, 5);printf("%d", result);  // 输出 15return 0;
}

        在上面的例子中,我们声明了一个指向函数的指针变量 `func_ptr`,并将函数 `add` 的地址赋值给它。然后,我们通过指针变量调用 `add` 函数,并将结果存储在 `result` 变量中。最后,我们打印 `result` 变量的值,输出 15。

7、函数指针数组

        函数指针数组是数组中的每个元素都是函数指针的数据结构。在 C 语言中,函数指针是指向函数的指针变量。函数指针可以被用来调用函数,或者用来作为参数传递给其它函数。

下面是一个例子,展示如何声明和使用函数指针数组:

#include <stdio.h>int add(int a, int b) {return a + b;
}int subtract(int a, int b) {return a - b;
}int multiply(int a, int b) {return a * b;
}int main() {int (*func_ptr[3]) (int, int);func_ptr[0] = &add;func_ptr[1] = &subtract;func_ptr[2] = &multiply;int a = 10, b = 5;for (int i = 0; i < 3; i++) {int result = (*func_ptr[i])(a, b);printf("The result is: %d\n", result);}return 0;
}

        在上面的例子中,`func_ptr`是一个函数指针数组,其中有三个元素,每个元素都是一个指向函数的指针。在 `main` 函数中,我们将 `add`、`subtract` 和 `multiply` 函数的地址分别赋予 `func_ptr` 数组中的相应元素。

        在循环中,我们通过 `(*func_ptr[i])(a, b)` 的方式来调用函数指针数组中的每个元素。注意到我们使用了 `(*)` 操作符来解引用函数指针,这是因为函数名本身在 C 语言中就是函数的地址,使用 `(*)` 操作符可以将函数指针解引用,得到函数的返回值。

该程序的输出结果是:
The result is: 15
The result is: 5
The result is: 50

        对于这个例子,我们可以看到函数指针数组可以用来简化代码,提高程序的灵活性和可维护性。根据需要,我们可以改变函数指针数组中的元素,来调用不同的函数或者实现不同的功能。

8、指向函数指针数组的指针

在C语言中,指向函数指针数组的指针可以通过以下方式声明:

typedef void (*FuncPtr)(int);  // 声明一个函数指针类型
FuncPtr func[3];               // 声明一个函数指针数组
FuncPtr (*funcP)[3];           // 声明一个指向函数指针数组的指针

        上述代码中,先定义了一个函数指针类型 `FuncPtr`,它可以指向一个具有一个int类型参数和void返回类型的函数。然后定义了一个函数指针数组 `func`,它包含3个元素,每个元素都是一个函数指针。最后,定义了一个指向函数指针数组的指针 `funcP`,它指向包含3个 `FuncPtr` 类型元素的数组。

        由于 `func` 是一个函数指针数组,因此它可以按照常规方式进行初始化:

void func1(int x) { printf("Func1: %d\n", x); }
void func2(int x) { printf("Func2: %d\n", x); }
void func3(int x) { printf("Func3: %d\n", x); }func[0] = func1;
func[1] = func2;
func[2] = func3;

        然后,将指向函数指针数组的指针 `funcP` 指向 `func` 数组的首地址:

funcP = &func;

        现在,可以使用指针 `funcP` 来调用函数指针数组中的任何一个函数指针:

(*funcP)[0](10);  // 调用func1函数指针,传入参数10
(*funcP)[1](20);  // 调用func2函数指针,传入参数20
(*funcP)[2](30);  // 调用func3函数指针,传入参数30

9、函数指针和指针函数的差别

        函数指针和指针函数是两个不同的概念。虽然它们都涉及指向函数或指向指针的指针,但它们在语法和语义上有不同的含义。

·函数指针是一个指向函数的指针,它存储函数的地址,可以像函数调用一样使用它。函数指针在C语言中被广泛使用,通常用于实现回调函数、动态函数调用和函数指针数组等。
  
        例如,下面的代码定义了一个函数指针`fp`,它指向一个函数,该函数有两个`int`类型的参数并返回一个`int`类型的值:

int (*fp)(int, int);

·指针函数是一个返回指针的函数,它本身是一个函数,但返回值是指针类型。指针函数也在C语言中使用,通常用于分配内存、字符串操作和复杂数据结构的声明等。

         例如,下面的代码定义了一个指针函数`func`,它返回一个指向`int`类型的指针:

int* func();

        所以,函数指针和指针函数虽然都涉及指向指针的指针,但它们的概念和用法是不同的。函数指针是指向函数的指针,指向函数的地址,而指针函数是函数,返回一个指针类型的指针。

10、回调函数

        C语言回调函数是一种函数指针,用于在一段代码中传递一个函数,以供另一段代码调用。

        回调函数通常用于实现事件驱动编程,即当某个事件发生时,调用预定义的回调函数进行处理。例如,当用户按下一个按钮时,回调函数可以执行与该按钮相关的操作。

以下是一个C语言回调函数的示例:

#include <stdio.h>typedef void (*callback_t)(int);void process(callback_t callback) {printf("Processing...\n");callback(42);
}void callback_function(int value) {printf("Callback received value: %d\n", value);
}int main() {process(callback_function);return 0;
}

        在上面的示例中,`process`函数接受一个类型为`callback_t`的函数指针作为参数,并在该函数内部调用该函数指针。`callback_function`函数是一个预定义的回调函数,它接受一个`int`类型的参数,并输出该参数的值。

        在`main`函数中,我们将`callback_function`作为参数传递给`process`函数,然后程序输出以下内容:


Processing...
Callback received value: 42
 

        这表明`process`函数成功地调用了我们传递的回调函数,并将参数`42`传递给它。

 🤞❤️🤞❤️🤞❤️指针的知识点总结就到这里啦,如果对博文还满意的话,劳烦各位看官动动“发财的小手”留下您对博文的赞和对博主的关注吧🤞❤️🤞❤️🤞❤️

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

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

相关文章

《Docker 容器化的艺术:深入理解容器技术》

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f405;&#x1f43e;猫头虎建议程序员必备技术栈一览表&#x1f4d6;&#xff1a; &#x1f6e0;️ 全栈技术 Full Stack: &#x1f4da…

javaweb04-vue基础

话不多说&#xff0c;参考官网地址Vue官网集成Vue应用。 一、Vue快速入门 &#xff08;1&#xff09;新建HTML页面&#xff0c;引入Vue.js 我这里用的是CDN方式 <script src"https://unpkg.com/vue3/dist/vue.global.js"></script> &#xff08;2&am…

windows10系统下Python3.11中安装Numpy库教程

Python3.11中安装Numpy库目录 项目场景&#xff1a;问题描述解决方案&#xff1a;①下载Numpy文件②把NumPy文件放到Python安装的Scripts文件夹里。③安装numpy④安装验证 项目场景&#xff1a; numpy是开源的数值计算扩展&#xff0c;用于数据分析、机器学习、科学计算的重要…

【Java 基础篇】Java TreeSet 详解:红黑树实现的有序集合

Java 集合框架提供了多种数据结构&#xff0c;用于存储和操作数据。其中&#xff0c;TreeSet 是一种特殊类型的集合&#xff0c;它通过红黑树&#xff08;Red-Black Tree&#xff09;数据结构实现了有序的、唯一元素存储。本篇博客将深入探讨 TreeSet&#xff0c;包括其概念、特…

小程序中使用分包

前言 小程序在未使用的分包的情况下仅支持大小为2M,如果图片等资源过多的情况下可以使用分包功能&#xff0c;使用分包的情况下单个分包大小不能超过2M,总大小不能超过20M&#xff0c;分包有两种情况&#xff1a;普通分包和独立分包&#xff0c;下面介绍的是普通分包。官方文档…

《向量数据库指南》——哪些需求推动了如Milvus Cloud等的向量数据库的更新和迭代?

这个问题需要深入讨论大模型与向量数据库之间的关系。从去年 ChatGPT 推出时这个问题就开始引发我们的思考。在当时,我们敏锐地意识到这将是一个机遇。然而,在国内,这个概念的认知需要更长的时间。我个人在去年四五月份的美国之行中注意到,数据库在美国已经是一个非常热门的…

算法通关村第十九关:青铜-动态规划是怎么回事

青铜挑战-动态规划是怎么回事 动态规划&#xff08;简称DP&#xff0c;Dynamic Programming&#xff09;&#xff1a;最热门、最重要的算法之一。面试中大量出现&#xff0c;整体偏难。 1. 热身&#xff1a;重复计算和记忆化搜索&#xff08;如何说一万次"我爱你"&…

【LeetCode-中等题】59. 螺旋矩阵 II

文章目录 题目方法一&#xff1a;二维数组缩圈填数字方法二&#xff1a; 题目 方法一&#xff1a;二维数组缩圈填数字 定义四个边界条件&#xff0c;每转一圈&#xff0c;把数值填进去&#xff0c;然后缩小一圈&#xff0c;直到不满足条件位置 结束循环条件可以是&#xff1a; …

QML android 采集手机传感器数据 并通过udp 发送

利用 qt 开发 安卓 app &#xff0c;采集手机传感器数据 并通过udp 发送 #ifndef UDPLINK_H #define UDPLINK_H#include <QObject> #include <QUdpSocket> #include <QHostAddress>class UdpLink : public QObject {Q_OBJECT public:explicit UdpLink(QObjec…

使用ExcelJS快速处理Node.js爬虫数据

什么是ExcelJS ExcelJS是一个用于处理Excel文件的JavaScript库。它可以让你使用JavaScript创建、读取和修改Excel文件。 以下是ExcelJS的一些主要特点&#xff1a; 支持xlsx、xlsm、xlsb、xls格式的Excel文件。可以创建和修改工作表、单元格、行和列。可以设置单元格样式、字…

leetcode:67. 二进制求和

题目&#xff1a; 函数原型&#xff1a; char * addBinary(char * a, char * b) 思路&#xff1a; 二进制相加&#xff0c;首先我们考虑先将字符串逆序。由此要写一个逆序函数reserve。字符串逆序后&#xff0c;从前往后相加&#xff0c;以较长的字符串的长度为标准长度n&#…

可视化大屏设计模板 | 主题皮肤(报表UI设计)

下载使用可视化大屏设计模板&#xff0c;减少重复性操作&#xff0c;提高报表制作效率的同时也确保了报表风格一致&#xff0c;凸显关键数据信息。 软件&#xff1a;奥威BI系统&#xff0c;又称奥威BI数据可视化工具 所属功能板块&#xff1a;主题皮肤上传下载&#xff08;数…

Python实现机器学习(下)— 数据预处理、模型训练和模型评估

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。本门课程将介绍人工智能相关概念&#xff0c;重点讲解机器学习原理机器基本算法&#xff08;监督学习及非监督学习&#xff09;。使用python&#xff0c;结合sklearn、Pycharm进行编程&#xff0c;介绍iris&#xff08;鸢尾…

Excel学习 WPS版

Excel学习 1.界面基础1.1 方格移动快捷键1.2 自动适配文字长度1.3 跨栏置中1.4 多个单元格同宽度&#xff1a;1.5 下拉框选择1.6 打印预览1.7 绘制边框1.8 冻结一行多行表头1.9 分割视图 2.日期相关2.1 今日日期快捷键2.2 月份提取 3.数学公式3.1 自动增长3.2 排序3.3 筛选3.4 …

数据结构——排序算法——冒泡排序

冒泡排序1 void swap(vector<int> arr, int i, int j) {int temp arr[i];arr[i] arr[j];arr[j] temp;}void bubbleSort1(vector<int> arr) {for (int i 0; i < arr.size() - 1; i){for (int j 0; j < arr.size() - 1 - i; j){if (arr[j] > arr[j 1…

【Unity编辑器扩展】| 顶部菜单栏扩展 MenuItem

前言【Unity编辑器扩展】 | 顶部菜单栏扩展 MenuItem一、创建多级菜单二、创建可使用快捷键的菜单项三、调节菜单显示顺序和可选择性四、创建可被勾选的菜单项五、右键菜单扩展5.1 Hierarchy 右键菜单5.2 Project 右键菜单5.3 Inspector 组件右键菜单六、AddComponentMenu 特性…

人工智能:神经细胞模型到神经网络模型

人工智能领域中的重要流派之一是&#xff1a;从神经细胞模型&#xff08;Neural Cell Model&#xff09;到神经网络模型&#xff08;Neural Network Model&#xff09;。 一、神经细胞模型 第一个人工神经细胞模型是“MP”模型&#xff0c;它是由麦卡洛克、匹茨合作&#xff0…

Java-华为真题-预定酒店

需求&#xff1a; 放暑假了&#xff0c;小王决定到某旅游景点游玩&#xff0c;他在网上搜索到了各种价位的酒店&#xff08;长度为n的数组A&#xff09;&#xff0c;他的心理价位是x元&#xff0c;请帮他筛选出k个最接近x元的酒店&#xff08;n>k>0&#xff09;&#xff…

通常用哪些软件做数据可视化大屏?

一般就两种&#xff0c;一种是可视化大屏编辑软件&#xff0c;另一种则是BI系统&#xff08;BI数据可视化工具&#xff09;。考虑到数据来源多、数据量大以及数据分析效率、直观易懂性等实实在在的客观问题&#xff0c;建议采用BI系统来制作数据可视化大屏。 BI系统做可视化大…

【SpringMVC】JSR 303与interceptor拦截器快速入门

目录 一、JSR303 1、什么是JSR 303&#xff1f; 2、为什么要使用JSR 303&#xff1f; 3、JSR 303常用注解 3.1、常用的JSR 303注解 3.2、Validated与Valid区别 3.2.1、Validated 3.2.2、Valid 3.2.3、区别 4、使用案例 4.1、导入依赖 4.2、配置校验规则 4.3、编写…