C语言学习----指针和数组

🌈这篇blog记录一下指针学习~ 主要是关于指针和数组之间的关系,还有指针的使用等~

🍎指针变量是一个变量 其本身也有一个地址 也需要存放,就和int char等类型一样的,也需要有一个地址来存放它

🍌而指针变量 是用于存储其他变量的地址 int char 等类型存储的是对应的值,比如 1 2 3 ‘a’ ‘b’等,但是指针变量存储的就是地址

🍅 可以通过解引用“ * ”来获取指针变量地址的变量对应的值

比如 ptr1是指向utn[0]的指针,那么 ptr1存放的就是utn[0]的地址,我通过解引用就可获取 utn[0]存储的值是多少。

文章目录

  • 指针和数组
  • 函数 数组和指针
  • 使用指针形参
  • 指针的操作
    • 指针的操作
        • 赋值
        • 解引用
        • 取址
        • 相加
        • 递增指针
        • 指针减去一个整数
        • 递减指针
        • 指针求差
        • 比较
    • 关于野指针

指针和数组

flizny == &flizny[0]; // 数组名是该数组首元素的地址

flizny 和&flizny[0]都表示数组首元素的内存地址(&是地址运算符)。两者都是常量,在程序的运行过程中,不会改变。

但是,可以把它们赋值给指针变量,然后可以修改指针变量的值。注意指针加上一个数时,它的值发生了什么变化(转换说明%p通常以十六进制显示指针的值)。

我们的系统中,地址按字节编址,short类型占用2字节,double类型占用8字节。在C中,指针加1指的是增加一个存储单元。对数组而言,这意味着把加1后的地址是下一个元素的地址,而不是下一个字节的地址。只知道地址不够,因为计算机要知道储存对象需要多少字节(即使指针指向的是标量变量,也要知道变量的类型,否则*pt 就无法正确地取回地址上的值)

int dates[y], *pti;
pti = dates; // or(pti = & dates [0];)

指针的值是它所指向对象的地址。地址的表示方式依赖于计算机内部的硬件。 许多计算机(包括PC和Macintosh)都是按字节编址,意思是内存中的每个字节都按顺序编号。这里,一个较大对象的地址(如double类型的变量)通常是该对象第一个字节的地址。

在指针前面使用*运算符可以得到该指针所指向对象的值。
指针加1,指针的值递增它所指向类型的大小(以字节为单位)。
下面的等式体现了C语言的灵活性:

dates + 2 == &date[2]    // 相同的地址

* (dates + 2) == dates[2]  // 相同的值

以上关系表明了数组和指针的关系十分密切,可以使用指针标识数组的元素和获得元素的值。 从本质上看,同一个对象有两种表示法。实际上,C语言标准在描述数组表示法时确实借助了指针。也就是说,定义ar[n]的意思是 * (ar + n)。可以认为 *(ar + n)的意思是“到内存的ar位置,然后移动n个单元,检索储存在那里的值”。

*(dates + 2) // dates第3个元素的值
*dates + 2  // dates第1个元素的值加2
#include <stdio.h>
#define MONTHS 12
int main(void)
{
    int days[MONTHS] = { 31, 28, 31, 30, 31, 30, 31, 31, 
    30, 31, 30, 31 };
    int index;
    for (index = 0; index < MONTHS; index++)
    printf("Month %2d has %d days.\n", index + 1,
    *(days + index)); //与 days[index]相同
    return 0;
}

这里,days是数组首元素的地址,days + index是元素days[index]的地址 ,而 * (days + index)则是该元素的值,相当于days[index]。for循环依次引用数组中的每个元素,并打印各元素的内容。

这样编写程序是否有优势?不一定。编译器编译这两种写法生成的代码相同。要注意的是,指针表示法和数组表示法是两种等效的方法。该例演示了可以用指针表示数组,反过来,也可以用数组表示指针。 在使用以数组为参数的函数时要注意这点。

函数 数组和指针

关于函数的形参,还有一点要注意。只有在函数原型或函数定义头中,才可以用int ar[]代替int * ar:

int sum (int ar[], int n);

*int ar形式和int ar[]形式都表示ar是一个指向int的指针。但是,int ar[]只能用于声明形式参数。第2种形式(int ar[])提醒读者指针ar指向的不仅仅一个int类型值,还是一个int类型数组的元素。

