当前位置: 首页 > news >正文

13 学习总结:指针 · 其一

目录

一、内存和地址

(一)内存

(二)内存单元

(三)地址

(四)拓展:CPU与内存的联系

二、指针变量和地址

(一)创建变量的本质

(二)取地址操作符:&

(三)指针变量和解引用操作符:*

1、指针变量

2、指针变量的理解

(1)【int* pa】的理解

(2)【int*】的理解

3、解引用操作符:*

(四)指针变量的大小

三、指针变量类型的意义

(一)解引用操作时,决定可以操作多少个字节

(二)指针 + -  整数时,向前/向后走多大的区别

(三)void* 指针

四、const修饰指针

(一)const修饰变量

(二)const修饰指针变量

五、指针的运算

(一)指针 + 或 -  整数

(二)指针 - 指针

(三)指针的关系运算(指针的比较)

六、野指针

(一)野指针造成的原因

1、指针未初始化

2、指针越界访问

3、指针指向的空间释放

(二)如何规避野指针

1、指针初始化

2、小心指针越界

3、指针变量不再使用时,及时置NULL,指针使用之前检查有效性

4、避免返回局部变量的地址

七、assert断言

八、指针的使用和传址调用

(一)指针的使用:strlen的模拟实现

(二)传值调用和传址调用


一、内存和地址

(一)内存

        又称内存储器或主存储器,计算机中所有程序的运行都在内存中进行,计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,这样使用内存则需要高效地管理内存空间;

(二)内存单元

        就是把内存划分为一个个的内存单元,每个内存单元的大小取1个字节(8个比特位),每个内存单元都有⼀个编号,有了这个内存单元的编号,CPU就可以快速找到⼀个内存空间;

(三)地址

        在计算机中我们把【内存单元的编号】也称为【地址】,C语言中给【地址】起了新的名字叫:【指针】

        可以理解为:【内存单元的编号 == 地址 == 指针】

(四)拓展:CPU与内存的联系

        有三条总线将CPU与内存连接彼此,交换数据:①地址总线;②数据总线;③控制总线

        交换过程:地址信息通过【地址总线】被下达给内存,在内存上就可以找到相应的数据,将数据通过【数据总线】传入CPU做处理,【控制总线】则负责传递对数据的操作,如读操作、写操作等

二、指针变量和地址

(一)创建变量的本质

        创建变量的本质是在内存中申请空间,例如创建一个 int 变量就是向内存申请4个字节的空间,每个字节都有自己的编号(地址),变量的名字仅仅是给程序员看的,编译器不看名字,编译器是通过地址找内存单元的

(二)取地址操作符:&

         使用:拿到变量的地址

        例如:

int a = 10;&a;

        &a 就可以拿到变量a的地址,虽然整型变量占用4个字节,我们只要知道了第⼀个字节地址,春藤摸瓜访问到4个字节的数据也是可行的

        注:当一个变量占多个内存单元的时候,总会取出该变量的第一个内存单元(地址较小的那个字节)

(三)指针变量和解引用操作符:*

1、指针变量

        通过取地址操作符(&)拿到的地址是⼀个数值,比如:0x0012ff40,这个数值有时候也是需要存储起来,方便后期再使用的,那我们把这样的地址值存放在哪里呢?答案是:指针变量中,例如:

#include <stdio.h>
int main()
{int a = 10;int * pa = &a;//取出a的地址并存储到指针变量pa中return 0;
}

        指针变量也是⼀种变量,这种变量就是⽤来存放地址的,存放在指针变量中的值都会理解为地址

2、指针变量的理解

        上面例子的写法中的 int *pa 拆开来理解:

(1)【int* pa】的理解

        ①【int *】是变量pa的类型;

        ② pa是一个变量,用来存放地址(指针)的,所以pa又叫指针变量

(2)【int*】的理解

        ① * 表示pa是指针变量;

        ② int 表示【pa 指针变量中保存的地址】所指向的【变量 a】的类型是int

3、解引用操作符:*

        又称为间接访问操作符,用法:

