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

C语言——指针进阶(四)

fe594ea5bf754ddbb223a54d8fb1e7bc.gif

目录

一.前言

二.指针和数组笔试题解析

2.1 二维数组

2.2 指针笔试题

三.全部代码

四.结语


8fb442646f144d8daecdd2b61ec78ecd.png

一.前言

本文我们将迎来指针的结尾,包含了二维数组与指针的试题解析。码字不易,希望大家多多支持我呀!(三连+关注,你是我滴神!)

二.指针和数组笔试题解析

2.1 二维数组

请逐个分析下面代码最终的打印结果:

int main()
{int a[3][4] = { 0 };printf("%zd\n", sizeof(a));printf("%zd\n", sizeof(a[0][0]));printf("%zd\n", sizeof(a[0]));printf("%zd\n", sizeof(a[0] + 1));printf("%zd\n", sizeof(*(a[0] + 1)));printf("%zd\n", sizeof(a + 1));printf("%zd\n", sizeof(*(a + 1)));printf("%zd\n", sizeof(&a[0] + 1));printf("%zd\n", sizeof(*(&a[0] + 1)));printf("%zd\n", sizeof(*a));printf("%zd\n", sizeof(a[3]));return 0;
}

这是我们假想中的3行4列:

这是真正的3行4列

数组名单独放在sizeof()里面时,我们计算的就是整个数组的大小,即3*4*4==48字节

下面的a[0][0]即代表数组里面的第一个元素,即计算第0行0列的大小,元素类型是整型所以大小为:4字节

 

二维数组其实可以理解为是一维数组的数组,就相当于这个二维数组中每行相当于一个元素,只不过这个元素里存放的是一维数组。既然如此我们就可以认为第一行的一维数组它的数组名是a[0],它作为二维数组的第一个元素(数组)

同理如果你想访问一维数组的话先指定该一维数组在二维数组中的下标,然后再用a[j]进行访问,这样就可以访问到一维数组中的元素(数据)。 

那么我们可以看到a[0]是作为二维数组中一维数组的数组名存在的,所以计算整个一维数组得到:4*4==16字节

这一次的a[0]并没有单独放在sizeof()内部,也没有&,所以不能把它看作是数组名(整个一维数组)。所以它只能表示数组首元素的地址,也就是第一行第一个元素的地址。而a[0]+1就代表是下一个的地址即第一行第二个元素的地址。那么地址的大小一律是4(x32)或8(x86)字节。

我们接着对上面第一行第二个元素的地址解引用,那就会得到第一行第二个元素。大小为4字节。

a没有单独放在sizeof()里面,也没有&,说明a就是作为二维数组的数组名,那就代表是二维数组中首元素的地址,即作为第一个元素(第一行)的整个一维数组的地址。而a+1就代表是第二行的地址。那么地址的大小一律是4(x32)或8(x86)字节。

我们接下来对第二行的一维数组地址解引用,那就是计算第二行的整个一维数组的大小,大小为4*4==16字节。

 

a[0]代表的是第一行的一维数组的数组名,而&代表的是取出整个一维数组的地址,最后+1就是取出的是第二行的一维数组的地址。那么地址的大小一律是4(x32)或8(x86)字节。

对第二行的一维数组地址解引用就是计算第二行的整个一维数组的大小,大小为4*4==16字节。

 

a表示二维数组的数组名,即首元素的地址(第一行的一维数组),而对其解引用就是计算整个一维数组的大小,大小为4*4==16字节。

在3行4列的二维数组中并没有第4行,但在sizeof()眼中并不会判定为越界,因为不管怎么写它们的类型是注定的,所以在sizeof()的判定中a[3]与a[0]是没有区别的,都是相同类型。a[0]单独放在sizeof()里代表第一行元素的整个一维数组,大小为4*4==16字节。

总结:数组名的意义:

  1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
  2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
  3. 除此之外所有的数组名都表示首元素的地址

2.2 指针笔试题

我们先标明ptr的指向 