因为数组名是该数组首元素的地址,作为实际参数的数组名要求形式参数是一个与之匹配的指针。只有在这种情况下,C才会把int ar[]和int * ar解释成一样。也就是说,ar是指向int的指针。由于函数原型可以省略参数名,所以下面4种原型都是等价的:

int sum(int *ar, int n);
int sum(int *, int);
int sum(int ar[], int n);
int sum(int [], int);

但是,在函数定义中不能省略参数名

关于sizeof 的占位符符号 %zd

如果编译器不支持 %zd,用 %u 或 %lu 替换它

printf("The size of marbles is %zd bytes.\n",
sizeof marbles);

关于指针和数组byte的问题

/ sum_arr1.c -- 数组元素之和
// 如果编译器不支持 %zd,用 %u 或 %lu 替换它
#include <stdio.h>
#define SIZE 10
int sum(int ar[], int n);
int main(void)
{
    int marbles[SIZE] = { 20, 10, 5, 39, 4, 16, 19, 26, 31, 20 };
    long answer;
    answer = sum(marbles, SIZE);
    printf("The total number of marbles is %ld.\n", answer);
    printf("The size of marbles is %zd bytes.\n",
    sizeof marbles);
    return 0;
}

int sum(int ar[], int n)   // 这个数组的大小是?
{
    int i;
    int total = 0;
    for (i = 0; i < n; i++)
    total += ar[i];
    printf("The size of ar is %zd bytes.\n", sizeof ar);
    return total;
}

/*该程序的输出如下:
The size of ar is 8 bytes.
The total number of marbles is 190.
The size of marbles is 40 bytes.

注意,marbles的大小是40字节。这没问题,因为marbles内含10个int类型的值,每个值占4字节,所以整个marbles的大小是40字节。

但是,ar才8字节。这是因为ar并不是数组本身,它是一个指向 marbles 数组首元素的指针。我们的系统中用 8 字节储存地址,所以指针变量的大小是 8字节(其他系统中地址的大小可能不是8字节)。简而言之,在程序中,marbles是一个数组, ar是一个指向marbles数组首元素的指针,利用C中数组和指针的特殊关系,可以用数组表示法来表示指针ar。

使用指针形参

/* 使用指针算法 */
int sump(int * start, int * end)
{
    int total = 0;
    while (start < end)
    {
        total += *start;  // 把数组元素的值加起来
        start++;      // 让指针指向下一个元素
        }
    return total;
}
//也可以
total += *start++;

指针start开始指向marbles数组的首元素,所以赋值表达式total += *start把首元素(20)加给total。然后,表达式start++递增指针变量start,使其指向数组的下一个元素。因为start是指向int的指针,start递增1相当于其值递增int类型的大小。

total += *start++;
一元运算符 * 和++的优先级相同,但结合律是从右往左所以start++先求值,然后才是 * start。 也就是说,指针start先递增后指向。

使用后缀形式(即start++而不是++start)意味着先把指针指向位置上的值加到total上,然后再递增指针。如果使用 * ++start,顺序则反过来,先递增指针,再使用指针指向位置上的值。 如果使用(* start)++,则先使用start指向的值,再递增该值,而不是递增指针。这样,指针将一直指向同一个位置,但是该位置上的值发生了变化。 虽然 * start++的写法比较常用,但是*(start++)这样写更清楚

/* order.c -- 指针运算中的优先级 */
#include <stdio.h>
int data[2] = { 100, 200 };

int moredata[2] = { 300, 400 };
int main(void)
{
    int * p1, *p2, *p3;
    p1 = p2 = data;
    p3 = moredata;
    printf(" *p1 = %d,  *p2 = %d,  *p3 = %d\n",*p1, *p2, *p3);
    printf("*p1++ = %d, *++p2 = %d, (*p3)++ = %d\n",*p1++, *++p2, (*p3)++);
    printf(" *p1 = %d,  *p2 = %d,  *p3 = %d\n",*p1, *p2, *p3);
    return 0;
}

想想打印出来最终结果是什么?


下面是该程序的输出:
*p1 = 100,  *p2 = 100,   *p3 = 300
*p1++ = 100, *++p2 = 200, (*p3)++ = 300
*p1 = 200,  *p2 = 200,   *p3 = 301