如下演示:
int main()
{int a = 100;int* pa = &a;*pa = 0;此处*pa == a,相当于对a进行修改return 0;
}

        总结:通过【指针变量pa】找到指向的变量a—— *pa(通过pa的值,找到a)

        ① pa —— 指针变量

        ② &pa —— 指针变量pa的地址

        ③ *pa —— pa指向的变量a

(四)指针变量的大小

        【指针变量类型的大小】取决于【地址的大小】,而地址大小由计算机是32位操作系统还是64位操作系统决定

        ① 指针变量是用来存放地址的,一个地址的存放需要多大空间,那么指针变量类型就是多大,所以32位平台总共有32根地址总线,每根线的电信号转化成数字信号后是1或0,那我们把32根地址总线产生的2进制序列作为一个地址,那么一个地址就是32个比特位,就是4个字节;同理,在64位的机器中,一个地址的大小就是8字节

        ② 地址的大小与【指向的原变量的类型大小】无关,就是4字节或者8字节

#include <stdio.h>//指针变量的⼤⼩取决于地址的⼤⼩
//32位平台下地址是32个bit位(即4个字节)
//64位平台下地址是64个bit位(即8个字节)int main()
{printf("%zd\n", sizeof(char *));printf("%zd\n", sizeof(short *));printf("%zd\n", sizeof(int *));printf("%zd\n", sizeof(double *));return 0;
}

        X86环境输出结果如下:

        X64环境输出结果如下:

        结论:

32位平台下地址是32个bit位,指针变量大小是4个字节

64位平台下地址是64个bit位,指针变量大小是8个字节

指针变量的大小和类型是无关的,只要指针类型的变量,在相同的平台下,大小都是相同的

三、指针变量类型的意义

        指针变量的大小和类型无关,只要是指针变量,在同⼀个平台下,大小都是⼀样的,都是4字节或者8字节,为什么还要有各种各样的指针类型呢?

(一)解引用操作时,决定可以操作多少个字节

        如下演示:

#include <stdio.h>
int main()
{int a = 0x11223344;int* p = &a;*p = 0;return 0;
}

        变量a的地址与4个字节的值如下:

        经过 *p = 0;的语句后,4个字节的值全部改为0,如下:

        若代码中指针变量的类型改为char*:

#include <stdio.h>
int main()
{int a = 0x11223344;char* p = &a;*p = 0;return 0;
}

        变量a的地址与4个字节的值如下:

        经过 *p = 0;的语句后,4个字节的值只有一个字节改为0,如下:

      

        结论:指针的类型决定了,解引用操作时,决定可以操作多少个字节

        比如: char* 的指针解引用就只能访问一个字节,而 int* 的指针的解引用就能访问四个字节

(二)指针 + -  整数时,向前/向后走多大的区别

        如下代码演示:

#include <stdio.h>
int main()
{int n = 10;char *pc = (char*)&n;int *pi = &n;printf("%p\n", &n);printf("%p\n", pc);printf("%p\n", pc+1);printf("%p\n", pi);printf("%p\n", pi+1);return 0;
}

        代码结果如下:

        从结果可以得出:char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节;

        结论:指针的类型决定了指针向前或者向后走一步有多大(距离)           

 补充:
        int* pa;   
        pa+1——> +1 * sizeof (int)
        pa+n——> +n * sizeof (int)

        char* pa;   
        pa+1——> +1 * sizeof (char)
        pa+n——> +n * sizeof (char)

总结:

        类型* 变量名;

        变量名 + 1 ——> +1 * sizeof(指针指向的变量类型)

(三)void* 指针

        void* ——无具体类型的指针(泛型指针)

        可以接收任何类型的地址,但是正因为他是泛型指针,所以没有特定类型指针的用法,即无法解引用和进行指针的 + - 操作

        作用:⼀般 void* 类型的指针是使用在函数参数的部分,用来接收不同类型数据的地址,这样的设计可以实现泛型编程的效果,使得⼀个函数来处理多种类型的数据

四、const修饰指针

