C++指针(三)

个人主页:PingdiGuo_guo

收录专栏:C++干货专栏

文章目录

前言

1.字符指针

1.1字符指针的概念

1.2字符指针的用处

1.3字符指针的操作

1.3.1定义

1.3.2初始化

1.4字符指针使用注意事项

2.数组参数,指针参数

2.1数组参数

2.1.1数组参数的概念

2.1.2数组参数的作用

2.1.3一维数组的传参

2.1.4二维数组的传参

2.2指针参数

2.2.1指针参数的概念

2.2.2指针参数的作用

2.2.3一级指针与二级指针

2.2.3一级指针的传参

2.2.4二级指针的传参

2.3练习

2.3.1数组参数的练习题目

2.3.2指针参数的练习题目

总结


前言

相关文章:C++指针(二)、C++指针(一)

本篇博客是介绍字符指针,数组参数与指针参数的。

1.字符指针

1.1字符指针的概念

字符指针是指向字符数组或字符串的指针。在C语言中,字符数组和字符串都是以字符指针的形式来操作和访问的。字符指针指向字符数组或字符串的第一个字符的地址,通过指针可以访问数组或字符串中的各个字符。

1.2字符指针的用处

字符指针有很多用途,以下是一些常见的用途:

1. C字符串操作:字符指针可以用来处理C字符串,包括字符串的拷贝、连接、比较等操作。由于C字符串以null字符结尾,我们可以使用字符指针来访问和操作字符串的每个字符。

2. 字符串数组访问:字符指针可以用于访问字符串数组中的每个字符串。通过递增指针的方式,可以依次访问字符串数组中的每个元素。

3. 动态内存分配:字符指针可以用于动态分配内存,即在程序运行时根据需要分配内存空间。通过使用`new`运算符,可以分配一段连续的内存,并返回第一个元素的指针。

4. 字符指针数组:字符指针可以用于创建指向字符的指针数组。这在处理多个字符串时非常有用,每个指针可以指向一个独立的字符串。

5. 文件操作:字符指针可以用于进行文件的读取和写入操作。通过指针的方式,我们可以逐字符或逐行读取文件内容,并将指针移动到文件的特定位置。

这些只是字符指针的一些常见用途,实际上,字符指针在C和C++中有广泛的应用,可以用于字符串处理、动态内存管理、文件操作等多种场景。

1.3字符指针的操作

1.3.1定义

字符指针需要关键字char*来定义,其他部分与普通指针的定义相同。如下:

char* ptr;

这样,我们就定义了一个字符指针。

1.3.2初始化

字符指针初始化有两种方式:

1.定义一个字符并为其赋值,然后用&来获取这个字符变量的地址。代码如下:


#include <bits/stdc++.h>
using namespace std;
int main()
{
	char ch = 'w';
	char* pc = &ch;
	cout<<*pc<<endl;
	return 0;
}

到这里,可能有些同学会疑惑:*pc里不是存储了变量ch的地址了么,为啥输出的是ch里的呢?

这里我们要注意,在代码中,*pc是一个解引用操作符,它用于获取指针pc所指向的内存地址上存储的值。在这种情况下,*pc表示获取指针pc所指向的内存地址上存储的字符。所以,cout<<*pc输出的是ch里的值,即字符w

那可能有些同学又要问了:PingdiGuo_guo,那啥情况输出的是地址呢?

注意:当我们直接输出指针变量本身时,会输出该指针变量所存储的地址而不是地址上的值。如果要输出指针变量所指向的地址上的值,需要使用解引用操作符*。

以下是一个例子:

#include <iostream>
using namespace std;

int main() {
    int x = 10;
    int* ptr = &x;

    cout << ptr << endl;   // 输出指针变量ptr的值,即x的地址
    cout << *ptr << endl;  // 输出指针ptr所指向的地址上存储的值,即x的值

    return 0;
}

上述代码输出结果:

第一行输出的是指针变量ptr存储的地址,第二行输出的是指针ptr所指向的地址上存储的值。

2.我们直接把一个字符串赋值给指针变量。如下:

​

#include <iostream>
using namespace std;
int main()
{
	const char* ps = "hello.";
    cout<<ps<<endl;
	return 0;
}


​