这道题很简单,ptr-1向前一步指向5的地址再*解引用指向元素5。a代表首元素地址,+1指向下一位,*解引用指向元素2. 

 

这里我们需要知道,int*类型的指针+1跳过4个字节,char*指针+1跳过1个字节。而里面的p是结构体指针,它+1肯定跳过的就是结构体大小的字节也就是20字节。在p原基础上+20也就0x100014.

第二个打印中我们把结构体指针类型的p强制转换为(unsigned long)整型,而整型+1就是数字运算的+1。0x10001

第三个打印中p被强制类型转换为int*型指针,那么+1就是代表跳过4个字节,0x100004 

 在我们标明ptr1的指向后只需要注意ptr1[-1]代表*(ptr1-1)即向前挪动一位指向4.

而对于a而言被强制类型转换为整型后+1就是数学运算的+1,而一个元素有4个字节,a指向首个元素的地址,就算+1也还是指向元素1,并不会跳出指向2.

假设我们是用小端存储 

 重点来了,因为我们ptr2是int*类型的指针,而*就代表我们要访问4个字节,所以ptr2访问的4个字节是00 00 00 02

但又因为是小端存储,所以真实值应该是0x 02 00 00 00按%x(省略2前面0)的话就是2000000

这道题是有坑的,稍不注意就会写错。如果在二维数组中想把0,1放在第一行,那用的应该是{},可题目用的却是(),那就代表(0,1)它是一个逗号表达式。    而a[0]代表的是第一行的一维数组的地址<==>&a[0][0],而p[0]<==>*(p+0)<==>*p,最后打印结果为1.

我们先把a[4][2]与p最开始的指向标明 

由于p是数组指针,它一次+1要跳过4个整型,而p认为它指向的数组是4个元素,所以我们把这4个元素框起来,再从里面找到第3个元素。 

随着数组下标的增长,地址的大小是由低到高的。所以我们这里是小地址减大地址得到的是一个负数。两地址之间相隔4个元素,所以最终由%d打印出来的是-4。

而在我们以%p的形式打印时,它是以-4的补码形式进行打印的,列出-4的原码与反码最终求出补码,然后把补码转换为16进制时应该是0xFFFFFFFC

&aa表示取出整个二维数组的地址,而ptr1-1就是向前挪动一位指向10

*(aa+1)表示取出的是二维数组中的第2个元素,即一维数组<==>aa[1],而aa[1]没有放在sizeof()内部,就表示它代表的是首元素的地址<==>&a[1][0]。ptr2-1就是向前挪动一位,指向5

其实真正理解来说应该是在a数组里面存放了3个char*指针(3个元素),这3个char*指针分别指向了这3个字符串。

而我们还有一个char**类型的指针pa则是指向这个数组a

而接下来pa++(跳过一个char*的元素),我们就指向a数组的第2个元素,*pa就是取出a数组的第2个元素,这个元素是char*类型的指针,里面存储的是字符串"at/0"的地址,所以我们最终取出的是字符串"at/0"的地址。以%s打印为at

首先把各个指针指向标明 

 

cpp+1表示它要跳过一个char**字节,*(cpp+1)对指向cp数组里的c+2解引用,指向元素c+2,即*(cpp+1)<==>c+2,而*c+2则表示指向c数组里面的第3个元素,POINT/0;

 +3的优先级最低,所以要最后算。我们再一次对cpp++,让cpp指向cp数组里面第3个元素的地址,而后面通过*(cpp+1)解引用得到cp数组里面的元素c+1,后面我们再对c+1这个元素进行--变成c,这样它就指向了c数组里面的首个元素的地址了,再对其解引用*c拿到c数组的元素ENTER。而再对指向字符串的指针+3,则拿到的就是ER。

下面的cpp[-2]可以转换成*(cpp-2),所以最终要求的其实是**(cpp-2) + 3.