(一)const修饰变量

        const修饰变量的时候,叫:常变量;

        本质还是变量,只是不能被修改;

        变量是可以修改的,如果把变量的地址交给⼀个指针变量,通过指针变量的也可以修改这个变量,若不想变量被直接修改,就使用const修饰变量起限制作用

#include <stdio.h>
int main()
{int m = 0;m = 20;//m是可以修改的const int n = 0;n = 20;//n是不能被修改的return 0;
}

        上述代码中n是不能被修改的,其实n本质是变量(无法在数组长度中使用),只不过被const修饰后,在语法上加了限制,只要我们在代码中对n进行修改,就不符合语法规则,就报错,致使没法直接修改n

        但是可以拿到n的地址,通过指针对它进行修改,但这是在打破语法规则

int main()
{const int n = 0;printf("n = %d\n", n);int*p = &n;*p = 20;printf("n = %d\n", n);return 0;
}

        结果如下:

        这里的初衷是不让变量改变,但是通过指针还是能打破const的限制,接下来就要对这一象限改进,直接对指针变量做const限制

(二)const修饰指针变量

        ⼀般来讲const修饰指针变量,可以放在 * 的左边,也可以放在 * 的右边,意义是不⼀样的

int * p;//没有const修饰
int const * p;//const 放在*的左边做修饰
int * const p;//const 放在*的右边做修饰

        如下代码演示:

        代码一:

int a = 10;
int b = 20;
int const * p = &a;*p = 200;err
p = &b;√

        代码一分析:

        这个const限制的是 *p,即p指向的变量a不能改变;但是并没有限制p,所以可以修改p所指向的变量;
        放在*的左边,限制的是指针指向的内容,也就是不能通过指针变量来修改它所指的内容;但是指针变量本身可以改变的

        代码二:

int a = 10;
int b = 20;
int * const p = &a;*p = 200;√
p = &b;err

        代码二分析:

        放在*的右边,限制的是指针变量本身,也就是指针变量本身不可以改变,但可以通过指针变量来修改它所指的内容

        结论:const修饰指针变量的时候

const如果放在 * 的左边,修饰的是【指针指向的内容 *p】,保证指针指向的内容不能通过指针来改变,但是【指针变量本身 p】的内容可变;
const如果放在*的右边,修饰的是【指针变量本身 p】,保证了指针变量的地址指向不能修改,但是【指针指向的内容*p】,可以通过指针改变

五、指针的运算

        指针的基本运算有三种,分别是:

        • 指针 + 或 -  整数

        • 指针 - 指针

        • 指针的关系运算(指针的比较)

(一)指针 + 或 -  整数

        因为数组在内存中是连续存放的,只要知道第⼀个元素的地址,顺腾摸瓜就能找到后⾯的所有元素

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

#include <stdio.h>
//指针+- 整数
int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);for(int i = 0; i < sz; i++){printf("%d ", *(p+i));//p+i 这⾥就是指针+整数}return 0;
}

        注意:指针运算是指对 p 进行运算,而不是对*p,若对 *p 运算,就是对变量a运算了

        在数组中,指针能够“顺腾摸瓜”的原因是:

        ①指针类型决定了【指针+1】的步长,和指针解引用之后的权限;

        ②数组在内存中的地址是连续的

        错误演示代码:

int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};char *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);for(int i = 0; i < sz; i++){printf("%d ", *p);p += 4;}return 0;
}

        代码分析:

        每次打印时,都让p += 4,在打印1~10时恰好正确,

        每次访问都只会访问第一个字节,后面三个字节是直接跳过的,所以两位数的时候是正确的,但是数字大一些就会忽略掉第二个字节的数字,就会出错

(二)指针 - 指针

        【指针 - 指针】的运算前提条件两个指针指向的是同一个空间,否则运算无意义;

        指针 - 指针的【绝对值】,是指针和指针之间【元素的个数】

        应用:求字符串长度 ,如下代码演示:

#include <stdio.h>int my_strlen(char *s)
{char *p = s;//设置尾指针while(*p != '\0' )p++;return p-s;
}int main()
{printf("%d\n", my_strlen("abc"));return 0;
}

        拓展:指针 + 指针?

        答:无意义,类似于 【日期 +- 天数(计算日期)】、【日期 - 日期(算的是两个日期之间差多少天)】有意义,而【日期 + 日期】无意义