大家看一看,运行上述代码,*ps里储存的是什么呢?

有同学觉得储存的的应该是字符串"hello."的地址,实际上储存的是字符串"hello."的首字符,也就是字符'h'的地址。

1.4字符指针使用注意事项

字符指针使用注意事项:


1. 注意字符串的结束符:C语言中的字符串以'\0'作为结束符,因此在使用字符指针操作字符串时,需要确保字符串末尾有一个'\0'字符,否则可能导致未定义的行为。

2. 避免修改字符串常量:字符串常量是只读的,因此尝试修改字符串常量的内容会导致编译错误或者运行时错误。如果需要修改字符串,应该使用可修改的字符数组或者动态分配内存的字符指针。

3. 空指针检查:在使用字符指针之前,应该进行空指针检查,以避免对空指针进行操作,导致程序崩溃或者出现未定义的行为。

4. 确保指针指向有效的内存区域:在使用字符指针操作字符串时,应确保指针指向的内存区域包含了足够的空间,以存储字符串的内容,并且字符串的结束符'\0'也需要在指针指向的内存区域内。

5. 避免指针越界访问:在使用字符指针操作字符串时,应避免指针越界访问,即超过了字符串的有效范围进行访问,这可能导致程序崩溃或者出现未定义的行为。

6. 避免指针悬挂:在使用字符指针时,需要确保指针指向的内存区域有效,并且在指针不再使用时及时释放或者置为NULL,以避免产生悬挂指针或者内存泄漏的问题。

7. 注意指针运算的规则:字符指针支持指针运算,例如指针加法和指针减法,但要注意指针运算时遵循指针的类型大小,以避免指针运算越界或者计算错误。

8. 使用函数库提供的字符串操作函数:C语言提供了一系列函数库来操作字符串,例如strcpy、strlen、strcat等,使用这些函数能够更方便、安全地操作字符串,同时避免常见的错误。

2.数组参数,指针参数

2.1数组参数

2.1.1数组参数的概念

数组参数是指在函数的参数列表中声明一个数组作为参数。当函数被调用时,实际传递给该参数的是数组的地址,而不是整个数组本身。通过使用数组参数,可以将数组的内容传递给函数,并在函数中对数组进行操作或者返回相应的结果。

2.1.2数组参数的作用

数组参数在函数中的作用主要包括以下几点:

1. 传递数组数据:通过数组参数,可以将数组的数据传递给函数进行处理。函数可以读取、修改数组的元素,执行各种操作。

2. 减少内存开销:使用数组参数可以避免将整个数组的副本传递给函数,而是只传递数组的地址或首元素地址。这样可以减少内存开销和数据复制次数。

3. 返回数组数据:函数也可以通过数组参数返回数据。在函数内部修改数组元素后,函数外部的数组也会被修改。

4. 可变长度数组:在函数参数中使用可变长度数组,可以根据需要传递不同大小的数组。这样可以编写更加灵活的函数,适应不同规模的数据。

5. 简化代码:通过使用数组参数,可以将对数组的一系列操作封装在函数中,提高代码的可读性和可维护性。

总的来说,数组参数可以使函数更加灵活、高效地处理数组数据,提高代码的可复用性和可维护性。它是C语言中非常重要的函数参数类型之一。

2.1.3一维数组的传参

void is(int a[])
{
}
void id(int a[100])
{
}
void ih(int* a[10])
{
}
​
void ij(int* a)
{
}

​
void ig(int** a)
{
}

注:上述这些格式都可以运行。

2.1.4二维数组的传参

二维数组的传参基本形式与一维数组类似,只是在声明参数时需要指明数组的行数和列数。

// 形参为二维数组,指定列数的方式
void functionName(dataType arrayName[][columns], int rows) {
    // 函数体
    // 可以通过双重循环访问和修改数组元素
}
// 形参为二维数组,指定指针的方式
void functionName(dataType *arrayName[], int rows, int columns) {
    // 函数体
    // 可以通过双重循环访问和修改数组元素
}
// 形参为二维数组,指定指向指针的指针的方式
void functionName(dataType **arrayName, int rows, int columns) {
    // 函数体
    // 可以通过双重循环访问和修改数组元素
}

