C 语言指针进阶
1.0 指针的定义
指针是内存中一个最小单元的编号(内存单元的编号称之为地址【地址就是指针指针就是地址】)指针通常是用来存放内存地址的一个变量。本质上指针就是地址:口语上说的指针起始是指针变量,指针变量就是一个变量,是一个用于存放地址的变量,指针指向的就是地址,通过这个地址可以找到对应的内存单元。
指针变量创建:
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/*
****************************
* DEF : 指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/14
* 作者 : _沧浪之水_
****************************
*/int main()
{// a 是一个整型变量,占用4个字节内存空间int a = 10;// pa 是一个指针变量,指针变量是用来存放地址的int* pa = &a;return 0;
}
总的来说,指针变量是用于存放地址的变量,(存放在指针中的值被当做是地址处理),在32位的平台下一个指针变量的大小是4个字节,在64位地址的机器上指针变量的大小是8个字节。
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/*
****************************
* DEF : 指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/14
* 作者 : _沧浪之水_
****************************
*/int main()
{char *pc = NULL;short *ps = NULL;int *pi = NULL;double *pd = NULL;printf("%zu\n", sizeof(pc));printf("%zu\n", sizeof(ps));printf("%zu\n", sizeof(pi));printf("%zu\n", sizeof(pd));return 0;
}
2.0 指针与指针类型
指针类型的含义
1. 指针的类型决定的指针被解引用的时候被访问几个字节【所谓的解引用是官方的叫法,实际上就去获取地址当中的值,或者说是将地址当中的值取出来】,例如:int * 的指针,解引用访问4个字节,char * 的指针解引用是访问一个字节,推广到其他的参数时也是一样的。
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/*
****************************
* DEF : 指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/14
* 作者 : _沧浪之水_
****************************
*/int main()
{int a = 0x11223344;int* pa = &a;*pa = 0;char* pc = (char*)&a;*pc = 0;return 0;
}
2. 指针的步长:理解指针步长的意义
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/*
****************************
* DEF : 指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/14
* 作者 : _沧浪之水_
****************************
*/int main()
{int a = 0x11223344;int* pa = &a;char* pc = (char *) & a;printf("pa = %p\n", pa);printf("pa = %p\n", pa + 1);printf("pa = %p\n", pc);printf("pa = %p\n", pc + 1);return 0;
}
指针类型决定了访问内存一次可以访问几个字节,如果是char * 的指针类型,那么访问内存只能一个字节一个字节的进行访问,如果是int * 类型的指针类型,那么访问内存就是以一次4个字节进行访问, int * pc如果是pc + 1 的话那么就是跳过前面的4个字节。
注:不同类型指针占用类型大小相同的指针是不能混用的,因为两者存储在内存中的空间是不同的,int 类型存储的是int类型,float类型存储的是float类型。
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/*
****************************
* DEF : 指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/14
* 作者 : _沧浪之水_
****************************
*/int main()
{int a = 0;int* pi = &a; // pi 解引用访问4个字节,pi + 1 也是跳过4个字节float* pf =(float *)& a;// pf 解引用访问4个字节,pf + 1 也是跳过4个字节return 0;
}
3.0 野指针,指针,与指针运算
野指针的概念:指的是指针指向的位置是不可知的
int main
{// p没有初始化,就意味着没有明确的指向// 一个局部变量不初始化,放的是随机值int *p;// 这样做的方式就是非法的访问内存,这个时候p就是野指针*p = 10;
}
#define _CRT_SECURE_NO_WARNINGS
#include "stdio.h"
#include "stdlib.h"
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>/*
****************************
* DEF : 指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/14
* 作者 : _沧浪之水_
****************************
*/int main()
{int arr[10] = { 0 };// 数组名表示数组首元素地址arr[0]int* p = arr;// 指针的越界访问也会造成野指针for (int i = 0; i <= 10; i++) {*p = i;p++;}return 0;
}
野指针:涉及到局部变量和全局变量知识
函数执行进入主函数:main
这个时候test() 函数被调用
通过return 返回a的地址地址返回后int a 由于数局部变量出函数之后被销毁
这个时候 int *p 通过地址可以找到a这个空间
但是这个时候a空间已经被销毁,p这个时候无法访问和使用这个空间,这个时候这个p属于是野指针。
int * test()
{int a = 10;return &a;
}int main()
{int *p = test();return 0;
}
4.0 如何避免野指针
NULL 的值相当于是0 ,0 空间是没有办法被指针访问的,避免野指针的方式可以在初始化不知道赋值为什么的时候赋值为一个NULL也就是空指针,同时在使用之前先判断指针是否为空,如果指针为空就不使用,如果指针不为空的时候就对指针变量进行相应的操作,具体的示例如下所示。
避免野指针:
1: 指针初始化,
2:小心数组下标越界,
3:指针指向空间释放及时设置为NULL,
4:避免返回局部变量的地址,
5:使用指针之前先检查指针的有效性。
int * p = NULL;
int mian(void)
{if(p != NULL){*p3 = 100;}return 0;}
指针加减整数运算
#define N_VALUE 5
float values[N_VALUES];
float *vpfor(vp = &values[0]; vp < &values[N_VALUES];)
{*vp++ = 0;
}
int main(void)
{int arr[10] = { 0 };int i = 0;int sz = sizeof(arr)/sizeof(arr[0]);for(i = 0; i < sz; i++){// 把数组里面的值全部赋值为 1arr[i] = 1;}// int 类型的指针变量p,数组名等于数组首元素的地址int *p = arr;for(i = 0; i < sz; i++){// *P 解引用:也就是取值的意思*p = 1;p++;}// 使用指针步长的方式访问数组,进行数组操作for(i = 0; i < sz; i++){*(p + 1) = 1;}return 0;}
5.0 指针加减指针
int main(void)
{// 指针减去指针得到的绝对值得到的是指针之间元素的个数// 不是所有的指针都能相减,指向同一块空间的指针才能相减int arr[10] = { 0 };printf("%d\n",&arr[9] - &arr[0]); // 9
}
字符串长度:使用指针减去指针的方式
int my_strlen(char *str)
{*// str 刚开始起始地址是aint count = 0;while(*str != '\0'){count++;str++;}return count;
}
// 指针 - 指针
int my_strlen(char *str)
{char *start = str;while(*str != '\0'){str++;}return (str - start);}int main(void)
{int len = my_strlen("abcdef");printf("%d\n",len);}
指针的关系运算
#define N_VALUES 5
float values[N_VALUES]
float *vp;for(vp = &values[N_VALUES]; vp > &values[0];)
{*--p = 0;
}
C 语言标准规定指向指针的元素与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
指针遍历访问数组
数组的定义:数组是一组相同元素的集合,指针变量是一个变量,存放的是地址,数组的数组名是首元素的地址 。
int main(void)
{int arr[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int *p = arr;int len = sizeof(arr)/sizeof(arr[0]);int i = 0for(i = 0; i < len; i++){printf("%d ",*(p + i));}for(i = 0; i < len; i++){// 打印输出的地址结果是相同的printf("%p-----------------%p\n",&arr[i],p + i);}return 0;
}
6.0 二级指针
引入一级指针的概念:
int a = 10 ; a 是一个int 类型的变量初始值为10
int * pa = &a; pa是一个指针,pa是一个指向int 类型的指针变量,
&a 把 变量a在内存中的地址赋值给指针变量pa ,pa可以通过这个地址找到a并获取a在变量当中的值并修改同时打印输出。
int main()
{int a = 10;// pa 是一个一级指针变量int* pa = &a;*pa = 20;printf("%d ", a);return 0;
}
二级指针变量:程序输出的值是 30 注意理解:int **ppa 中
int main()
{int a = 10;// pa 是一个一级指针变量int* pa = &a;int** ppa = &pa;**ppa = 30;printf("%d ", a);return 0;
}
二级指针存放的是一级指针变量的地址
int main() {int a = 10;// pa 是一个一级指针变量int* pa = &a;int** ppa = &pa;**ppa = 30;printf("%d ", a);return 0; }
7.0 指针数组
【指针数组:存放指针的数组就是指针数组】
int main()
{int a = 10;int b = 20;int c = 30;int arr[10];int* pa = &a;int* pb = &b;int* pc = &c;// parr 是存放指针的数组,称之为指针数组int* parr[10] = { &a, &b, &c };int i = 0;int len = sizeof(parr) / sizeof(parr[0]);for (i = 0; i < len; i++) {printf("%d ", *(parr[i]));}return 0;
}
【补充:二维数组创建与遍历】
/*
****************************
* DEF : 二级指针
* 参数 : 无参数
* 返回值 : 无返回值
* 时间 : 2024/7/15
* 作者 : _沧浪之水_
****************************
*/int main()
{int arr[3][4] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};int i = 0;int j = 0;for (i = 0; i < 3; i++) {for (j = 0; j < 4; j++) {printf("%d ", arr[i][j]);}printf("\n");}return 0;
}
指针模拟二维数组
int main()
{int arrOne [4] = { 1, 2, 3, 4 };int arrTwo [4] = { 2, 3, 4, 5 };int arrThree[4] = { 6, 7, 8, 9 };int* parr[3] = { arrOne, arrTwo, arrThree };int i = 0;for (i = 0; i < 3; i++) {int j = 0;for (j = 0; j < 4; j++) {printf("%d ", parr[i][j]);}printf("\n");}return 0;
}
字符指针
#define _CRT_SECURE_NO_WARNINGS
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
#include <stdio.h>int main()
{char ch = 'c';char* p = &ch;*p = 'b';printf("%c\n", ch);const char* pc = "abcdef";printf("%s\n", pc);return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
#include <stdio.h>int main()
{const char* p1 = "abcdef";const char* p2 = "abcdef";char arr1[] = "abcdef";char arr2[] = "abcdef";if (p1 == p2) {printf("p1 == p2\n");}else {printf("p1 != p2\n");}if (arr1 == arr2) {printf("arr1 == arr2\n");}else {printf("arr1 != arr2\n");}return 0;
}
8.0 指针数组
int arr[10]; // 表示整形数组
char ch[5]; // 表示字符数组
int *arr[6]; // 存放整形指针的数组
char * arr[5] // 存放字符类型的数组
int* parr[MAX_ARR_NUM] = { arr1, arr2, arr3 };
以上这段代码的含义是 创建指针数组 parr
注: parr 是一个指针变量 ,指向的是一个数组,数组中存放了三个变量,也就是数组元素的首地址,每个变量的类型是int * 【也就是创建了一个int* 类型,变量名字叫做parr的数组指针,执行每个数组元素的首地址,每个数组元素的类型为 int 】
#define _CRT_SECURE_NO_WARNINGS
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
#include <stdio.h>#define MAX_ARR_NUM 3int main()
{int arr1[] = { 1,2,3,4,5 };int arr2[] = { 1,2,3,4,5 };int arr3[] = { 1,2,3,4,5 };// 数组名表示数组首元素地址,数组指针存放的是三个数组的地址int* parr[MAX_ARR_NUM] = { arr1, arr2, arr3 };int i = 0;for (i = 0; i < MAX_ARR_NUM; i++) {int j = 0;for (j = 0; j < 5; j++) {// *(parr + i ) == p [i];printf("%d ", parr[i][j]);printf("%d ", *(parr[i] + j));}printf("\n");}return 0;
}
注:*(parr + i) 等价于 parr[i] ,所以上面的代码有两种不同的遍历办法
以下是一些数组地址的补充阐释,为了更好的理解下面的知识
[数组指针 --- 指针-------指向数组的指针]
整型指针-------指向整型的指针
字符指针------指向字符的指针
int* p[10] p 是指针数组
int (*p)[10] p 是一个数组指针,p可以指向一个数组,该数组有10个元素,每个元素是int 类型。
数组名的理解
数组名通常表示数组首元素的地址,但是有两个例外,
1.sizeof(数组名),这里的数组表示的是整个数组,计算的是整个数组的大小,
2.&数组名,这里的数组名表示的依然是整个数组。所以取出的是整个数组的地址
#define _CRT_SECURE_NO_WARNINGS
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
#include <stdio.h>#define MAX_ARR_NUM 3int main()
{int arr[10] = { 0 };printf("%p\n", arr);printf("%p\n", &arr[0]);int sz = sizeof(arr);printf("%d\n", sz);return 0;
}
#define _CRT_SECURE_NO_WARNINGS
#include "math.h"
#include <string.h>
#include "add.h"
#include <stdint.h>
#include <stdio.h>#define MAX_ARR_NUM 3int main()
{int arr[10] = { 0 };printf("%p\n", arr);printf("%p\n", arr + 1);printf("%p\n", &arr[0]);printf("%p\n", &arr[0] + 1);// 这是一个数组的地址,&arr取出的是整个数组printf("%p\n", &arr);// &数组名 + 1 表示的是跳过整个数组printf("%p\n", &arr + 1);int sz = sizeof(arr);printf("%d\n", sz);return 0;
}
数组指针是用于存放数组的地址
int main()
{// 数组:名字是arrint arr[10] = { 0 };// 指针: 数组名arr表示首元素的地址,将首元素的地址放到一个int类型的arr指针当中int* p = arr;// 数组指针:存放数组的地址,表示的是一个int类型的数组指针int(*p)[10] = &arr;return 0;
}
注意:上面的代码中 int * p = arr; p 是一个指针,指针的类型是 int * . int (*p)[10] = &arr ; 这是一一个数组指针,存储的是整个数组的,指针的类型是 int *[] 。
......
相关文章:

C 语言指针进阶
1.0 指针的定义 指针是内存中一个最小单元的编号(内存单元的编号称之为地址【地址就是指针指针就是地址】)指针通常是用来存放内存地址的一个变量。本质上指针就是地址:口语上说的指针起始是指针变量,指针变量就是一个变量&#…...

SpringBootWeb 篇-入门了解 Swagger 的具体使用
🔥博客主页: 【小扳_-CSDN博客】 ❤感谢大家点赞👍收藏⭐评论✍ 文章目录 1.0 Swagger 介绍 1.1 Swagger 和 Yapi 的使用场景 2.0 Swagger 的使用方式 2.1 导入 knife4j 的 maven 坐标 2.2 在配置类中加入 knife4j 相关配置 2.3 设置静态资源…...

Python面试题:如何在 Python 中处理大数据集?
在 Python 中处理大数据集可能面临许多挑战,包括内存限制、计算性能和数据处理效率等。以下是一些处理大数据集的常见方法和技术: 1. 使用高效的数据处理库 1.1 Pandas Pandas 是一个强大的数据分析库,可以处理中等大小的数据集࿰…...

C++:入门基础
1.命名空间 1.1namespace的价值 在C/C中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称都将存在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,避免命名冲突或者名字…...

微信小游戏 彩色试管 倒水游戏 逻辑 (二)
最近开始研究微信小游戏,有兴趣的 可以关注一下 公众号, 记录一些心路历程和源代码。 定义一个 Water class 1. **定义接口和枚举**: - WaterInfo 接口定义了水的颜色、高度等信息。 - PourAction 枚举定义了水的倒动状态,…...

【链表】算法题(一) ---- 力扣 / 牛客
一、移除链表元素 移除链表中值为val的元素,并返回新的头节点 思路: 题目上这样说,我们就可以创建一个新的链表,将值不为val的节点,尾插到新的链表当中,最后返回新链表的头节点。 typedef struct ListNo…...

Linux系统之部署盖楼小游戏
Linux系统之部署盖楼小游戏 一、小游戏介绍1.1 小游戏简介1.2 小游戏玩法基本介绍1.3 项目预览二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍2.3 版本要求三、检查本地环境3.1 检查本地操作系统版本3.2 检查系统内核版本四、安装node.js4.1 安装nvm4.2 查看nvm版本4.3 安装…...

“金山-讯飞”杯2024年武汉理工大学程序设计竞赛 A. Mobiusp败走***(思维题-点双连通分量、连通性)
题目 思路来源 官方题解 题解 手玩发现,能换的话,当且仅当.和1在一个环里,而这就是点双连通分量 所以最优策略是先把.换到(x,y)的位置,然后判断.和1在不在一个环里 也就是: 1. 判断删掉1时,.和(x,y)联…...

【机器翻译】基于术语词典干预的机器翻译挑战赛
文章目录 一、赛题链接二、安装库1.spacy2.torch_text 三、数据预处理赛题数据类定义 TranslationDataset批量处理函数 collate_fn 四、编码器和解码器Encoder 类Decoder 类Seq2Seq 类注意事项 五、主函数1. load_terminology_dictionary(dict_file)2. train(model, iterator, …...

推荐系统:从协同过滤到深度学习
目录 一、协同过滤(Collaborative Filtering, CF)1. 基于用户的协同过滤2. 基于物品的协同过滤 二、深度学习在推荐系统中的应用1. 深度学习模型的优势2. 深度学习在推荐系统中的应用实例 三、总结与展望 推荐系统是现代信息处理和传播中不可或缺的技术&…...

记录些Spring+题集(1)
接口防刷机制 接口被刷指的是同一接口被频繁调用,可能是由于以下原因导致: 恶意攻击:攻击者利用自动化脚本或工具对接口进行大量请求,以消耗系统资源、拖慢系统响应速度或达到其他恶意目的。误操作或程序错误:某些情…...

SpringBoot 解决 getSession().getAttribute() 在负载均衡环境下无法获取session的问题
在Spring Boot中,使用getSession().getAttribute()方法时遇到在负载均衡环境下无法正确获取session属性的问题,通常是由于session属性存储在单个服务器的内存中,而负载均衡会导致用户的请求被分配到不同的服务器上,因此无法找到在…...

Jmeter常用组件及执行顺序
一 常用组件 1.线程组 Thread Group 线程组是一系列线程的集合,每一个线程代表着一个正在使用应用程序的用户。在 jmeter 中,每个线程意味着模拟一个真实用户向服务器发起请求。 在 jmeter 中,线程组组件运行用户设置线程数量、初始化方式等…...

PTrade常见问题系列10
get_ashares获取list为空。 get_Ashares函数目前都是向行情服务器进行获取的 如果请求数过多,应答返回偶现为空现象, 后续版本内进行优化从服务器缓存内取,需求单号:202303213922,于PTradeQT1.0V202202.01.023内发布…...

数据结构(4.4)——求next数组
next数组的作用:当模式串的第j个字符失配时,从模式串的第next[j]的继续往后匹配 求模式串的next数组(手算) next[1] 任何模式串都一样,第一个字符不匹配时,只能匹配下一个子串,因此,往后,next[1]都无脑写…...

《mysql篇》--JDBC编程
JDBC是什么 JDBC就是Java DataBase Connectivity的缩写,翻译过来就很好理解了,就是java连接数据库。所以顾名思义,JDBC就是一种用于执行SQL语句的JavaApl,是Java中的数据库连接规范。为了可以方便的用Java连接各种数据库ÿ…...

android studio 怎么下载 buildTool
在Android Studio中下载Build Tools,通常可以通过Android Studio内置的SDK Manager来完成。以下是详细的步骤: 一、通过Android Studio的SDK Manager下载Build Tools 启动Android Studio:首先,确保你已经安装了Android Studio&am…...

copy 和 mutableCopy 有点乱
字符串的拷贝操作 对 string literal (字符串字面量) 执行 copy 要打印指针指向对象的地址和指针本身的地址,可以使用 %p 格式符来输出指针地址。以下代码,展示了 originalString 和 copiedString 的指针地址和指向对象的地址: NSString *…...

sqlalchemy通过查询参数生成query
sqlalchemy通过查询参数生成query 在SQLAlchemy中,可以使用查询参数来动态生成查询。这通常通过使用.filter()方法和Python的比较运算符来实现。以下是一个简单的示例,展示如何使用查询参数生成查询: 假设我们有一个名为User的模型(表),它具有id、username和email字段。…...

【JavaScript 算法】二分查找:快速定位目标元素
🔥 个人主页:空白诗 文章目录 一、算法原理二、算法实现三、应用场景四、优化与扩展五、总结 二分查找(Binary Search)是一种高效的查找算法,适用于在有序数组中快速定位目标元素。相比于线性查找,二分查找…...

论文研读:ViT-V-Net—用于无监督3D医学图像配准的Vision Transformer
目录 摘要 介绍 方法 VIT-V-Net体系结构 损失函数 图像相似性度量 变形场正则化 结果与讨论 摘要 在过去的十年里,卷积神经网络(ConvNets)在各种医学成像应用中占据了主导地位并取得了最先进的性能。然而,由于缺乏对图像中远程空间关系的理解&a…...

C++入门到进阶(图文详解,持续更新中)
C入门到进阶(图文详解,持续更新中) 详解C入门知识到进阶,配合图观看易于理解记录 文章目录 目录 C入门到进阶(图文详解,持续更新中) 文章目录 前言 一、数据 (一)数据类…...

【React Hooks原理 - useRef】
概述 在Function Component项目中当我们需要操作dom的时候,第一时间想到的就是使用useRef这个Hook来绑定dom。但是这个仅仅是使用这个Hook而已,为了更好的学习React Hooks内部实现原理,知其所以然。所以本文根据源码从useRef的基础使用场景一…...

MVC之 IHttpModule管道模型《二》
》》》注意:在http请求的处理过程中,只能调用一个HttpHandler,但可以调用多个HttpModule。 HTTP Modules ASP.NET请求处理过程是基于管道模型的,这个管道模型是由多个HttpModule和HttpHandler组成,当请求到达HttpMod…...

2025上海纺织助剂展会+上海织物整理剂展
2025上海纺织助剂展会上海织物整理剂展 2025第十二届中国(上海)纺织助剂及织物整理剂展览会 时间: 2025年4月23-25日 地点:上海跨国采购会展中心(光复西路2739号) 展会简介: 2025第12届中国(上海&#…...

中科亿海微亮相慕尼黑上海电子展
7月8-10日,备受瞩目的全球电子行业盛会“慕尼黑上海电子展”以空前规模启幕,汇聚了超过1600家参展企业,涵盖了从终端产品制造商到元器件供应商、组装/系统供应商、EMS、ODM/OEM、材料供应商及生产设备供应商的完整产业链。中科亿海微电子科技…...

Spring boot 2.0 升级到 3.3.1 的相关问题 (一)
文章目录 Spring boot 2.0 升级到 3.3.1 的相关问题 (一)拦截器Interceptor的变动问题介绍解决方案 WebMvcConfigurerAdapter 自定义Mvc配置问题介绍解决方案 Spring boot 2.0 升级到 3.3.1 的相关问题 (一) 拦截器Interceptor的…...

数据分析——Python网络爬虫(四){爬虫库的使用}
爬虫库 爬虫的步骤urllib库发送请求两种方法案例 爬虫的步骤 #mermaid-svg-h5azjtPInpsU2ZpP {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-h5azjtPInpsU2ZpP .error-icon{fill:#552222;}#mermaid-svg-h5azjtPInps…...

C++客户端Qt开发——信号和槽
三、信号和槽 1.信号和槽概述 在Qt中,用户和控件的每次交互过程称为一个事件。比如"用户点击按钮”是一个事件,"用户关闭窗口”也是一个事件。每个事件都会发出一个信号,例如用户点击按钮会发出"按钮被点击"的信号&…...

基于双向长短期记忆 BiLSTM 实现股票单变量时间序列预测(PyTorch版)
前言 系列专栏:【深度学习:算法项目实战】✨︎ 涉及医疗健康、财经金融、商业零售、食品饮料、运动健身、交通运输、环境科学、社交媒体以及文本和图像处理等诸多领域,讨论了各种复杂的深度神经网络思想,如卷积神经网络、循环神经网络、生成对…...