(三)指针的关系运算(指针的比较)

        应用:做判断条件使用,数组中,若一个地址小于另一个地址,则执行语句

#include <stdio.h>int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];int sz = sizeof(arr)/sizeof(arr[0]);while(p<arr+sz) //指针的⼤⼩⽐较{printf("%d ", *p);p++;}return 0;
}

六、野指针

        概念: 野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的)

(一)野指针造成的原因

1、指针未初始化

        指针变量也是局部变量,不初始化就会给随机值;

        如果将未初始化的指针变量的值作为地址来进行解引用操作,就会形成非法访问

#include <stdio.h>int main()
{ int *p;//局部变量指针未初始化,默认为随机值*p = 20;return 0;
}

2、指针越界访问

#include <stdio.h>int main()
{int arr[10] = {0};int *p = &arr[0];int i = 0;for(i=0; i<=11; i++){//当指针指向的范围超出数组arr的范围时,p就是野指针*(p++) = i;}return 0;
}

3、指针指向的空间释放

#include <stdio.h>int* test()
{int n = 100;return &n;
}int main()
{int* p = test();printf("%d\n", *p);return 0;
}

(二)如何规避野指针

1、指针初始化

        如果明确知道指针指向哪里就直接赋值地址,如果不知道指针应该指向哪里,可以给指针赋值NULL,NULL 是C语言中定义的⼀个标识符常量,值是0(这个0在C语言中会被强制转化为void*类型),0也是地址,这个地址是无法使用的,读写该地址会报错

        演示代码如下:

#include <stdio.h>
int main()
{int num = 10;int* p1 = &num;int* p2 = NULL;return 0;
}

2、小心指针越界

        ⼀个程序向内存申请了哪些空间,通过指针也就只能访问哪些空间,不能超出范围访问,超出了就是越界访问

3、指针变量不再使用时,及时置NULL,指针使用之前检查有效性

        当指针变量指向⼀块区域的时候,我们可以通过指针访问该区域,后期不再使用这个指针访问空间的时候,我们可以把该指针置为NULL;因为约定俗成的⼀个规则就是:只要是NULL指针就不去访问,同时使用指针之前可以判断指针是否为NULL

        演示代码如下:

int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10};int *p = &arr[0];for(int i = 0; i<10; i++){*(p++) = i;}//此时p已经越界了,可以把p置为NULLp = NULL;//下次使⽤的时候,判断p不为NULL的时候再使⽤//...p = &arr[0];//重新让p获得地址if(p != NULL) //判断{//...}return 0;
}

4、避免返回局部变量的地址

        不要返回局部变量的地址

七、assert断言

        

        assert.h 头文件定义了宏 assert ( ) ,用于在运行时确保程序符合指定条件,如果不符合,就报错终止运行,这个宏常常被称为“断言”

        使用:#include <assert.h>;assert(表达式)

        作用:判断是否符合指定条件,如果不符合就会终止运行;【通常用来判断指针变量的有效性】

        判断:判断为真则程序继续向下走,判断为假则报错

int* p = NULL;
...
assert(p != NULL); 
此处经过一些列的代码后,若 p 不等于NULL则正常运行下去,若还是等于NULL,则程序报错,终止运行

        若想取消assert断言,则在#include <assert.h>上面 #define NDEBUG;

        assert断言只在Debug版本中有效,在Release版本中会被优化掉

        缺点:引入了额外的检查,增加了程序的运行时间

八、指针的使用和传址调用

(一)指针的使用:strlen的模拟实现

        库函数strlen的功能是求字符串⻓度,统计的是字符串中 \0 之前的字符的个数

        函数原型如下:

size_t strlen ( const char * str );

        参数str接收⼀个字符串的起始地址,然后开始统计字符串中 \0 之前的字符个数,最终返回长度;

        如果要模拟实现只要从起始地址开始向后逐个字符的遍历,只要不是 \0 字符,计数器就+1,这样直到 \0 就停止,代码如下:

size_t my_strlen(const char * str)
{int count = 0;assert(str);//为了保险,判断传来的是不是空地址while(*str){count++;str++;}return count;
}int main()
{size_t len = my_strlen("abcdef");printf("%zd\n", len);return 0;
}

        注:代码中的 const(不希望原值被修改)和 assert(保险判断)来加强代码使用时的健壮性(鲁棒性)
 

(二)传值调用和传址调用

        传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用,如果函数内部要修改主调函数中的变量的值,就需要传址调用


        以上内容仅供分析,若有错误,请多多指正

相关文章:

13 学习总结:指针 · 其一

目录 一、内存和地址 &#xff08;一&#xff09;内存 &#xff08;二&#xff09;内存单元 &#xff08;三&#xff09;地址 &#xff08;四&#xff09;拓展&#xff1a;CPU与内存的联系 二、指针变量和地址 &#xff08;一&#xff09;创建变量的本质 &#xff08;二…...

golang 项目打包部署环境变量设置

最近将 golang 项目打包部署在不同环境&#xff0c;总结一下自己的心得体会&#xff0c;供大家参考。 1、首先要明确自己目标服务器的系统类型(例如 windows 或者Linux) &#xff0c;如果是Linux 还需要注意目标服务器的CPU架构(amd或者arm) 目标服务器的CPU架构可执行命令&…...

【Linux进程】进程优先级 Linux 2.6内核进程的调度

目录 前言 1. 进程优先级 2. 并发 3. Linux kernel 2.6 内核调度队列与调度原理 总结 前言 进程是资源分配的基本单位, 在OS中存在这很多的进程, 那么就必然存在着资源竞争的问题, 操作系统是如何进行资源分配的? 对于多个进程同时运行, 操作系统又是如何调度达到并发呢?…...

Linux中的粘滞位及mysql日期函数

只要用户具有目录的写权限, 用户就可以删除目录中的文件, 而不论这个用户是否有这个文件的写 权限. 为了解决这个不科学的问题, Linux引入了粘滞位的概念. 粘滞位 当一个目录被设置为"粘滞位"(用chmod t),则该目录下的文件只能由 一、超级管理员删除 二、该目录…...

BP神经网络的实践经验

目录 一、BP神经网络基础知识 1.BP神经网络 2.隐含层选取 3.激活函数 4.正向传递 5.反向传播 6.不拟合与过拟合 二、BP神经网络设计流程 1.数据处理 2.网络搭建 3.网络运行过程 三、BP神经网络优缺点与改进方案 1.BP神经网络的优缺点 2.改进方案 一、BP神经网络基…...

PCL 点云FPFH特征描述子

点云FPFH特征描述子 一、概述1.1 FPFH概念1.2 基本原理1.3 PFH和FPFH的区别二、代码实现三、结果示例一、概述 1.1 FPFH概念 快速点特征直方图(FPFH)描述子:计算 PFH 特征的效率其实是十分低的,这样的算法复杂度无法实现实时或接近实时的应用。因此,这篇文章将介绍 PFH 的简…...

基于golang的文章信息抓取

基于golang的文章信息抓取 学习golang爬虫&#xff0c;实现广度爬取&#xff0c;抓取特定的网页地址&#xff1a;测试站点新笔趣阁&#xff08;https://www.xsbiquge.com/&#xff09; 主要学习golang的goroutine和channel之间的协作&#xff0c;无限爬取站点小说的地址仅限书目…...

【手撕数据结构】卸甲时/空间复杂度

目录 前言时间复杂度概念⼤O的渐进表⽰法小试牛刀 空间复杂度 前言 要想知道什么是空/时间复杂度,就得知道什么是数据结构。 这得分两层来理解。我们生活中处处存在数据&#xff0c;什么抖音热点上的国际大事&#xff0c;什么懂的都懂的雍正卸甲等等一系列我们用户看得到的&a…...

消防认证-防火窗