在上述代码中,dataType是数组中元素的数据类型,arrayName是二维数组的名称,rows是数组的行数,columns是数组的列数。

在函数参数列表中,我们可以使用dataType arrayName[][columns]或者dataType *arrayName[]或dataType **arrayName来声明一个二维数组作为参数。

在函数体内部,可以使用双重循环来访问和修改二维数组的元素。

2.2指针参数

2.2.1指针参数的概念

指针参数是指函数中的参数被声明为指针类型的参数。指针参数允许函数通过引用传递内存地址,从而能够修改原始数据的值。

2.2.2指针参数的作用

指针参数的作用有以下几个方面:

1. 传递大型数据结构:通过将指针作为参数传递给函数,可以避免复制整个数据结构。这对于大型结构体或数组来说尤为重要,可以提高程序性能。

2. 在函数内部修改变量的值:通过传递指向变量的指针作为参数,函数可以直接修改变量的值。这对于需要在函数中修改全局变量或者需要通过函数返回多个值的情况非常有用。

3. 动态内存分配:通过指针参数,可以在函数内部对动态分配的内存进行操作。例如,在函数中动态创建一个数组,并通过指针参数返回数组的地址。

4. 传递数组:通过将数组的首地址作为指针参数传递给函数,可以在函数内部操作数组中的元素。

需要注意的是,使用指针参数需要谨慎,避免出现空指针或者越界访问等问题。在使用指针参数时,需要确保传递正确的地址,并在函数内部对指针进行适当的处理和保护。

总之,指针参数在函数传参中具有重要作用,可以通过引用传递内存地址,实现对变量和数据的修改和操作。

2.2.3一级指针与二级指针

一级指针和二级指针是指针的不同级别。

一级指针(Level 1 Pointer)是指一个指针变量(如int*)指向一个存储地址,该地址保存了一个值或者另一个指针。通过一级指针可以直接访问到被指向的内存地址中的值。

二级指针(Level 2 Pointer),也被称为指向指针的指针,是指一个指针变量(如int**)存储了一个指针的地址。通过二级指针可以间接地访问到被指向的内存地址中的值。

二级指针常用于需要对一级指针进行修改的情况,例如在函数中传入一个指针的指针,以便修改指针的值。同时,你也可以定义三级指针、四级指针以及更高级别的指针,但在实际开发中很少用到。

2.2.3一级指针的传参

一级指针的传参是通过将指针作为函数的参数传递给函数

在函数中,可以通过一级指针来访问和修改指针所指向的值。

下面是一级指针传参的基本形式:

void func(int* ptr) {
    // 使用指针访问和修改指针所指向的值
    *ptr = 10;
    // ...
}

int main() {
    int x = 0;
    int* p = &x;
    // 将指针p作为参数传递给函数func
    func(p);
    // x的值已经被修改为10
    return 0;
}


 

在上面的例子中,通过将指针p作为参数传递给函数func,函数内部可以通过指针ptr来访问和修改p所指向的值。在函数中,通过解引用操作符*来访问指针所指向的值。

需要注意的是,传递一级指针作为参数时,函数内部对指针所指向的值的修改是有效的,因为传递的是指针变量本身的地址,而不是指针变量的副本。

问:在这种情况下,函数能接受什么参数?

答:在这种情况下,函数func可以接受一个指向整型变量的指针作为参数。在main函数中,通过将指针p作为参数传递给func函数,函数func可以使用指针访问和修改指针所指向的值。

2.2.4二级指针的传参

二级指针的传参是通过将指向指针的指针作为函数的参数传递给函数

二级指针在某些情况下用于传递指针数组或二维数组的地址,或者用于动态分配内存等场景。

下面是二级指针传参的基本形式:


 

void func(int** ptr) {
    // 使用二级指针访问和修改指针所指向的值
    **ptr = 20;
    // ...
}

int main() {
    int x = 0;
    int* p = &x;
    int** pp = &p;
    // 将二级指针pp作为参数传递给函数func
    func(pp);
    // x的值已经被修改为20
    return 0;
}

在上面的例子中,通过将二级指针pp作为参数传递给函数func,函数内部可以通过二级指针ptr来访问和修改pp所指向的值。在函数中,通过解引用操作符*两次来访问指针所指向的值。