cpp-2最后的指向其实是cp数组的首元素地址(cpp-2的指向是首元素,但cpp指向是不会变的,还是原来的指向),对其解引用后得到元素c+3,再对c+3解引用得到c数组的最后一个元素PITSR,最后指针+3打印为SR。

最后一个数据中cpp[-1]可以解析为*(cpp-1),那么cpp[-1][-1]也可以解析为*(*(cpp-1)-1)。所以最后我们要求的是*(*(cpp-1)-1)+1

首先cpp-1代表指向cp数组中第2个元素的地址,解引用后为c+2,c+2-1变为c+1,指向了c数组中第2个元素的地址,再次解引用后指向c数组的第2个元素,最后指针+1打印出EW.

三.全部代码

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>int main()
{int a[3][4] = { 0 };printf("%zd\n", sizeof(a));//48-数组名a单独放在了sizeof内存,表示整个数组,sizeof(a)计算的是数组的大小,单位是字节printf("%zd\n", sizeof(a[0][0]));//4-a[0][0]是数组的第一行第一个元素,这里计算的就是一个元素的大小,单位是字节printf("%zd\n", sizeof(a[0]));//16 - a[0]是第一行这个一维数组的数组名,数组名单独放在了sizeof内部//a[0]就表示整个第一行这个一维数组,sizeof(a[0])计算的整个第一行这个一维数组的大小printf("%zd\n", sizeof(a[0] + 1));//4/8 - a[0]并非单独放在sizeof内部,也没有&,所以a[0]表示第一行这个一维数组首元素的地址//也就是第一行第一个元素的地址//a[0] <---> &a[0][0]//a[0]+1 ---> &a[0][1]printf("%zd\n", sizeof(*(a[0] + 1)));//4 - a[0] + 1是第一行第二个元素的地址,*(a[0] + 1))就是第一行第二个元素//printf("%zd\n", sizeof(a + 1));//4/8//a 作为二维数组的数组名,并没有单独放在sizeof内部,也没有&,a就是数组首元素的地址,也就是第一行的地址, a 的类型是 int(*)[4]//a+1 就是第二行的地址,类型是:int(*)[4]//printf("%zd\n", sizeof(*(a + 1)));//16 a+1是第二行的地址,*(a+1)就是第二行,计算的就是第二行的大小//另外一个角度理解:*(a+1) -- a[1]//sizeof(a[1]) - a[1]这个第二行的数组名,单独放在了sizeof内部,计算的是第二行的大小printf("%zd\n", sizeof(&a[0] + 1));//4/8//a[0]是第一行的数组名,&a[0]取出的是数组的地址,取出的是第一行这个一维数组的地址,类型就是int(*)[4]//&a[0]+1 就是第二行的地址,类型就是int(*)[4]printf("%zd\n", sizeof(*(&a[0] + 1)));//*(&a[0] + 1)得到的就是第二行,计算的就是第二行的大小printf("%zd\n", sizeof(*a));//16//a表示数组首元素的地址,也就是第一行的地址//*a 就是第一行,也就相当于是第一行的数组名//*a--> *(a+0) -- a[0]//printf("%zd\n", sizeof(a[3]));//16-不会越界,//a[3] --    arr[0]//int [4]    int [4]return 0;
}int main()
{int a[5] = { 1, 2, 3, 4, 5 };int* ptr = (int*)(&a + 1);printf("%d, %d", *(a + 1), *(ptr - 1));return 0;
}//由于还没学习结构体,这里告知结构体的大小是20个字节
//X86 环境下演示
struct Test
{int Num;char* pcName;short sDate;char cha[2];short sBa[4];
} * p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
//已知,结构体Test类型的变量大小是20个字节
//0x开头的数字是16进制的数字
int main()
{p = (struct Test*)0x100000;printf("%p\n", p + 0x1);printf("%p\n", (unsigned long)p + 0x1);printf("%p\n", (unsigned int*)p + 0x1);return 0;
}int main()
{int a[4] = { 1, 2, 3, 4 };int* ptr1 = (int*)(&a + 1);int* ptr2 = (int*)((int)a + 1);printf("%x,%x", ptr1[-1], *ptr2);return 0;
}#include <stdio.h>
int main()
{int a[3][2] = { (0, 1), (2, 3), (4, 5) };int* p;p = a[0];printf("%d", p[0]);return 0;
}int main()
{int a[5][5];int(*p)[4];//数组指针p = a;//a - int(*)[5]//p - int(*)[4]printf("%p, %d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);////%p是打印地址,认为内存中存储的补码就是地址//return 0;
}int main()
{int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };int* ptr1 = (int*)(&aa + 1);int* ptr2 = (int*)(*(aa + 1));printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));return 0;
}#include <stdio.h>
//阿里的笔试题
int main()
{char* a[] = { "work","at","alibaba" };char** pa = a;pa++;printf("%s\n", *pa);return 0;
}int main()
{char* c[] = { "ENTER","NEW","POINT","FIRST" };char** cp[] = { c + 3,c + 2,c + 1,c };char*** cpp = cp;printf("%s\n", **++cpp);printf("%s\n", *-- * ++cpp + 3);printf("%s\n", *cpp[-2] + 3);printf("%s\n", cpp[-1][-1] + 1);return 0;
}