一、消防认证 消防认证是指消防产品符合国家相关技术要求和标准&#xff0c;且通过了国家认证认可监督管理委员会审批&#xff0c;获得消防认证资质的认证机构颁发的证书&#xff0c;消防产品具有完好的防火功能&#xff0c;是住房和城乡建设领域验收的重要指标。 二、认证依据…...

C++进阶-二叉树进阶(二叉搜索树)

1. 二叉搜索树 1.1 二叉搜索树概念 二叉搜索树又称二叉排序树&#xff0c;它或者是一棵空树&#xff0c;或者是具有以下性质的二叉树: 1.若它的左子树不为空&#xff0c;则左子树上所有节点的值都小于根节点的值2.若它的右子树不为空&#xff0c;则右子树上所有节点的值都大于…...

【Unity小知识】UnityEngine.UI程序集丢失的问题

问题表现 先来说一下问题的表现&#xff0c;今天在开发的时候工程突然出现了报错&#xff0c;编辑器提示UnityEngine.UI缺少程序集引用。 问题分析与解决&#xff08;一&#xff09; 既然是程序集缺失&#xff0c;我们首先查看一下工程项目是否引用了程序集。在项目引用中查找一…...

CentOS 离线安装部署 MySQL 8详细教程

1、简介 MySQL是一个流行的开源关系型数据库管理系统&#xff08;RDBMS&#xff09;&#xff0c;它基于SQL&#xff08;Structured Query Language&#xff0c;结构化查询语言&#xff09;进行操作。MySQL最初由瑞典的MySQL AB公司开发&#xff0c;后来被Sun Microsystems公司…...

云计算【第一阶段(28)】DNS域名解析服务

一、DNS解析的定义与作用 1.1、DNS解析的定义 DNS解析&#xff08;Domain Name System Resolution&#xff09;是互联网服务中的一个核心环节&#xff0c;它负责将用户容易记住的域名转换成网络设备能够识别和使用的IP地址。一般来讲域名比 IP 地址更加的有含义、也更容易记住…...

pygame 音乐粒子特效

代码 import pygame import numpy as np import pymunk from pymunk import Vec2d import random import librosa import pydub# 初始化pygame pygame.init()# 创建屏幕 screen pygame.display.set_mode((1920*2-10, 1080*2-10)) clock pygame.time.Clock()# 加载音乐文件 a…...

Leetcode 295.数据流的中位数

295.数据流的中位数 问题描述 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: Media…...

A59 STM32_HAL库函数 之 TIM扩展驱动 -- A -- 所有函数的介绍及使用

A59 STM32_HAL库函数 之 TIM扩展驱动 -- A -- 所有函数的介绍及使用 1 该驱动函数预览1.1 HAL_TIMEx_HallSensor_Init1.2 HAL_TIMEx_HallSensor_DeInit1.3 HAL_TIMEx_HallSensor_MspInit1.4 HAL_TIMEx_HallSensor_MspDeInit1.5 HAL_TIMEx_HallSensor_Start1.6 HAL_TIMEx_HallSe…...

【Unity】UGUI的基本介绍

Unity的UGUI&#xff08;Unity User Interface&#xff09;是Unity引擎内自带的UI系统&#xff0c;官方称之为UnityUI&#xff0c;是目前Unity商业游戏开发中使用最广泛的UI系统开发解决方案。以下是关于Unity的UGUI的详细介绍&#xff1a; 一、UGUI的特点 灵活性&#xff1a…...

MySQL 9.0新特性:向量存储

MySQL 9.0 正式版已经发布&#xff0c;其中一个亮点就是向量&#xff08;VECTOR&#xff09;数据类型的支持&#xff0c;本文给大家详细介绍一下这个新功能。 向量类型 MySQL 9.0 增加了一个新的向量数据类型&#xff1a;VECTOR。它是一种可以存储 N 个数据项的数据结构&…...

ruoyi实用性改造--(四)选择数据源及非标准使用数据库