需要注意的是,传递二级指针作为参数时,需要对指针进行两次解引用才能访问到最终的值。在函数内部修改指针所指向的值也是有效的。

此外,还要注意对于二维数组的传参,可以使用一级指针或二级指针来传递二维数组的地址。

问:在这种情况下,函数能接受什么参数?

答:在这种情况下,函数func可以接受一个指向指向整型变量的一级指针的二级指针作为参数。

2.3练习

2.3.1数组参数的练习题目

题目:

编写一个函数,接收一个整型数组和数组长度作为参数,并返回数组中的最大值。

步骤:
1. 在main函数中声明一个整型数组并初始化。
2. 定义一个函数findMax,接收一个整型数组和数组长度作为参数,并返回一个整型值。
3. 在findMax函数中,定义一个变量max,初始化为数组的首个元素。
4. 使用循环遍历数组,比较数组中的每个元素与max的值,并更新它。
5. 返回最大值。
6. 在main函数中调用findMax函数,并将返回值打印出来。

流程图:
 

开始
声明和初始化数组以及定义数组长度
定义函数findMax,接收数组和长度作为参数,并返回最大值
定义变量max,并初始化为数组的首个元素
循环遍历数组
    比较当前元素和max的值,若大于max,则更新max的值
返回max
调用findMax函数并打印返回值
结束


 

代码:
 

#include <iostream>

int findMax(int arr[], int size) {
    int max = arr[0];
    
    for (int i = 1; i < size; i++) {
        if (arr[i] > max) {
            max = arr[i];
        }
    }
    
    return max;
}

int main() {
    int arr[] = {3, 5, 1, 4, 2};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    int max = findMax(arr, size);
    
    std::cout << "Max: " << max << std::endl;
    
    return 0;
}

在这个例子中,findMax函数接收一个整型数组和数组长度作为参数,并返回最大值。函数内部使用循环遍历数组,比较每个元素与max的值,并根据情况更新它。在main函数中声明数组arr并初始化,然后调用findMax函数并传递相应的参数,将返回值存储在max变量中,并使用std::cout 打印出来。

运行结果:

2.3.2指针参数的练习题目

题目:

编写一个函数,接收一个整型数组的指针和数组长度作为参数,并将数组中的所有元素翻转。

步骤:
1. 在main函数中声明一个整型数组并初始化。
2. 定义一个函数reverseArray,接收一个指向整型数组的指针和数组长度作为参数,并将数组中的所有元素翻转。
3. 在reverseArray函数中,使用两个指针start和end,分别指向数组的起始和末尾位置。
4. 使用循环,交换`start`和`end`指针所指向的元素,并同时将`start`往后移动一位,`end`往前移动一位。
5. 循环继续,直到start指针超过或等于end指针。
6. 在main函数中调用reverseArray函数,并将修改后的数组打印出来。

流程图:
 

开始
声明和初始化数组以及定义数组长度
定义函数reverseArray,接收整型数组指针和长度作为参数
定义指针start,指向数组起始位置
定义指针end,指向数组末尾位置
循环,交换start和end指针所指向的元素,并同时移动start和end指针
    若start指针超过或等于end指针,则跳出循环
在main函数中调用reverseArray函数,并打印修改后的数组
结束


 

代码:

 

#include <iostream>

void reverseArray(int* arr, int size) {
    int* start = arr;
    int* end = arr + size - 1;
    
    while (start < end) {
        int temp = *start;
        *start = *end;
        *end = temp;
        
        start++;
        end--;
    }
}

int main() {
    int arr[] = {1, 2, 3, 4, 5};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    std::cout << "Original array: ";
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
    
    reverseArray(arr, size);
    
    std::cout << "Reversed array: ";
    for (int i = 0; i < size; i++) {
        std::cout << arr[i] << " ";
    }
    std::cout << std::endl;
    
    return 0;
}

在这个例子中,reverseArray函数接收一个指向整型数组的指针和数组长度作为参数,并将数组中的所有元素翻转。函数内部使用两个指针start和end分别指向数组的起始和末尾位置,通过循环交换指针所指向的元素,并同时移动指针,直到start指针超过或等于`end`指针。在main函数中声明数组arr并初始化,然后调用reverseArray函数并传递相应的参数,将数组的元素翻转。最后使用std::cout打印出原始数组和翻转后的数组。