4b12323f94834afd9ec146a3c10df229.jpeg四.结语

数组和指针的笔试题解析就此谢幕。最后感谢大家的观看,友友们能够学习到新的知识是额滴荣幸,期待我们下次相见~

相关文章:

C语言——指针进阶(四)

目录 一.前言 二.指针和数组笔试题解析 2.1 二维数组 2.2 指针笔试题 三.全部代码 四.结语 一.前言 本文我们将迎来指针的结尾&#xff0c;包含了二维数组与指针的试题解析。码字不易&#xff0c;希望大家多多支持我呀&#xff01;&#xff08;三连&#xff0b;关注&…...

Django介绍

一、介绍 Django是Python语言中的一个Web框架&#xff0c;Python语言中主流的web框架有Django、Tornado、Flask 等多种 优势&#xff1a;大而全&#xff0c;框架本身集成了ORM、模型绑定、模板引擎、缓存、Session等功能&#xff0c;是一个全能型框架&#xff0c;拥有自己的A…...

【idea】几个不错的idea插件让我码速又快了

目录 前言 Gradianto插件 jclasslib Bytecode viewer插件 Grep Console 插件 GenerateAllSetter 插件 GsonFormat 插件 JRebel and XRebel 插件 leetcode editor 插件 maven helper 插件 SequenceDiagram 插件 Statistic 插件 Translation 插件 前言 idea可以说是j…...

LabVIEW直流电机转速检测与控制

研究了使用LabVIEW软件和ELVIS实验平台来检测和控制直流电机的转速。通过集成光电传感器和霍尔传感器&#xff0c;实现了对电机转速的精确测量和调节。 系统组成&#xff1a;系统由NI ELVIS实验平台、光电传感器、霍尔传感器和直流电机组成。通过这些硬件元件&#xff0c;系统…...

༺༽༾ཊ—Unity之-05-抽象工厂模式—ཏ༿༼༻

首先创建一个项目&#xff0c; 在这个初始界面我们需要做一些准备工作&#xff0c; 建基础通用文件夹&#xff0c; 创建一个Plane 重置后 缩放100倍 加一个颜色&#xff0c; 任务&#xff1a;使用 抽象工厂模式 创建 人物与宠物 模型&#xff0c; 首先资源商店下载 人物与宠物…...

力扣面试题02.07-链表相交

链表相交 题目链接 解题思路&#xff1a; 题目可以确定如果相交&#xff0c;那么相交的部分一定是在链表的结尾部分第一步求得两条链表的长度第二步长度做差&#xff0c;将长的那条链表与短的那条链表后部分对其第三步遍历后面的部分&#xff0c;如果当前节点相等&#xff0c;…...

Java集合-ArrayList

