C語言中指標和陣列的愛恨情仇
文章目錄
- C語言中指標和陣列的愛恨情仇
- 一、前言
- 二、為什么學指標
- 三、說明
- 四、跟我一起學
- (一)C語言中的*和&
- 1、C語言中為什么存在&和*
- 2、&和*是什么?
- 3、&(取地址運算子)和*(間接尋址運算子)的使用
- (二)初識指標和變數
- 1、變數
- (1)變數如何創建
- (2)變數如何賦值
- (3)變數如何使用
- 2、指標
- (1)指標如何創建
- (2)指標如何賦值
- (3)指標如何使用
- (三)指標的一些基本用法
- 1、指標和變數的定義
- 2、指標和變數的初始化
- 3、指標如何作為引數
- 4、指標如何作為回傳值
- 5、案例1:完成swap函式,完成兩個引數交換的功能
- 6、案例2:找到最大和第二大的值
- (四)指標和陣列的淵源
- 1、提前說明
- 2、陣列和指標的簡單運用
- 3、指標中的算術運算
- (1)指標加上整數
- (2)指標減去整數
- (3)兩個指標相減
- 4、指標做比較
- 5、指標指向復合
- 6、指標直接指向陣列
- (五)指標實戰演算法題
- 五、結尾
一、前言
你可能會有小疑問,愛什么?恨什么?
先說恨吧,相信剛學C語言的同志都恨過,
記得大一時,C語言老師上課時用的VC++6.0,記得考試時用的VC++6.0,當時真的咬牙切齒,你說能不恨嗎,
沒有代碼提示,直接勸退了!
剛考完C語言的時候,真的想過這輩子再也不碰C了,
大二下學期,學了Java,授課老師用的Eclipse,雖然老師上課手擼代碼,但是我們寫作業,考試起碼有提示呀,頓時喜歡上了,
就這樣,大學期間搞了四年的Java,
那么愛什么呢?
愛的是,我大學畢業后缺搞起C語言,做了嵌入式Linux開發,因為我非常喜歡Linux,
C語言可以直接操作硬體的,那么你可能會問,一個編程語言怎么能和硬體想關聯呢?是不是很神奇,
我一開始也不知道,后來經過在公司的一段時間內接觸了HDMI、DVI、VGA等信號的驅動知識才了解到,C語言是可以直接操作暫存器的,但是也不能直接操作,而是通過一些特定的協議規則,例如:I2C協議,
搞嵌入式還是挺有好處的,沒有Java加班多是真的,下午下班回家、周六、周日、年假基本上不加班,也沒辦法加班,因為設備是在公司,你沒辦法拿到家里來對吧,只能回家學習了,想加班的話,還得看公司,至少我們公司965,還是挺爽的,選擇生活,還是選擇其他還是看自己,
即使不愛,也得愛呀,哈哈哈哈,
二、為什么學指標
- 1、因為不會,基本用法都不會;
- 2、因為很想會,必須得懂;
- 3、因為會用到,必須得學;
不會C語言的指標,你去刷個演算法題,去瞧瞧,
哈哈,記得我下定決心搞嵌入式Linux開發的時候,第一次想使用C語言去刷演算法題的時候,因為想提升一下自己的C語言的基礎,
就打開的一個最最最簡單的題:
在這里插入圖片描述

給的初始代碼如下:
/**
* Note: The returned array must be malloced, assume caller calls free().
*/
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
}
我滴個乖乖,這簡直了,直接頭大了,沒錯,直接勸退了,
再來看一下Java版的:
class Solution {
public int[] twoSum(int[] nums, int target) {
}
}
哎,好爽快呀,
你就說吧,你不會指標,你怎么去用C語言刷演算法題?????