只有(*p3)++改变了数组元素的值,其他两个操作分别把p1和p2指向数
组的下一个元素。

🌴首先p1 他是直接指向我们数组的首地址,解引用之后自然是数组的第一个数据 p2 p3也是一样的

☘️ 其次 * p1++ 也就是 先执行指针start先递增后指向。使用后缀形式(即p1++而不是++p1)所以此时还是100 等这条命令结束之后,* p1就是200了。而*++p2 他是前缀形式,所以不用等命令完成,直接解引用得到200 p3的例子和p1类似 先解引用得到300 然后后缀递增也就是加一,但是也是得等这条命令结束以后

🌿 最后一行 就是上面的p1 和p3结束以后得到的值,而p2保持不变

至于C语言,ar[i]和*(ar+1)这两个表达式都是等价的。无论ar是数组名还是指针变量,这两个表达式都没问题。但是,只有当ar是指针变量时,才能使用ar++这样的表达式。

指针的操作

下面的程序示例中演示了8种不同的操作。为了显示每种操作的结果,该程序打印了指针的值(该指针指向的地址)储存在指针指向地址上的值,以及指针自己的地址。 如果编译器不支持%p 转换说明,可以用%u 或%lu 代替%p;如果编译器不支持用%td转换说明打印地址的差值,可以用%d或%ld来代替