集合就是一个保存数据的容器。在计算机中引入集合&#xff0c;是为了便于处理一组类似的数据。Java标准库自带的java.util包提供了集合相关的接口和实现类&#xff1a;Collection接口&#xff0c;它是除了Map接口外所有其他集合类的根接口。 Java的Java.uitl包主要提供以下三种…...

数据结构·单链表经典例题

1. 移除链表元素 OJ链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 本题是说给出一个链表的头节点head和一个整数val&#xff0c;如果发现节点中存的数据有val就删掉它&#xff0c;最后返回修改后的链表头节点地址 如果题目中没有明确…...

Linux常用指令的整合

之前面试被问到了Linux相关的指令&#xff0c;所以我整理的一份常用的Linux指令列表&#xff0c;适用于大多数Linux发行版&#xff0c;现分享给大家&#xff1a; 文件操作 ls&#xff1a;列出目录内容。cd [目录]&#xff1a;更改当前目录。pwd&#xff1a;显示当前目录路径。m…...

阿里云centos安装mysql,并修改初始密码

阿里云centos安装mysql&#xff0c;并修改初始密码 安装数据库、修改初始密码、并测试建立自己的数据库步骤1&#xff1a;创建数据库和用户步骤2&#xff1a;配置Nginx1. 创建新的站点配置文件2. 编辑配置文件3. 保存并退出编辑器4. 测试配置文件是否正确5. 重新加载 Nginx 以应…...

【JavaScript基础入门】04 JavaScript基础语法(二)

JavaScript基础语法&#xff08;二&#xff09; 目录 JavaScript基础语法&#xff08;二&#xff09;变量变量是什么声明变量变量类型动态类型注释 数字与运算符数字类型算术运算符操作运算符比较运算符逻辑运算符运算符的优先级 变量 变量是什么 在计算机中&#xff0c;数据…...

标准库中的string类(下)——“C++”

各位CSDN的uu们你们好呀&#xff0c;这段时间小雅兰的内容仍然是Cstring类的使用的内容&#xff0c;下面&#xff0c;让我们进入string类的世界吧&#xff01;&#xff01;&#xff01; string类的常用接口说明 string - C Reference string类的常用接口说明 string类对象的修…...

如何使用Docker部署火狐浏览器并实现无公网ip远程访问

文章目录 1. 部署Firefox2. 本地访问Firefox3. Linux安装Cpolar4. 配置Firefox公网地址5. 远程访问Firefox6. 固定Firefox公网地址7. 固定地址访问Firefox Firefox是一款免费开源的网页浏览器&#xff0c;由Mozilla基金会开发和维护。它是第一个成功挑战微软Internet Explorer浏…...

瑞_数据结构与算法_AVL树

文章目录 1 什么是AVL树1.1 AVL树的背景及定义1.2 判断失衡1.2.1 平衡因子1.2.2 失衡的四种情况1.2.2.1 LL1.2.2.2 LR1.2.2.3 RL1.2.2.4 RR 1.3 解决失衡1.3.1 左旋&#xff08;RR&#xff09;1.3.2 右旋&#xff08;LL&#xff09;1.3.3 先左旋再右旋&#xff08;LR&#xff0…...

BGP同步规则

BGP同步规则:开启同步下,从IBGP收到一条路由不会传给任何EBGP邻居(实验效果IBGP邻居和EBGP邻居都不传),除非从自身的IGP中也学到这条路由。目的是防止AS内部出现路由黑洞,向外部通告了一个本AS不可达的虚假的路由。 同步规则只影响从IBGP邻居收到的路由,不影响从EBGP邻居收…...

Linux命令-apt-key命令(管理Debian Linux系统中的软件包密钥)

补充说明 apt-key命令 用于管理Debian Linux系统中的软件包密钥。每个发布的deb包&#xff0c;都是通过密钥认证 的&#xff0c;apt-key用来管理密钥。 语法 apt-key(参数)参数 操作指令&#xff1a;APT密钥操作指令。 实例 apt-key list # 列出已保存在系统中key。 apt-…...