运行结果:

总结

本篇博客到这里就结束了,感谢大家的支持与观看,如果有好的建议欢迎留言,谢谢大家啦!

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

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

相关文章

论文阅读_代码生成模型_CodeLlama

英文名称: Code Llama: Open Foundation Models for Code 中文名称: Code Llama&#xff1a;开放基础代码模型 链接: https://arxiv.org/abs/2308.12950 代码: https://github.com/facebookresearch/codellama 作者: Baptiste Rozire, Jonas Gehring, Fabian Gloeckle, Sten So…

微信小程序云开发教程——墨刀原型工具入门(文件设置+编辑组件)

引言 作为一个小白&#xff0c;小北要怎么在短时间内快速学会微信小程序原型设计&#xff1f; “时间紧&#xff0c;任务重”&#xff0c;这意味着学习时必须把握微信小程序原型设计中的重点、难点&#xff0c;而非面面俱到。 要在短时间内理解、掌握一个工具的使用&#xf…

C++STL之vector

vector 1. vector介绍 vector文档vector其实就是一个顺序表&#xff0c;它表示可变大小数组的序列容器。像数组一样&#xff0c;可以使用下标[] 来访问vector的元素&#xff0c;和数组一样高效&#xff1b;甚至&#xff0c;它的大小是可以动态改变的&#xff0c;其大小由容器自…

广和通5G智能模组SC171支持Android、Linux和Windows系统,拓宽智能物联网应用

世界移动通信大会2024期间&#xff0c;广和通宣布&#xff1a;5G智能模组SC171除支持Android操作系统外&#xff0c;还兼容Linux和Windows系统&#xff0c;帮助更多智能终端客户快速迭代产品&#xff0c;拓宽智能化应用覆盖范围。 广和通SC171系列基于高通QCM6490物联网解决方案…

Redis安全加固策略:服务账号管理 开启redis密码认证 开启防护模式

Redis安全加固策略&#xff1a;服务账号管理 & 开启redis密码认证 & 开启防护模式 1.1 服务账号管理1.1.1 检测方法1.1.2 加固参考配置操作 1.2 开启redis密码认证1.2.1 检测方法1.2.2 加固参考配置操作 1.3 开启防护模式1.3.1 检测方法1.3.2 加固参考配置操作 &#x…

图神经网络实战——基于DeepWalk创建节点表示

图神经网络实战——基于DeepWalk创建节点表示 0. 前言1. Word2Vec1.1 CBOW 与 skip-gram1.2 构建 skip-gram 模型1.3 skip-gram 模型1.4 实现 Word2Vec 模型 2. DeepWalk 和随机行走3. 实现 DeepWalk小结系列链接 0. 前言 DeepWalk 是机器学习 (machine learning, ML) 技术在图…

【NR 定位】3GPP NR Positioning 5G定位标准解读(三)

目录 前言 5 NG-RAN UE定位架构 5.1 架构 5.2 UE定位操作 5.3 NG-RAN定位操作 5.3.1 通用NG-RAN定位操作 5.3.2 OTDOA定位支持 5.3.3 广播辅助信息支持 5.3.4 NR RAT相关定位支持 5.4 NG-RAN中与UE定位相关的元素功能描述 5.4.1 用户设备&#xff08;UE&#xff09; …

寻址错题本

指令寻址 顺序寻址 通过程序计数器PC自动加1,形成下一条指令的指令地址。 跳跃寻址 通过转移类指令实现跳转到指定的代码段或者子程序。 数据寻址 直接寻址 形式地址A就是操作数的地址EA,执行阶段访问一次存储器。 所以当我们需要取得实际的值(操作数)的时候: 第一步:…

项目实战 MySQL读写分离【构建主从结构数据库(查从库)(增删改主库)】【ShardingJDBC实现读写分离】

项目实战 MySQL读写分离 1. MySQL主从复制1.1 介绍1.2 搭建1.2.1 准备工作1.2.3 从库配置 2. 读写分离案例2.2 ShardingJDBC介绍 转自-黑马 在前面基础功能实现的过程中&#xff0c;我们后台管理系统及移动端的用户&#xff0c;在进行数据访问时&#xff0c;都是直接操作数据库…