三、說明
本篇文章不長篇大論的研究指標背后的原理,因為博主還沒到這地步,只是簡單的總結一下我段時間學到的技巧用法等,
四、跟我一起學
(一)C語言中的*和&
參考我其他博文中的一段話
1、C語言中為什么存在&和*
C語言中大名鼎鼎的“指標”,想必你肯定聽說過吧,
沒錯,C語言中的&和*就是為了指標而誕生的,
指標說白了就是直接/間接的操作(取/存)存盤中的地址中的資料,
試想一下,如果沒有&和*的存在,你可能每天都在為計算和尋找某個變數在哪里而發愁呢!
有了&和*之后,就不需要你手動的去計算記憶體中的地址,
2、&和*是什么?
&:取地址運算子;
*:間接尋址,也可以稱為取值運算子,這樣就好理解了運算子;
&的作用:如果想找到變數的地址,可以使用&(取地址)運算子,
*的作用:如果你學過鏈表,你經常會用到:
p->q;
那么p就是指向q的地址,
如果你學過計算機組成原理或者作業系統,里面的暫存器的尋址方式,就有間接尋址方式,
間接尋址方式:說白了就是取這個地址指向的地址的值,
如果有一個變數p,那么p就是取p指向地址的值,
3、&(取地址運算子)和*(間接尋址運算子)的使用
int i; 是變數
int *pi;是指標
int i, *pi;
char c,*pc;
例子:
#include <stdio.h>
int main()
{
int i, *pi;
char c,*pc;
//初始化i為10
i = 10;
//初始化c為‘a’字符
c = 'a';
//把pi指向i的地址
pi = &i;
//把pc指向c的地址
pc = &c;
printf("i=%d;c=%c\n",*pi,*pc);
//做一些基本處理
*pi = *pi + 100;
printf("*pi+100=%d\n",*pi);
printf("pi addr=%p;i addr=%p;pc addr=%p;c addr=%p\n",pi,&i,pc,&c);
return 0;
}
執行結果:
i=10;c=a
*pi+100=110
pi addr=0x7ffe76034684;i addr=0x7ffe76034684;pc addr=0x7ffe76034683;c addr=0x7ffe76034683
(二)初識指標和變數
1、變數
(1)變數如何創建
zhenghui@zhlinux:~/codeProject/20210719$ cat test1.c -n
1 #include <stdio.h>
2
3 int main()
4 {
5
6
7 //定義int型別的變數
8 int i1,i2,i3;
9 //定義double型別的變數
10 double d1,d2,d3;
11
12 return 0;
13 }
zhenghui@zhlinux:~/codeProject/20210719$
如上所示代碼中的【資料型別 空格 變數名 ;】輕輕松松就定義出來了1-N個變數,
(2)變數如何賦值
//初始化變數
i1 = 5;
i2 = 2;
i3 = 1;
公式:【變數名 = 值;】
意思是把什么內容保存到什么變數中,
你是不是有疑問了,區區一個小小滴變數這是如何保存的呢?別急,繼續看吧騷年,
(3)變數如何使用
zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$ cat test1.c
#include <stdio.h>
int main()
{
//定義int型別的變數
int i1,i2,i3;
//初始化變數
i1 = 5;
i2 = 2;
i3 = 1;
printf("i1=%d,i2=%d,i3=%d\n",i1,i2,i3);
return 0;
}
zhenghui@zhlinux:~/codeProject/20210719$ zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$ gcc test1.c
zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$ ./a.out
i1=5,i2=2,i3=1
zhenghui@zhlinux:~/codeProject/20210719$
2、指標
(1)指標如何創建
//定義int型別的指標
int *p1,*p2,*p3;
(2)指標如何賦值
//定義int型別的變數
int i1,i2,i3;
//初始化變數
i1 = 5;
.......
//定義int型別的指標
int *p1,*p2,*p3;
//賦值
p1 = &i1;
等等
請留步,這里說一下,
指標,其實就是存的地址,
不信可以使用printf大法看看:
zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$ cat test2.c
#include <stdio.h>
int main()
{
//定義int型別的變數
int i1,i2,i3;
//初始化變數
i1 = 5;
i2 = 2;
i3 = 1;
printf("i1=%d,i2=%d,i3=%d\n",i1,i2,i3);
//定義int型別的指標
int *p1,*p2,*p3;
//賦值
p1 = &i1;
//列印
printf("p1=%p,&i1=%p\n",p1,&i1);
return 0;
}
zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$ ./a.out
i1=5,i2=2,i3=1
p1=0x7ffde7e3f364,&i1=0x7ffde7e3f364
zhenghui@zhlinux:~/codeProject/20210719$
可以看到,我用p1=&i1,列印的結果是相同的,所以可以得到結論,
一個錯誤的示范:
int *p1;
p1 = 10;
我在沒具體學習指標的時候,就這樣做過,
編譯的時候:
所以:
- 指標變數只能接收某個記憶體中的地址;
- 只能把地址賦值給指標變數,
zhenghui@zhlinux:~/codeProject/20210719$
zhenghui@zhlinux:~/codeProject/20210719$ gcc test2.c
test2.c: In function ‘main’:
test2.c:23:5: warning: assignment to ‘int *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
23 | p2 = 123;
| ^
zhenghui@zhlinux:~/codeProject/20210719$
(3)指標如何使用
這里只需要學會*和&就行了,其余的暫時可以不用管,
(三)指標的一些基本用法
1、指標和變數的定義
//變數定義
int i,j,k;
//指標的定義
int *pi,*pj,*pk;
2、指標和變數的初始化
//變數定義
int i,j,k;
//指標的定義
int *pi,*pj,*pk;
//變數的初始化
i = 10;
j = 100;
k = 1000;
//指標的初始化
pi = &i;
pj = &j;
pk = &k;
如果你還不知道&和*的用法和作用,可以參考我這篇:
《C語言中的&和*》
3、指標如何作為引數
#include <stdio.h>
void maxV(int a,int b,int *max)
{
if( a > b)
{
*max = a;
}else
{
*max = b;
}
}
int main()
{
//變數定義
int i,j,k;
//指標的定義
int *pi,*pj,*pk;
//變數的初始化
i = 10;
j = 100;
k = 1000;
//指標的初始化
pi = &i;
pj = &j;
pk = &k;
int max;
maxV(i,j,&max);
printf("最大的數是:%d\n",max);
return 0;
}
結果:
最大的數是:100
4、指標如何作為回傳值
#include <stdio.h>
void maxV(int a,int b,int *max)
{
if( a > b)
{
*max = a;
}else
{
*max = b;
}
}
int *maxV2(int *a,int *b)
{
return *a > *b ? a : b;
}
int main()
{
//變數定義
int i,j,k;
//指標的定義
int *pi,*pj,*pk;
//變數的初始化
i = 10;
j = 100;
k = 1000;
//指標的初始化
pi = &i;
pj = &j;
pk = &k;
int max;
maxV(i,j,&max);
printf("最大的數是:%d\n",max);
printf("最大的數是:%d\n",*maxV2(&j,&k));
return 0;
}
結果:
最大的數是:100
最大的數是:1000
5、案例1:完成swap函式,完成兩個引數交換的功能
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$ cat swap.c
#include <stdio.h>
void swap(int *p,int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
int main()
{
int a=10;
int b=20;
swap(&a,&b);
printf("a=%d,b=%d\n",a,b);
return 0;
}
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$ ./a.out
a=20,b=10
zhenghui@zhlinux:~/codeProject/11指標$
6、案例2:找到最大和第二大的值
題目如下:

方法一:兩次回圈
第一次:找出最大的值,然后記錄下來最大值的位置;
第二次查找的時候把最大值的位置的資料給清空,繼續尋找最大的值,那么這一次的最大的值就是第二大的,
#include <stdio.h>
#define ARRAY_SIZE(array) ((int) (sizeof(array) / sizeof(array[0]) ))
/*
*查找最大的值和第二大的值
* */
void find_tow_largest(int a[],int n,int *largest,int *second_largest)
{
//1、找到最大的值
*largest = a[0];
//記錄下來最大的值的位置
int maxIndex = 0;
for(int i = 1;i<n;i++)
{
if(*largest < a[i])
{
*largest = a[i];
maxIndex = i;
}
}
//2、找第二大的值
//把最大的值變成最小的值
a[maxIndex] = -1;
*second_largest = a[0];
for(int i = 1;i<n;i++)
{
if(*second_largest < a[i])
{
*second_largest = a[i];
}
"find_tow_larget.c" 54L, 863C 31,2-9 頂端
*largest = a[i];
maxIndex = i;
}
}
//2、找第二大的值
//把最大的值變成最小的值
a[maxIndex] = -1;
*second_largest = a[0];
for(int i = 1;i<n;i++)
{
if(*second_largest < a[i])
{
*second_largest = a[i];
}
}
}
int main()
{
int a[] = {1,5,2,4,7,5,8,234};
int n = ARRAY_SIZE(a);
int largest,second_largest;
find_tow_largest(a,n,&largest,&second_largest);
printf("最大的是:%d,第二大的是:%d\n",largest,second_largest);
return 0;
}
執行結果:
zhenghui@zhlinux:~/codeProject/11指標$ vim find_tow_larget.c
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$ gcc find_tow_larget.c
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$ ./a.out
最大的是:234,第二大的是:8
zhenghui@zhlinux:~/codeProject/11指標$
方法2:排序
可以利用陣列的排序來做,任何排序都可以,
這里選用插入排序來做,
zhenghui@zhlinux:~/codeProject/11指標$
zhenghui@zhlinux:~/codeProject/11指標$ cat find_tow_larget.c
#include <stdio.h>
#define ARRAY_SIZE(array) ((int) (sizeof(array) / sizeof(array[0]) ))
/*
*查找最大的值和第二大的值
* */
void find_tow_largest(int a[],int n,int *largest,int *second_largest)
{
//1、找到最大的值
*largest = a[0];
//記錄下來最大的值的位置
int maxIndex = 0;
for(int i = 1;i<n;i++)
{
if(*largest < a[i])
{
*largest = a[i];
maxIndex = i;
}
}
//2、找第二大的值
//把最大的值變成最小的值
a[maxIndex] = -1;
*second_largest = a[0];
for(int i = 1;i<n;i++)
{
if(*second_largest < a[i])
{
*second_largest = a[i];
}
}
}
/*
*使用排序查找最大的值和第二大的值
* */
void find_sort_tow_largest(int a[],int n,int *largest,int *second_largest)
{
//1、初始化
for(int i = 1;i<n;i++)
{
if(a[i-1] > a[i])
{
int j = i - 1;
int temp = a[i];
while(j > -1 && temp < a[j])
{
a[j+1] = a[j];
j--;
}
a[j+1] = temp;
}
}
*largest = a[n-1];
*second_largest = a[n-2];
}
int main()
{
int a[] = {1,5,2,4,7,5,8,234};
int n = ARRAY_SIZE(a);
int largest,second_largest;
//find_tow_largest(a,n,&largest,&second_largest);
find_sort_tow_largest(a,n,&largest,&second_largest);
printf("最大的是:%d,第二大的是:%d\n",largest,second_largest);
return 0;
}
結果:
zhenghui@zhlinux:~/codeProject/11指標$ ./a.out
最大的是:234,第二大的是:8
zhenghui@zhlinux:~/codeProject/11指標$
(四)指標和陣列的淵源
1、提前說明
為了更好的說明指標和陣列的情況,本文假設你最起碼已經會簡單的使用陣列了,
下文中所使用的陣列都是:int a[] = {10,20,30,40,50,60,70,80,90,100},
如下圖所示:

我們宣告陣列a和指標p如下:
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p;
2、陣列和指標的簡單運用
int a;只是存放的一個數,陣列中而是存放的一組數;
那么我們可以把某個變數的地址賦值給某個指標變數,那么陣列可不可以呢?
當然是可以的:
zhenghui@zhlinux:~/codeProject/20210720$ ./a.out
a[0]=1,p=10
zhenghui@zhlinux:~/codeProject/20210720$
zhenghui@zhlinux:~/codeProject/20210720$
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p;
p = &a[0];
printf("a[0]=%d,p=%d \n",a[0],*p);
}
zhenghui@zhlinux:~/codeProject/20210720$
當我們把a[0]的地址賦值給p的時候,那么就相當于p指向了陣列中a[0]處這個數值的地址,如下圖所示:

3、指標中的算術運算
算術運算是什么?
就是從小就會的,加法、減法、乘法、除法,
C語言中的指標支持三種格式(只有三種,只能三種)的指標算術運算,
分別是:
指標加上整數;指標減去整數;兩個指標相減;
下面來分別介紹一下陣列中的指標怎么加減,
(1)指標加上整數
實驗代碼修改如下:
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p;
p = &a[0];
printf("a[0]=%d, *(p + 1)=%d \n",a[0], *(p+1) );
}
zhenghui@zhlinux:~/codeProject/20210720$
你猜猜(*p+1)會列印什么,
- 老王說:我猜是11;
- 老李說:我猜會報錯,指標怎么能做加法呢!;
看看是誰說的對:
zhenghui@zhlinux:~/codeProject/20210720$ gcc test1.c
zhenghui@zhlinux:~/codeProject/20210720$
zhenghui@zhlinux:~/codeProject/20210720$ ./a.out
a[0]=10, *(p + 1)=20
zhenghui@zhlinux:~/codeProject/20210720$
居然是20,
為什么是20呢,是不是很納悶,
現在可以嘗試猜想一下,
這個*(p+1) = 20的話,那么這個+1的操作很明擺著就是向前移動了一個位置呀,變成了a[1],
驗證一下:
zhenghui@zhlinux:~/codeProject/20210720$
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p;
p = &a[0];
printf("a[0]=%d, *(p + 1)=%d \n",a[0], *(p+1) );
printf("a[1] addr=%p, *(p+1) addr=%p \n",&a[1], (p+1) );
}
zhenghui@zhlinux:~/codeProject/20210720$
通過列印a[1]和p+1的地址,還真的是一樣的地址,那么就證明了我們的猜想,如果指標指向陣列的話,那么加N就等于是向前移動了幾個位置,
zhenghui@zhlinux:~/codeProject/20210720$ ./a.out
a[0]=10, *(p + 1)=20
a[1] addr=0x7fff953b17b4, *(p+1) addr=0x7fff953b17b4
zhenghui@zhlinux:~/codeProject/20210720$
(2)指標減去整數
有了前面加整數的鋪墊,不難想象,減去一個整數,肯定就是向后移動了幾個位置,
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p;
p = &a[0];
//+5
p = p + 5;
printf("(p + 5)之后=%d \n",*p);
//-2
p = p - 2;
printf("(p + 5 - 2)之后=%d \n",*p);
}
運行結果如下:
zhenghui@zhlinux:~/codeProject/20210720$ ./a.out
(p + 5)之后=60
(p + 5 - 2)之后=40
zhenghui@zhlinux:~/codeProject/20210720$
(3)兩個指標相減
修改測驗代碼如下:
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p, *q;
p = &a[2];
q = &a[8];
printf("p=%d,q=%d,(p - q)之后=%ld \n", *p, *q,(p - q) );
printf("p=%d,q=%d,(q - p)之后=%ld \n", *p, *q,(q - p) );
}
zhenghui@zhlinux:~/codeProject/20210720$
運行結果:
zhenghui@zhlinux:~/codeProject/20210720$ ./a.out
p=30,q=90,(p - q)之后=-6
p=30,q=90,(q - p)之后=6
zhenghui@zhlinux:~/codeProject/20210720$
4、指標做比較
指標和指標之間也可以使用:<、>、<=、>=、==、!=來做比較,但是只有在相同的陣列中做比較才有意義,因為陣列中的指標做比較的話,會依賴于同一陣列中的元素的相對位置,
代碼修改如下:
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p, *q;
p = &a[2];
q = &a[8];
printf("(p > q)之后=%d \n",(p > q) );
printf("(q < p)之后=%d \n",(q > p) );
}
zhenghui@zhlinux:~/codeProject/20210720$
結果:
zhenghui@zhlinux:~/codeProject/20210720$ gcc test1.c && ./a.out
(p > q)之后=0
(q < p)之后=1
5、指標指向復合
這個是c99中的一個特性,
我們之前是先創建一個陣列,然后用指標再指向陣列的第一個元素,以此達到目的,
這樣做是很不方便的,那么接下來的操作,就是可以為了簡化這個操作,減少一些麻煩,
int *p1 = (int []){1,2,3,4,5,6};
我們使用的時候,也是一樣用就可以了:
printf("p1 + 1 =%d \n",*(p1+1));
6、指標直接指向陣列
廢話不多說,直接上代碼:
zhenghui@zhlinux:~/codeProject/20210720$ cat test1.c
#include <stdio.h>
int main()
{
int a[10] = {10,20,30,40,50,60,70,80,90,100}, *p, *q;
p = a;
printf("p+1=%d \n",*(p+1));
}
zhenghui@zhlinux:~/codeProject/20210720$
zhenghui@zhlinux:~/codeProject/20210720$ gcc test1.c && ./a.out
p+1=20
zhenghui@zhlinux:~/codeProject/20210720$
(五)指標實戰演算法題
學習完了C語言的指標,再一次信心滿滿的打開了
https://leetcode-cn.com/problems/two-sum/submissions/
這道演算法題,
現在Ubuntu的vim寫了一下:
#include <stdio.h>
int* twoSum(int* nums, int numsSize, int target, int* returnSize){
int *res = (int[2]){};
for(int i = 0;i<numsSize;i++)
{
for(int j = 1;j<numsSize;j++)
{
if(i != j && (nums[i] + nums[j] == target))
{
*(res) = i;
*(res+1) = j;
*returnSize = 2;
return res;
}
}
}
return res;
}
int main()
{
int *nums = (int[]){2,7,11,15};
int numsSize = 4;
int target = 9;
int returnSize;
int *result = twoSum(nums,numsSize,target,&returnSize);
printf("returnSize=%d,result1=%d,result2=%d \n",returnSize,*result,*(result+1));
}
運行:
zhenghui@zhlinux:~/codeProject/20210720$ gcc test2.c && ./a.out
returnSize=2,result1=0,result2=1
zhenghui@zhlinux:~/codeProject/20210720$
好滴很,沒有毛病,
放到力扣試試:

一遍過,哈哈哈,挺開心的,
開心的是這是我用指標寫過最長的C語言代碼了,
開心的是第一次用指標寫了一個程式,
剛好對比一下,以前我用Java寫的:

不得不說C語言的優勢就一下子體現出來了,
時間上的問題不是大問題,只是本次使用了兩層for回圈來處理的,時間會久一些,
五、結尾
現在高興還太早,只是初出茅廬,會了皮毛,簡單的使用,
C語言高級的地方在于記憶體的管理,如何動態的分配記憶體,管理記憶體,如何動態的分配字串,分配陣列,釋放存盤空間等等,還有一大把的基礎知識帶研究,
下次繼續研究,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/289649.html
標籤:其他
