C语言指针详解与实战教程
学习知识要善于思考,思考,再思考!今天golang学习网小编就给大家带来《C语言指针详解:概念、优势与实战代码》,以下内容主要包含等知识点,如果你正在学习或准备学习科技周边,就都不要错过本文啦~让我们一起来看看吧,能帮助到你就更好了!

C 语言以其高效、灵活而著称,至今仍是系统编程、嵌入式开发等领域的重要工具。而指针,是 C 语言的灵魂,也是让许多初学者望而却步的难点。指针的概念理解起来比较抽象,但掌握指针,对于理解 C 语言的内存管理机制、提高编程效率至关重要。本文将带你一步步揭开 C 语言指针的神秘面纱,从指针的基本概念入手,剖析指针的优势,并结合代码示例,让你在实践中掌握指针的精髓,彻底告别指针恐惧症。无论是准备参加 C 语言考试,还是希望提升编程技能,本文都将为你提供有力的帮助。准备好开启你的指针探索之旅了吗?让我们一起深入 C 语言的世界,掌握指针的奥秘!
C 语言指针学习要点
指针的定义: 指针是一种特殊的变量,它存储的是另一个变量的内存地址。
指针的声明: 需要指定指针所指向变量的数据类型。
地址运算符 &: 用于获取变量的内存地址。
*间接寻址运算符 ``:** 用于访问指针所指向内存地址中存储的值。
指针的算术运算: 指针可以进行加减运算,但要注意其含义是指针地址的移动,与数据类型大小相关。
指针与数组: 数组名本质上是一个指向数组首元素的指针。
指针与函数: 可以将指针作为函数参数传递,实现对函数外部变量的修改。
动态内存分配: 指针可以用于动态分配内存空间,灵活管理程序所需的内存。
空指针 NULL: 在声明指针时,如果暂时没有指向的内存地址,可以将其初始化为 NULL,避免野指针的出现。
深入理解 C 语言指针
什么是 C 语言指针?指针的定义
在 C 语言中,指针是一种特殊的变量,它存储的是另一个变量在内存中的地址。 想象一下,你的电脑内存就像一栋大楼,每个房间都有一个唯一的房间号。普通变量就相当于住在这个房间里的人,而指针变量,就相当于记录了某个房间号的纸条。通过这张纸条,我们可以找到对应的房间,进而找到住在里面的人。
简单来说,指针就是存储内存地址的变量。这个地址指向内存中的某个位置,而该位置可能存储着一个变量的值,一段数据,甚至是一段代码。
让我们用一个例子来进一步理解:
假设我们有一个整型变量 age,它的值为 21。我们可以声明一个指针变量 pAge,让它存储变量 age 的内存地址。这样,pAge 就指向了 age 变量。
代码示例:
<code>int age = 21; // 声明一个整型变量 age,赋值为 21 int *pAge; // 声明一个整型指针变量 pAge pAge = &age; // 将 age 的内存地址赋值给 pAge</code>
在这个例子中:
int *pAge;声明了一个名为pAge的指针变量,int *表示pAge是一个指向整型变量的指针。&age使用了地址运算符&,获取了变量age的内存地址。pAge = &age;将age的内存地址赋值给pAge,使得pAge指向了age变量。
指针的声明:
在 C 语言中,声明指针变量需要指定其指向的数据类型。
语法:
<code>data_type *pointer_name;</code>
data_type表示指针所指向变量的数据类型,例如int、char、float等。*表示声明的是一个指针变量。pointer_name是指针变量的名称。
例如:
int *ptr;声明一个指向整型变量的指针。char *str;声明一个指向字符型变量的指针。float *fp;声明一个指向浮点型变量的指针。
需要注意的是,指针变量本身也是需要占用内存空间的。指针变量存储的是内存地址,而内存地址通常是一个固定长度的数值(例如,在 32 位系统中,地址通常是 4 字节,在 64 位系统中,地址通常是 8 字节)。因此,指针变量的大小与它所指向的数据类型无关,只与系统的寻址能力有关。
总而言之,指针是 C 语言中一种非常强大而灵活的工具,理解指针的概念是掌握 C 语言的关键。通过指针,我们可以直接操作内存,实现更高效、更灵活的编程。
使用 printf() 显示变量的地址和值
要理解指针,需要先了解变量的两个重要属性:值(value)和地址(address)。每个变量在内存中都占据一定的空间,拥有一个唯一的地址,而变量的值就存储在这个地址对应的内存单元中。
代码示例:
以下代码演示了如何使用 printf() 函数显示变量的地址和值:
<code>#include <stdio.h>
int main() {
int age = 21;
printf("address of age: %p
", &age);
printf("value of age: %d
", age);
return 0;
}</stdio.h></code>
代码解读:
%p是printf()函数的一个格式说明符,用于以十六进制格式显示内存地址。&age是地址运算符,用于获取变量age的内存地址。%d是printf()函数的一个格式说明符,用于显示十进制整数。
程序运行结果:
程序将输出变量 age 的内存地址和值,例如:
address of age: 000000000061FE1C value of age: 21
代码演示:上述代码展示了变量 age 拥有一个十六进制格式的内存地址(例如:000000000061FE1C)以及一个十进制的值(21)。printf 函数能够帮助我们直观的观察到变量在内存中的存储情况,这对于理解指针的概念至关重要。
总结:
- 每个变量都有地址和值。
- 使用地址运算符
&来获取变量的地址。 printf()函数的%p格式说明符可以用来显示地址。
理解了变量的地址和值,才能更好地理解指针,因为指针本质上就是存储变量地址的变量。
C 语言指针变量:存储地址的“纸条”
理解了变量的地址和值之后,让我们深入了解指针变量。 指针变量是一种特殊的变量,它的值是另一个变量的内存地址。可以将指针变量看作是存储地址的“纸条”,通过这张“纸条”,我们可以找到对应的变量,并访问其存储的值。
如何声明指针变量?
在 C 语言中,声明指针变量需要指定其指向的数据类型,并使用 * 符号来表示这是一个指针变量。
语法:
<code>data_type *pointer_name;</code>
data_type表示指针所指向变量的数据类型,例如int、char、float等。*表示声明的是一个指针变量。pointer_name是指针变量的名称。
例如:
int *ptr;声明一个指向整型变量的指针。char *str;声明一个指向字符型变量的指针。float *fp;声明一个指向浮点型变量的指针。
如何将变量的地址赋值给指针变量?
可以使用地址运算符 & 来获取变量的地址,然后将其赋值给指针变量。
例如:
<code>int age = 21; int *pAge = &age; // 将 age 的地址赋值给 pAge</code>
如何通过指针变量访问所指向的变量的值?
可以使用间接寻址运算符 * 来访问指针变量所指向的内存地址中存储的值。
例如:
<code>int age = 21;
int *pAge = &age;
printf("Value of age: %d
", *pAge); // 通过 pAge 访问 age 的值</code>
在这个例子中,*pAge 表示访问 pAge 所指向的内存地址中存储的值,也就是变量 age 的值,因此程序将输出 Value of age: 21。
代码演示:
<code>#include <stdio.h>
int main() {
int age = 21;
int *pAge = &age; // 声明并初始化指针变量 pAge
printf("address of age: %p
", &age);
printf("value of pAge: %p
", pAge); // 指针变量存储的是地址
printf("size of age: %d bytes
", sizeof(age));
printf("size of pAge: %d bytes
", sizeof(pAge)); // 指针变量本身的大小
printf("value of age: %d
", age);
printf("value at stored address: %d
", *pAge); // 通过指针访问变量的值
return 0;
}</stdio.h></code>
程序输出:
address of age: 000000000061FE14 value of pAge: 000000000061FE14 size of age: 4 bytes size of pAge: 8 bytes value of age: 21 value at stored address: 21
程序解读:
address of age和value of pAge输出相同的值,这说明指针变量pAge确实存储了变量age的内存地址。size of age输出4 bytes,因为age是一个int类型的变量,占用 4 个字节的内存空间。size of pAge输出8 bytes,这说明指针变量本身占用 8 个字节的内存空间(在 64 位系统中)。value of age和value at stored address输出相同的值,这说明我们可以通过指针变量pAge成功访问到变量age的值。
总结:
- 指针变量存储的是变量的内存地址。
- *可以使用 `` 运算符通过指针访问其指向的变量的值**。
- 指针变量本身也需要占用内存空间,其大小与系统有关。
理解指针变量的概念,是掌握 C 语言指针的核心。通过指针,我们可以间接访问和操作内存中的数据,实现更灵活、更高效的编程。
C 语言指针的优势
使用指针的优点和好处
C 语言指针虽然学习曲线陡峭,但掌握后能带来诸多好处。以下表格总结了 C 语言中使用指针的优势:
| 优势 | 描述 |
|---|---|
| 代码效率 | 指针允许直接访问内存,避免了不必要的数据拷贝,提高了代码的执行效率。 |
| 修改函数外部变量 | 通过将指针作为函数参数传递,可以在函数内部修改函数外部的变量的值。 |
| 动态内存分配 | 指针可以用于动态分配和释放内存,灵活管理程序所需的内存空间。 |
| 数据结构 | 指针是实现链表、树等复杂数据结构的基础。 |
| 处理字符串 | C 语言中的字符串本质上是字符数组,使用指针可以方便地对字符串进行各种操作。 |
| 与硬件交互 | 在系统编程和嵌入式开发中,指针可以直接操作硬件寄存器,实现与硬件的交互。 |
总而言之,指针是 C 语言中一种非常强大而灵活的工具,合理使用指针可以提高代码效率、节省内存空间,并实现更复杂的功能。但是,指针也存在一定的风险,例如空指针、野指针等,需要谨慎使用,避免程序出现错误。以下将分别讨论。
- 减少程序执行时间 指针能够直接访问内存,而无需像其他变量那样通过多层寻址。这能够极大地提升程序的执行速度,尤其是在处理大量数据时。
- 直接操作原始变量 使用指针,函数可以直接修改调用者提供的变量,无需创建副本。这在节省内存和提高效率方面非常重要。
- 构建复杂数据结构 无论是链表、树,还是图,指针都是构建这些数据结构的基础。它们允许数据以非连续的方式存储,并能够灵活地组织和访问。
- 从函数返回多个值 虽然 C 语言的函数直接返回值数量有限,但通过指针参数,函数可以修改多个外部变量,从而“返回”多个结果。
- 高效搜索与排序 指针特别适合处理大量数据的搜索和排序操作。通过操作指针,可以避免昂贵的数据复制,实现更高效的算法。
- 动态内存分配 利用指针,程序可以在运行时动态地申请和释放内存,这对于处理大小不确定的数据非常有用。
C 语言指针的实践应用:代码示例
声明和初始化指针变量
要使用指针,首先需要声明一个指针变量。 声明指针变量需要指定其指向的数据类型,并使用 * 符号来表示这是一个指针变量。
语法:
<code>data_type *pointer_name;</code>
示例:
<code>int *pAge; // 声明一个指向整型变量的指针</code>
在声明指针变量之后,需要将其初始化,使其指向一个有效的内存地址。可以使用地址运算符 & 来获取变量的地址,然后将其赋值给指针变量。
示例:
<code>int age = 21; int *pAge = &age; // 将 age 的地址赋值给 pAge</code>
注意:
- 指针变量必须初始化才能使用,否则可能导致程序崩溃。
- 如果暂时没有指向的内存地址,可以将指针变量初始化为
NULL,表示空指针。 - NULL指针可以解决*野指针问题,可以先给指针设置为空,使用前在设置指针的目标变量地址可以有效解决该问题。
通过指针访问变量的值
可以使用间接寻址运算符 * 来访问指针变量所指向的内存地址中存储的值。这个操作被称为解引用(dereference)。
示例:
<code>int age = 21;
int *pAge = &age;
printf("Value of age: %d
", *pAge); // 通过 pAge 访问 age 的值</code>
在这个例子中,*pAge 表示访问 pAge 所指向的内存地址中存储的值,也就是变量 age 的值,因此程序将输出 Value of age: 21。
注意:
- 只能对已初始化的指针变量进行解引用操作,否则可能导致程序崩溃。
- 解引用操作符
*只能用于指针变量,不能用于普通变量。
指针的算术运算
指针可以进行加减运算,但其含义与普通变量的加减运算不同。指针的算术运算是指针地址的移动,移动的字节数与指针所指向的数据类型的大小有关。
例如:
<code>int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr 指向数组 arr 的首元素
printf("Value of ptr: %p
", ptr);
ptr++; // ptr 指向数组 arr 的下一个元素
printf("Value of ptr: %p
", ptr);</code>
在这个例子中,ptr++ 表示将指针 ptr 向后移动一个整型变量的大小(通常为 4 个字节),使其指向数组 arr 的下一个元素。
注意:
- 指针的算术运算只能用于指向相同数据类型的指针。
- 指针的算术运算容易出错,需要谨慎使用。
指针与数组
C 语言中的数组名本质上是一个指向数组首元素的指针。这意味着,可以使用指针来访问数组的元素。
例如:
<code>int arr[5] = {1, 2, 3, 4, 5};
int *ptr = arr; // ptr 指向数组 arr 的首元素
printf("Value of arr[0]: %d
", *ptr);
printf("Value of arr[1]: %d
", *(ptr + 1));</code>
在这个例子中,*ptr 表示访问数组 arr 的首元素,*(ptr + 1) 表示访问数组 arr 的第二个元素。
使用指针访问数组元素的好处:
- 代码更简洁:使用指针可以避免使用下标,使代码更简洁易读。
- 效率更高:使用指针可以避免数组下标的计算,提高代码效率。
注意:
- 数组名不能被赋值,因为它是一个常量指针。
- 指针的算术运算需要小心,避免越界访问。
指针与函数
可以将指针作为函数参数传递,实现对函数外部变量的修改。 这在 C 语言中非常常见,可以用于实现一些高级功能。
示例:
<code>#include <stdio.h>
void increment(int *num) {
(*num)++; // 通过指针修改 num 的值
}
int main() {
int age = 21;
increment(&age); // 将 age 的地址传递给 increment 函数
printf("Value of age: %d
", age);
return 0;
}</stdio.h></code>
在这个例子中,increment() 函数接受一个指向整型变量的指针作为参数,并在函数内部通过指针修改了该变量的值。在 main() 函数中,我们将变量 age 的地址传递给 increment() 函数,因此 age 的值被成功修改为 22。
注意:
- 在函数内部,需要使用解引用操作符
*才能访问指针所指向的变量的值。 - 通过指针传递参数,可以避免函数内部对参数的修改影响函数外部的变量。
C 语言指针的优缺点分析
? Pros高效性: 直接操作内存,避免数据拷贝,提高效率。
灵活性: 动态内存分配,实现复杂数据结构。
函数交互: 修改函数外部变量,实现多返回值。
硬件操作: 直接访问硬件寄存器,与硬件交互。
? Cons复杂性: 概念抽象,学习曲线陡峭。
安全性: 容易出现空指针、野指针等问题。
可读性: 指针操作可能降低代码可读性。
C 语言指针常见问题解答
什么是野指针?如何避免野指针?
野指针是指指向无效内存地址的指针。例如,指针指向的内存已经被释放,或者指针没有被初始化就使用了。野指针会导致程序崩溃或产生不可预测的行为。 如何避免野指针: 初始化指针: 在声明指针变量时,一定要将其初始化为一个有效的内存地址,或者将其设置为 NULL。NULL 指针表示该指针当前没有指向任何有效的内存地址。 释放内存后将指针设置为 NULL: 当使用 free() 函数释放了指针所指向的内存后,一定要将指针设置为 NULL,避免该指针再次被使用。 避免返回局部变量的地址: 不要在函数中返回局部变量的地址,因为当函数执行结束后,局部变量的内存空间会被释放,导致指针指向无效的内存地址。 谨慎使用指针运算: 在进行指针运算时,一定要小心,避免指针越界访问内存。 示例: int *ptr = NULL; // 声明并初始化指针为 NULL int age = 21; ptr = &age; // 将 ptr 指向 age free(ptr); // 错误:不能释放栈内存 ptr = NULL; // 避免 ptr 成为悬挂指针
什么是空指针?空指针有什么作用?
空指针是指值为 NULL 的指针。NULL 是一个预定义的常量,通常表示内存地址 0,表示该指针不指向任何有效的内存地址。空指针主要用于以下几个方面: 作为指针的初始值: 在声明指针变量时,如果暂时没有指向的内存地址,可以将其初始化为 NULL,避免野指针的出现。 作为函数返回值: 函数可以返回一个指针,如果函数执行失败,可以返回 NULL,表示没有找到有效的结果。 用于判断指针的有效性: 在使用指针之前,可以先判断其是否为空指针,避免对空指针进行解引用操作。 示例: int *ptr = NULL; // 声明一个空指针 if (ptr != NULL) { // 指针有效,可以进行解引用操作 printf("Value at ptr: %d\n", *ptr); } else { // 指针为空,不能进行解引用操作 printf("Pointer is NULL\n"); }
指针和引用有什么区别?
指针和引用都是 C++ 中用于间接访问变量的机制,但它们之间存在一些重要的区别: 指针是一个变量,存储的是内存地址;引用是一个别名,是变量的另一个名称。 指针可以被赋值为 NULL,表示空指针;引用在声明时必须初始化,并且不能指向其他变量。 指针可以进行算术运算,例如 ptr++;引用不能进行算术运算。 指针可以有多级,例如 `int ptr`;引用只能有一级。** *指针需要使用解引用操作符 `` 才能访问所指向的变量的值;引用可以直接访问所引用的变量的值。** 总结: 指针更灵活,可以指向不同的变量,也可以为空;引用更安全,必须初始化,并且不能指向其他变量。 在 C 语言中,只有指针;C++ 中既有指针,也有引用。
C 语言指针相关问题扩展
C 语言指针的高级应用有哪些?
掌握了 C 语言指针的基本概念之后,可以进一步学习指针的高级应用,例如: 函数指针: 函数指针是指向函数的指针,可以用于实现回调函数、策略模式等设计模式。 指针数组: 指针数组是一个数组,其中的每个元素都是一个指针,可以用于存储多个字符串或其他数据结构的指针。 多级指针: 多级指针是指指向指针的指针,例如 int **ptr,可以用于动态分配多维数组等高级应用。 结构体指针: 指向结构体的指针,可以通过该指针访问结构体的成员变量,在链表、树等结构中非常有用。 const 指针:C语言中可以使用const关键字定义常量指针,例如const int p,表示指针p指向的是int类型的常量,因此不能通过指针p来修改其指向的内容。此外还可以定义指针常量,例如int const p,指针p本身是常量,值不能修改,即指针不能指向其他地址。C语言也可以使用const int * const p,此时指针p和它所指向的内容都不能被修改。 深入学习这些高级应用,可以让你更充分地利用 C 语言指针的强大功能,编写更高效、更灵活的程序。 学习和理解 C 语言指针需要时间和实践。希望本文能够帮助你入门 C 语言指针,并为你进一步学习和掌握指针打下坚实的基础。指针是 C 语言的精髓,掌握指针,你就能更好地理解 C 语言的内存管理机制,编写更高效、更强大的程序。通过不断地学习和实践,你一定能够克服指针的恐惧,成为一名优秀的 C 语言程序员!
到这里,我们也就讲完了《C语言指针详解与实战教程》的内容了。个人认为,基础知识的学习和巩固,是为了更好的将其运用到项目中,欢迎关注golang学习网公众号,带你了解更多关于的知识点!
图像处理数据可视化教程详解
- 上一篇
- 图像处理数据可视化教程详解
- 下一篇
- PHP递归转换数据格式方法详解
-
- 科技周边 · 人工智能 | 4分钟前 |
- 百度输入法AI联想关闭教程
- 139浏览 收藏
-
- 科技周边 · 人工智能 | 26分钟前 |
- Claude3文件上传与图文分析教程
- 324浏览 收藏
-
- 科技周边 · 人工智能 | 36分钟前 |
- AI真相揭秘:事实、观点与智能边界
- 136浏览 收藏
-
- 科技周边 · 人工智能 | 48分钟前 | 人工智能工具
- DesignsAI如何生成界面原型详解
- 127浏览 收藏
-
- 科技周边 · 人工智能 | 55分钟前 |
- NanoBanana名称由来与技术解析
- 231浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- 雷小兔AI写作保存草稿方法详解
- 428浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- 不会JS?AI快速生成网页特效教程
- 265浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- N8NAI自动化工作流平台详解
- 339浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- ProggenArcana:DND地图生成神器推荐
- 436浏览 收藏
-
- 科技周边 · 人工智能 | 1小时前 |
- AI视频制作全流程:画面生成与配音技巧
- 103浏览 收藏
-
- 科技周边 · 人工智能 | 2小时前 | 编程语言 PHP Java
- 即梦图片库怎么找?访问教程分享
- 147浏览 收藏
-
- 科技周边 · 人工智能 | 2小时前 |
- Gemini语音输入设置教程
- 408浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 485次学习
-
- ChatExcel酷表
- ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
- 3504次使用
-
- Any绘本
- 探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
- 3733次使用
-
- 可赞AI
- 可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
- 3733次使用
-
- 星月写作
- 星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
- 4876次使用
-
- MagicLight
- MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
- 4102次使用
-
- GPT-4王者加冕!读图做题性能炸天,凭自己就能考上斯坦福
- 2023-04-25 501浏览
-
- 单块V100训练模型提速72倍!尤洋团队新成果获AAAI 2023杰出论文奖
- 2023-04-24 501浏览
-
- ChatGPT 真的会接管世界吗?
- 2023-04-13 501浏览
-
- VR的终极形态是「假眼」?Neuralink前联合创始人掏出新产品:科学之眼!
- 2023-04-30 501浏览
-
- 实现实时制造可视性优势有哪些?
- 2023-04-15 501浏览