一、实用型数据直接访问/** 使用Druid中 application-druid.yml 中定义的副数据源Connection con=null; //手工调用Druid的配置访问Connection con2=null;try {//DruidDataSource ds = SpringUtils.getBean("masterDataSource");DruidDataSource ds = Spring…...

HMI 的 UI 风格创造奇迹

HMI 的 UI 风格创造奇迹...

如何安全隐藏IP地址,防止网络攻击?

当您想在互联网上保持隐私或匿名时&#xff0c;您应该做的第一件事就是隐藏您的 IP 地址。您的 IP 地址很容易被追踪到您&#xff0c;并被用来了解您的位置。下面的文章将教您如何隐藏自己&#xff0c;不让任何试图跟踪您的活动的人发现。 什么是 IP 地址&#xff1f; 首先&am…...

Windows10/11家庭版开启Hyper-V虚拟机功能详解

Hyper-V是微软的一款虚拟机软件&#xff0c;可以使我们在一台Windows PC上&#xff0c;在虚拟环境下同时运行多个互相之间完全隔离的操作系统&#xff0c;这就实现了在Windows环境下运行Linux以及其他OS的可能性。和第三方虚拟机软件&#xff0c;如VMware等相比&#xff0c;Hyp…...

202487读书笔记|《我有个拥抱,你要不要》——生活从来如此,你的态度赋予它意义

202487读书笔记|《我有个拥抱&#xff0c;你要不要》——生活从来如此&#xff0c;你的态度赋予它意义 《我有个拥抱&#xff0c;你要不要》作者一天到晚气fufu&#xff0c;挺有愛的小漫画&#xff0c;适合用来看图说话锻炼小语言&#xff0c;我看的很快乐也写得很痛快&#xf…...

使用tcpdump抓取本本机的所有icmp包

1、抓取本机所有icmp包 tcpdump -i any icmp -vv 图中上半部分&#xff0c;是源主机tmp179无法ping通目标主机192.168.10.79&#xff08;因为把该主机关机了&#xff09;的状态&#xff0c;注意看&#xff0c;其中有unreachable 图中下半部分&#xff0c;是源主机tmp179可以p…...

Nginx:负载均衡小专题

运维专题 Nginx&#xff1a;负载均衡小专题 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.net/…...

新增多种图表类型,新增插件管理模块,DataEase开源数据可视化分析工具v2.8.0发布

2024年7月8日&#xff0c;人人可用的开源数据可视化分析工具DataEase正式发布v2.8.0版本。 这一版本的功能变动包括&#xff1a;图表方面&#xff0c;新增组合图、热力地图、符号地图、K线图等图表类型&#xff0c;并对已有的仪表盘、明细表、指标卡、富文本等图表类型进行了功…...

android perfetto使用技巧梳理

1 抓取方法 根据不同的配置参数&#xff0c;会显示不同的功能。 比如有的trace文件就无法显示线程状态信息&#xff0c;有的无法显示锁依赖信息等等&#xff0c;要看你的参数&#xff0c;我这个是很全的&#xff0c;基本够了&#xff0c;如果还想添加&#xff0c;可以命令行看…...

bond网络配置文件中zone

在bond网络配置文件中&#xff0c;zone是一个参数&#xff0c;用于指定bond设备所属的防火墙安全区域。它可以设置为一个字符串值&#xff0c;通常是一个自定义的区域名称。 防火墙安全区域是一种网络隔离和安全策略的概念&#xff0c;它可以将网络划分为不同的区域&#xff0…...

spring事务详解

事务管理方式 在Spring中&#xff0c;事务有两种实现方式&#xff0c;分别是编程式事务管理和声明式事务管理两种方式。 编程式事务管理&#xff1a; 编程式事务管理使用TransactionTemplate或者直接使用底层的PlatformTransactionManager。对于编程式事务管理&#xff0c;sp…...

LIMS系统的核心功能有哪些

LIMS实验室管理系统&#xff0c;是一种利用信息化技术管理和优化实验室工作流程的系统。其核心功能主要包括以下几个方面&#xff1a; 一、样品管理 样品登记与追踪&#xff1a;LIMS系统能够对实验室内的所有样品进行统一管理&#xff0c;包括样品的接收、登记、分类、追踪和管…...