Python根据Excel表进行文件重命名

一、问题背景 在日常办公过程中&#xff0c;批量重命名是经常使用的操作。之前我们已经进行了初步探索&#xff0c;主要是通过批处理文件、renamer软件或者Python中的pathlib等模块对当前目录下的文件进行批量重命名。 而今天我们要使用的是PythonExcel的方法对指定目录下的文…...

【UVM源码】UVM Config_db机制使用总结与源码解析

UVM Config_db机制使用总结与源码解析 UVM Config_db机制介绍UVM Config_db 机制引入的背景基本介绍使用方法优缺点&#xff1a; UVM Config_db机制使用示例&#xff1a;UVM Config_db使用高阶规则Config_db资源优先级 UVM Config_db 源码解析 UVM Config_db机制介绍 UVM Conf…...

群辉开启WebDav服务+cpolar内网穿透实现移动端ES文件浏览器远程访问本地NAS文件

文章目录 1. 安装启用WebDAV2. 安装cpolar3. 配置公网访问地址4. 公网测试连接5. 固定连接公网地址6. 使用固定地址测试连接 本文主要介绍如何在群辉中开启WebDav服务&#xff0c;并结合cpolar内网穿透工具生成的公网地址&#xff0c;通过移动客户端ES文件浏览器即可实现移动设…...

通过mybatis拦截器给sql执行加一个耗时监控

代码没什么内容&#xff0c;直接贴上来吧&#xff0c;其中costTimeUtil可以看我的另一篇博文&#xff1a;java实现一个不带次数变量的加权平均值算法-CSDN博客 Slf4j Intercepts({Signature(type StatementHandler.class,method "query",args {Statement.class, …...

mongodb源码分析session执行handleRequest命令find过程

mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程&#xff0c;并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令&#xff0c;把数据流转换成Message&#xff0c;状态转变流程是&#xff1a;State::Created 》 St…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

YSYX学习记录(八)

C语言&#xff0c;练习0&#xff1a; 先创建一个文件夹&#xff0c;我用的是物理机&#xff1a; 安装build-essential 练习1&#xff1a; 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件&#xff0c;随机修改或删除一部分&#xff0c;之后…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

微信小程序 - 手机震动

一、界面 <button type"primary" bindtap"shortVibrate">短震动</button> <button type"primary" bindtap"longVibrate">长震动</button> 二、js逻辑代码 注&#xff1a;文档 https://developers.weixin.qq…...

.Net Framework 4/C# 关键字(非常用,持续更新...)

一、is 关键字 is 关键字用于检查对象是否于给定类型兼容,如果兼容将返回 true,如果不兼容则返回 false,在进行类型转换前,可以先使用 is 关键字判断对象是否与指定类型兼容,如果兼容才进行转换,这样的转换是安全的。 例如有:首先创建一个字符串对象,然后将字符串对象隐…...

【JavaSE】多线程基础学习笔记

多线程基础 -线程相关概念 程序&#xff08;Program&#xff09; 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序&#xff0c;比如我们使用QQ&#xff0c;就启动了一个进程&#xff0c;操作系统就会为该进程分配内存…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

手动给中文分词和 直接用神经网络RNN做有什么区别

手动分词和基于神经网络&#xff08;如 RNN&#xff09;的自动分词在原理、实现方式和效果上有显著差异&#xff0c;以下是核心对比&#xff1a; 1. 实现原理对比 对比维度手动分词&#xff08;规则 / 词典驱动&#xff09;神经网络 RNN 分词&#xff08;数据驱动&#xff09…...

【技巧】dify前端源代码修改第一弹-增加tab页

回到目录 【技巧】dify前端源代码修改第一弹-增加tab页 尝试修改dify的前端源代码&#xff0c;在知识库增加一个tab页"HELLO WORLD"&#xff0c;完成后的效果如下 [gif01] 1. 前端代码进入调试模式 参考 【部署】win10的wsl环境下启动dify的web前端服务 启动调试…...