// ptr_ops.c -- 指针操作
#include <stdio.h>
int main(void)
{
    int urn[5] = { 100, 200, 300, 400, 500 };
    int * ptr1, *ptr2, *ptr3;
    ptr1 = urn;       // 把一个地址赋给指针
    ptr2 = &urn[2];     // 把一个地址赋给指针
    // 解引用指针,以及获得指针的地址
    printf("pointer value, dereferenced pointer, pointer address:\n");
    printf("ptr1 = %p, *ptr1 =%d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1);
// 指针加法
	ptr3 = ptr1 + 4;
    printf("\nadding an int to a pointer:\n");
    printf("ptr1 + 4 = %p, *(ptr1 + 4) = %d\n", ptr1 + 4, *(ptr1 + 4));
    ptr1++;         // 递增指针
    printf("\nvalues after ptr1++:\n");
    printf("ptr1 = %p, *ptr1 =%d, &ptr1 = %p\n", ptr1, *ptr1, &ptr1);
    ptr2--;         // 递减指针
    printf("\nvalues after --ptr2:\n");
    printf("ptr2 = %p, *ptr2 = %d, &ptr2 = %p\n", ptr2, *ptr2, &ptr2);
    --ptr1;         // 恢复为初始值
    ++ptr2;         // 恢复为初始值
    printf("\nPointers reset to original values:\n");
    printf("ptr1 = %p, ptr2 = %p\n", ptr1, ptr2);
    // 一个指针减去另一个指针
    printf("\nsubtracting one pointer from another:\n");
    printf("ptr2 = %p, ptr1 = %p, ptr2 - ptr1 = %td\n", 
    ptr2, ptr1, ptr2 - ptr1);
    // 一个指针减去一个整数
    printf("\nsubtracting an int from a pointer:\n");
    printf("ptr3 = %p, ptr3 - 2 = %p\n", ptr3, ptr3 - 2);
	return 0;
}

对于以上的程序可以运行一下

指针的操作

赋值

可以把地址赋给指针。例如,用数组名、带地址运算符(&)的
变量名、另一个指针进行赋值。 在该例中,把urn数组的首地址赋给了ptr1,
该地址的编号恰好是0x7fff5fbff8d0。变量ptr2获得数组urn的第3个元素
(urn[2])的地址。注意,地址应该和指针类型兼容。也就是说,不能把
double类型的地址赋给指向int的指针,至少要避免不明智的类型转换。
C99/C11已经强制不允许这样做。

解引用

“ * ” 运算符**给出指针指向地址上储存的值。*因此, ptr1的初值是
100,该值储存在编号为0x7fff5fbff8d0的地址上。

取址

和所有变量一样,指针变量也有自己的地址和值。对指针而言,
&运算符给出指针本身的地址。本例中,ptr1 储存在内存编号为
0x7fff5fbff8c8 的地址上,该存储单元储存的内容是0x7fff5fbff8d0,即urn的地
址。因此**&ptr1是指向ptr1的指针**,而ptr1是指向utn[0]的指针。

🍎指针变量是一个变量 其本身也有一个地址 也需要存放,就和int char等类型一样的,也需要有一个地址来存放它

🍌而指针变量 是用于存储其他变量的地址 int char 等类型存储的是对应的值,比如 1 2 3 ‘a’ ‘b’等,但是指针变量存储的就是地址

🍅 可以通过解引用“ * ”来获取指针变量地址的变量对应的值

比如 ptr1是指向utn[0]的指针,那么 ptr1存放的就是utn[0]的地址,我通过解引用就可获取 utn[0]存储的值是多少。

相加

指针与整数相加:可以使用+运算符把指针与整数相加,或整数与指针
相加。无论哪种情况,整数都会和指针所指向类型的大小(以字节为单位)
相乘,然后把结果与初始地址相加。因此ptr1 +4与&urn[4]等价。如果相加
的结果超出了初始指针指向的数组范围,计算结果则是未定义的。除非正好
超过数组末尾第一个位置,C保证该指针有效。

递增指针

递增指向数组元素的指针可以让该指针移动至数组的下一个
元素。因此,ptr1++相当于把ptr1的值加上4(我们的系统中int为4字节),
ptr1指向urn[1](见图10.4,该图中使用了简化的地址)。现在ptr1的值是
0x7fff5fbff8d4(数组的下一个元素的地址),*ptr的值为200(即urn[1]的
值)。注意,ptr1本身的地址仍是 0x7fff5fbff8c8。毕竟,变量不会因为值发
生变化就移动位置。

指针减去一个整数

可以使用-运算符从一个指针中减去一个整数。指针必须是第1个运算对象,整数是第 2 个运算对象。该整数将乘以指针指向类型的大小(以字节为单位),然后用初始地址减去乘积。所以ptr3 - 2与&urn[2]等价,因为ptr3指向的是&arn[4]。如果相减的结果超出了初始指针所指向数组的范围,计算结果则是未定义的。除非正好超过数组末尾第一个位置,C保证该指针有效。

递减指针

当然,除了递增指针还可以递减指针。在本例中,递减ptr3使其指向数组的第2个元素而不是第3个元素。前缀或后缀的递增和递减运算符都可以使用。注意,在重置ptr1和ptr2前,它们都指向相同的元素urn[1]。

指针求差

可以计算两个指针的差值。通常,求差的两个指针分别指向同一个数组的不同元素,通过计算求出两元素之间的距离。 差值的单位与数组类型的单位相同。例如,ptr2 - ptr1得2,意思是这两个指针所指向的两个元素相隔两个int,而不是2字节。只要两个指针都指向相同的数组(或者其中一个指针指向数组后面的第 1 个地址),C 都能保证相减运算有效。如果指向两个不同数组的指针进行求差运算可能会得出一个值,或者导致运行时错误。

比较

使用关系运算符可以比较两个指针的值,前提是两个指针都指向相同类型的对象。

在递增或递减指针时还要注意一些问题。编译器不会检查指针是否仍指
向数组元素。C 只能保证指向数组任意元素的指针和指向数组后面第 1 个位
置的指针有效。但是,如果递增或递减一个指针后超出了这个范围,则是未
定义的。 另外,可以解引用指向数组任意元素的指针。但是,即使指针指向
数组后面一个位置是有效的,也能解引用这样的越界指针。

关于野指针

说到注意事项,一定要牢记一点:千万不要解引用未初始化的指针。例
如,考虑下面的例子:

int * pt;// 未初始化的指针
*pt = 5;   // 严重的错误

为何不行?第2行的意思是把5储存在pt指向的位置。但是pt未被初始化,其值是一个随机值,所以不知道5将储存在何处。这可能不会出什么错,也可能会擦写数据或代码,或者导致程序崩溃。

切记:创建一个指针时,系统只分配了储存指针本身的内存,并未分配储存数据的内存。因此,在使用指针之前,必须先用已分配的地址初始化它。 例如,可以用一个现有变量的地址初始化该指针(使用带指针形参的函数时,就属于这种情况)。
无论如何,使用指针时一定要注意,不要解引用未初始化的指针!

在这里插入图片描述

☘️笔记源于 C Primer Pluse 第六版

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

打包less

接HTML和css之后对less进行打包 1.在之前的文件夹里的src文件夹创建一个less文件 2.打开webpack——>中文文档——>Loader——>less—loader 3.复制下图代码到终端 4.复制下图内容到webpack.config.js脚本 5.在src里的js文件年引入less文件 6.在终端运行 npm run te…

实现安装“自由化”!在Windows 11中如何绕过“您尝试安装的应用程序未通过微软验证”

这篇文章描述了如果你不能安装应用程序,而是当你在Windows 11中看到消息“您尝试安装的应用程序未通过微软验证”时该怎么办。完成这些步骤将取消你安装的应用程序必须经过Microsoft验证的要求。 使用设置应用程序 “设置”应用程序提供了绕过此警告消息的最简单方法,以便你…

C# OpenCvSharp DNN 部署YOLOV6目标检测

目录 效果 模型信息 项目 代码 下载 C# OpenCvSharp DNN 部署YOLOV6目标检测 效果 模型信息 Inputs ------------------------- name&#xff1a;image_arrays tensor&#xff1a;Float[1, 3, 640, 640] -------------------------------------------------------------…

[c++]—vector类___基础版(带你了解vector熟练掌握运用)

&#x1f469;&#x1f3fb;‍&#x1f4bb;作者:chlorine 目录 &#x1f393;标准库类型vector &#x1f393;定义和初始化vector的对象 &#x1f4bb;列表初始化vector对象 &#x1f4bb;创建指定数量的元素 &#x1f576;️值初始化 ❗列表初始化还是值初始化&#xf…

Vuex快速上手

一、Vuex 概述 目标&#xff1a;明确Vuex是什么&#xff0c;应用场景以及优势 1.是什么 Vuex 是一个 Vue 的 状态管理工具&#xff0c;状态就是数据。 大白话&#xff1a;Vuex 是一个插件&#xff0c;可以帮我们管理 Vue 通用的数据 (多组件共享的数据)。例如&#xff1a;购…

DevEco Studio 3.1IDE环境配置(HarmonyOS 3.1)

DevEco Studio 3.1IDE环境配置&#xff08;HarmonyOS 3.1&#xff09; 一、安装环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、环境安装 IDE下载地址&#xff1a;HUAWEI DevEco Studio和SDK下载和升级 | HarmonyOS开发者 IDE的安装就是…

关于uniapp X 的最新消息

uni-app x 是什么&#xff1f; uni-app x&#xff0c;是下一代 uni-app&#xff0c;是一个跨平台应用开发引擎。 uni-app x 没有使用js和webview&#xff0c;它基于 uts 语言。在App端&#xff0c;uts在iOS编译为swift、在Android编译为kotlin&#xff0c;完全达到了原生应用的…

计算机网络(三) | 数据链路层 PPP协议、广播CSMA/CD协议、集线器、交换器、扩展and高速以太网

文章目录 1 数据链路基本概念和问题1.1 基本概念1.2 基本问题&#xff08;1&#xff09;封装成帧&#xff08;2&#xff09;透明传输&#xff08;3&#xff09;差错控制 2.数据链路层协议2.1 点对点 PPP协议2.1.1 需要实现的2.1.2 PPP组成2.1.3 帧格式2.1.4 工作流程 2.2 广播 …

python:五种算法(HHO、WOA、GWO、PSO、GA)求解23个测试函数(python代码)

一、五种算法简介 1、哈里斯鹰优化算法HHO 2、鲸鱼优化算法WOA 3、灰狼优化算法GWO 4、粒子群优化算法PSO 5、遗传算法GA 二、5种算法求解23个函数 &#xff08;1&#xff09;23个函数简介 参考文献&#xff1a; [1] Yao X, Liu Y, Lin G M. Evolutionary programming …

树莓派,opencv,Picamera2利用舵机云台追踪人脸

一、需要准备的硬件 Raspiberry 4b两个SG90 180度舵机&#xff08;注意舵机的角度&#xff0c;最好是180度且带限位的&#xff0c;切勿选360度舵机&#xff09;二自由度舵机云台&#xff08;如下图&#xff09;Raspiberry CSI 摄像头 组装后的效果&#xff1a; 二、项目目标…

Unity之OpenXR+XR Interaction Toolkit接入微软VR设备Windows Mixed Reality

前言 Windows Mixed Reality 是 Microsoft 用于增强和虚拟现实体验的VR设备,如下图所示: 在国内,它的使用率很低,一把都是国外使用,所以适配起来是相当费劲。 这台VR设备只能用于串流Windows,启动后,会自动连接Window的Mixed Reality程序,然后打开微软的增强现实门户…

LAMP 搭建

目录 LAMP LAMP组成及作用 LAMP搭建实验举例&#xff0c;优先将防火墙和安全终端关闭&#xff0c;在一台虚拟机上操作 搭建 apache httpd服务 搭建 mysql服务 搭建 php服务 安装论坛 LAMP —— LAMP架构是目前成熟的企业网站应用模式之一&#xff0c;指的是协同工作的一…

记录汇川:自由口案例01-梯形图

H5U和FX5U通信&#xff1a;通过H5U区点亮FX5U的Y0-Y7 H5U配置 FX5U配置 02 0F 00 00 00 08 01 FF CRC校验码高 CRC校验码低 02:FX5U的站地址 0F:多个线圈写入 00 00:FX5U的MODBUS地址Y0开始 00 08&#xff1a;Y0 - Y7 FF:1111 1111 将Y0 - Y7全部点亮 主程序 MAIN: 记录汇川&a…

开源框架Apache NiFi调研

开源框架Apache NiFi调研 NiFi背景介绍一、什么是NiFi1.1 Apache NiFi特点&#xff1a;流管理、易用性、安全性、可扩展的体系结构和灵活的伸缩模型。1.2 Apache NiFi特性1.2 Apache NiFi核心概念1.3架构 二、NiFi的诞生&#xff0c;要致力于解决的问题有哪些&#xff1f;三、为…

DevEco Studio IDE 创建项目时候配置环境

DevEco Studio IDE 创建项目时候配置环境 一、安装环境 操作系统: Windows 10 专业版 IDE:DevEco Studio 3.1 SDK:HarmonyOS 3.1 二、在配置向导的时候意外关闭配置界面该如何二次配置IDE环境。 打开IDE的界面是这样的。 点击Create Project进行环境配置。 点击OK后出现如…

Mac安装DevEco Studio

下载 首先进入鸿蒙开发者官网&#xff0c;顶部导航栏选择开发->DevEco Studio 根据操作系统下载不同版本&#xff0c;其中Mac(X86)为英特尔芯片&#xff0c;Mac(ARM)为M芯片。 安装 下载完毕后&#xff0c;开始安装。 点击Agree 首次使用&#xff0c;请选择Do not impor…

037.Python面向对象_关于抽象类和抽象方法

我 的 个 人 主 页&#xff1a;&#x1f449;&#x1f449; 失心疯的个人主页 &#x1f448;&#x1f448; 入 门 教 程 推 荐 &#xff1a;&#x1f449;&#x1f449; Python零基础入门教程合集 &#x1f448;&#x1f448; 虚 拟 环 境 搭 建 &#xff1a;&#x1f449;&…

ssm基于MVC的舞蹈网站的设计与实现论文

摘 要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;舞蹈网站当然也不能排除在外。舞蹈网站是以实际运用为开发背景&#xff0c;运用软件工程开发方法&#xff0c;采用Java技…

人体关键点检测2:Pytorch实现人体关键点检测(人体姿势估计)含训练代码

人体关键点检测2&#xff1a;Pytorch实现人体关键点检测(人体姿势估计)含训练代码 目录 人体关键点检测2&#xff1a;Pytorch实现人体关键点检测(人体姿势估计)含训练代码 1. 前言 2.人体关键点检测方法 (1)Top-Down(自上而下)方法 (2)Bottom-Up(自下而上)方法&#xff1…

(企业 / 公司项目) 企业项目如何使用jwt?

按照企业的项目然后写的小demo&#xff0c; 自己搞一个登录接口然后调用jwtUtil工具类 后端实现 创建一个通用模块common来实现jwt生成token 登录注册的基本实现逻辑思路 面试| ProcessOn免费在线作图,在线流程图,在线思维导图 注释挺详细的jwtUtil工具类&#xff0c; 封装的…