MYSQL---日志

1.日志的概述 日志是MySQL数据库的重要组成部分。日志文件中记录着MySQL数据库运行期间发生的变化&#xff1b;也就是说用来记录MySQL数据库的客户端连接状况、SQL语句的执行情况和错误信息等。当数据库遭到意外的损坏时&#xff0c;可以通过日志查看文件出错的原因&#xff0…

自定义类型(结构体、枚举、联合体)内存大小的计算方法

内存对齐 为什么会存在内存对齐&#xff1f; 大部分参考资料是这么说的&#xff1a; 平台原因(移植原因)&#xff1a; 不是所有的硬件平台都能访问任意地址上的任意数据的&#xff1b;某些硬件平台只能在某些地址处取某些特定类型的数据&#xff0c;否则抛出硬件异常。性能原…

LeetCode---386周赛

题目列表 3046. 分割数组 3047. 求交集区域内的最大正方形面积 3048. 标记所有下标的最早秒数 I 3049. 标记所有下标的最早秒数 II 一、分割数组 这题简单的思维题&#xff0c;要想将数组分为两个数组&#xff0c;且分出的两个数组中数字不会重复&#xff0c;很显然一个数…

Apache Flink连载(三十七):Flink基于Kubernetes部署(7)-Kubernetes 集群搭建-2

🏡 个人主页:IT贫道-CSDN博客 🚩 私聊博主:私聊博主加WX好友,获取更多资料哦~ 🔔 博主个人B栈地址:豹哥教你学编程的个人空间-豹哥教你学编程个人主页-哔哩哔哩视频 目录

BUGKU 网站被黑

打开环境&#xff0c;什么都没发现&#xff0c;使用蚁剑扫描一下&#xff0c;发现shell.php&#xff0c;打开 使用BP抓包&#xff0c;进行爆破 得到密码&#xff1a;hack 进去得到flag

Vins-Moon配准运行

Vins-Moon运行 源码地址电脑配置环境配置编译适配Kitti数据集运行结果Euroc数据集kitti数据集 evo评估&#xff08;KITTI数据&#xff09;输出轨迹(tum格式)结果 源码地址 源码链接&#xff1a;https://github.com/HKUST-Aerial-Robotics/VINS-Mono.git 电脑配置 Ubuntu 18.…

2024年不容错过的行业峰会盛宴,引领未来商业潮流!

随着全球经济的不断演变和科技的日新月异&#xff0c;行业峰会成为了企业领袖、创新者和投资者们洞察未来趋势、交流前沿思想的重要平台。 2024年&#xff0c;一系列引人瞩目的行业峰会即将拉开帷幕&#xff0c;它们将汇聚全球精英&#xff0c;共同探讨各行业的未来发展之路。…

ssm637教材管理系统

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一 、设计说明 1.1研究背…

day02-JavaScript-Vue

文章目录 1 JavaScript1.1 介绍 1.2 引入方式1.3 基础语法1.3.1 书写语法1.3.2 变量1.3.3 数据类型和运算符 1.4 函数1.4.1 第一种定义格式1.4.2 第二种定义格式 1.5 JavaScript对象1.5.1 基本对象1.5.1.1 Array对象语法格式特点属性和方法 1.5.1.2 String对象语法格式属性和方…

unity学习(45)——选择角色菜单——客户端处理服务器的数据

1.已知客户端ReceiveCallBack中已经收到来自服务器返回的数据包。 2.问题是客户端MessageManager中的Update并没有拆解该数据包 &#xff0c;因该是因为脚本没有挂载。 挂在SelectMenu场景中的Camera上即可。 挂载后成功达到目地 其中Update中的List是一个起到全局效果的static…

[GYCTF2020]EasyThinking --不会编程的崽

看标题就知道&#xff0c;这大概率是关于thinkphp的题目。先尝试错误目录使其报错查看版本号 thinkphp v6.0.0&#xff0c;在网上搜索一下&#xff0c;这个版本有一个任意文件上传漏洞。参考以下文章。 https://blog.csdn.net/god_zzZ/article/details/104275241 先注册一个账…