欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

詳解C語(yǔ)言中的自定義類型

 更新時(shí)間:2023年07月20日 14:33:15   作者:C.C  
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言中的四大自定義類型(結(jié)構(gòu)體、位段、枚舉和聯(lián)合)的相關(guān)知識(shí),文中的示例代碼簡(jiǎn)潔易懂,需要的可以參考一下

一. 結(jié)構(gòu)體

1.1 什么是結(jié)構(gòu)體

結(jié)構(gòu)體: 結(jié)構(gòu)體是一些值的集合,這些值被稱為成員變量,結(jié)構(gòu)體中的成員變量可以是不同類型的變量

1.2 結(jié)構(gòu)體的聲明

struct tag //結(jié)構(gòu)體名
{
 member-list; //成員列表
}variable-list; //結(jié)構(gòu)體變量列表

例如,描述一個(gè)學(xué)生

struct Stu
{
 char name[20];//名字
 int age;//年齡
 char sex[5];//性別
 char id[20];//學(xué)號(hào)
}; //分號(hào)不能丟

1.3 特殊的聲明

在聲明結(jié)構(gòu)體時(shí),可以不完全的聲明,即結(jié)構(gòu)體名可以省略,這種結(jié)構(gòu)體一般被稱為匿名結(jié)構(gòu)體,只能使用一次

//匿名結(jié)構(gòu)體類型
struct
{
 int a;
 char b;
 float c;
}x;
struct
{
 int a;
 char b;
 float c;
}a[20], *p;

上面兩個(gè)結(jié)構(gòu)體在聲明時(shí)都省略了結(jié)構(gòu)體標(biāo)簽(結(jié)構(gòu)體名),那么問(wèn)題來(lái)了,p=&x,這句話對(duì)嘛?

即使兩個(gè)結(jié)構(gòu)體沒(méi)有名字,并且里面的成員變量完全相同,但編譯器也會(huì)認(rèn)為這是兩個(gè)不同的結(jié)構(gòu)體,所以這種寫(xiě)法是錯(cuò)誤的

1.4 結(jié)構(gòu)體的自引用

結(jié)構(gòu)體的自引用: 結(jié)構(gòu)體的自引用就是結(jié)構(gòu)體里面又包含了本身

//代碼1
struct Node
{
 int data;
 struct Node next;
};
//可行否?
//如果可以,那sizeof(struct Node)是多少?

上述這種方式是錯(cuò)誤的,因?yàn)槲覀冊(cè)谟?jì)算sizeof(struct Node)結(jié)構(gòu)體里面又包含了自己,所以就會(huì)無(wú)限套娃,算不出來(lái)一個(gè)答案,正確的定義如下:

//代碼2
struct Node
{
 int data;
 struct Node* next;
};

要將里面包含的結(jié)構(gòu)體定義為結(jié)構(gòu)體指針的形式,這樣我們通過(guò)next的地址,就能很好的找到另一個(gè)結(jié)構(gòu)體在內(nèi)存中的位置

注意:

//代碼3
typedef struct
{
 int data;
 Node* next;
}Node;
//這樣寫(xiě)代碼,可行否?

這樣寫(xiě)代碼是錯(cuò)誤的,因?yàn)樵谑褂胻ypedef時(shí)我們要對(duì)struct這個(gè)匿名結(jié)構(gòu)體類型重命名,但在命名過(guò)程中遇到了Node*,編譯器就會(huì)報(bào)錯(cuò)說(shuō)之前沒(méi)有見(jiàn)過(guò)Node這種類型,所以我們?cè)谟胻ypedef時(shí)不要使用匿名結(jié)構(gòu)體去重命名,這就類似于先有雞還是先有蛋的問(wèn)題,正確代碼如下

//解決方案:
typedef struct Node
{
 int data;
 struct Node* next;
}Node;

一定要用完整的結(jié)構(gòu)體聲明方式去聲明,才能用typedef重命名

1.5 結(jié)構(gòu)體變量的定義和初始化

有了結(jié)構(gòu)體,那么我們?nèi)绾味x一個(gè)結(jié)構(gòu)體變量并且為它初始化呢?

1.5.1 結(jié)構(gòu)體變量的定義

struct Point
{
 int x;
 int y;
}p1; //聲明類型的同時(shí)定義變量p1
struct Point p2; //定義結(jié)構(gòu)體變量p2

如上:有兩種方式定義結(jié)構(gòu)體變量

  • 在聲明類型的同時(shí)定義結(jié)構(gòu)體變量,如上p1,p1屬于全局變量
  • 利用結(jié)構(gòu)體類型定義結(jié)構(gòu)體變量,如上p2,p2屬于局部變量

1.5.2 結(jié)構(gòu)體變量的初始化

//初始化:定義變量的同時(shí)賦初值。
struct Stu        //類型聲明
{
 char name[15];//名字
 int age;      //年齡
};
struct Stu s = {"zhangsan", 20};//初始化
struct Node
{
 int data;
 struct Point p;
 struct Node* next; 
}n1 = {10, {4,5}, NULL}; //結(jié)構(gòu)體嵌套初始化
struct Node n2 = {20, {5, 6}, NULL};//結(jié)構(gòu)體嵌套初始化

結(jié)構(gòu)體變量的初始化也是兩種方式

  • 在定義結(jié)構(gòu)體變量時(shí)初始化,如上圖 s
  • 結(jié)構(gòu)體嵌套初始化,如上圖n1,n2

1.6 結(jié)構(gòu)體內(nèi)存對(duì)齊

上面我們知道了結(jié)構(gòu)體如何定義,聲明,初始化,那么結(jié)構(gòu)體成員變量在內(nèi)存中是如何存儲(chǔ)的?我們?nèi)绾稳ビ?jì)算一個(gè)結(jié)構(gòu)體在內(nèi)存中占用的字節(jié)數(shù)?

其實(shí)在計(jì)算結(jié)構(gòu)體內(nèi)存時(shí)有一定的對(duì)齊規(guī)則如下:

  • 1) 第一個(gè)成員在與結(jié)構(gòu)體變量偏移量為0的地址處
  • (2)其他成員變量要對(duì)齊到某個(gè)數(shù)字(對(duì)齊數(shù))的整數(shù)倍的地址處

如何計(jì)算對(duì)齊數(shù)

對(duì)齊數(shù) = 編譯器默認(rèn)的一個(gè)對(duì)齊數(shù) 與 該成員數(shù)據(jù)類型大小的較小值.VS中默認(rèn)的值為8,Linux中沒(méi)有默認(rèn)對(duì)齊數(shù),對(duì)齊數(shù)就是成員自身的大小

(3)結(jié)構(gòu)體總大小為最大對(duì)齊數(shù)(每個(gè)成員變量都有一個(gè)對(duì)齊數(shù))的整數(shù)倍

(4)如果嵌套了結(jié)構(gòu)體的情況,嵌套的結(jié)構(gòu)體對(duì)齊到自己的最大對(duì)齊數(shù)的整數(shù)倍處,結(jié)構(gòu)體的整體大小就是所有最大對(duì)齊數(shù)(含嵌套結(jié)構(gòu)體的對(duì)齊數(shù))的整數(shù)倍。

struct S2
{
 char c1;
 char c2;
 int i;
};
printf("%d\n", sizeof(struct S2));

默認(rèn)對(duì)齊數(shù)是8,c1是第一個(gè)直接放在偏移量為0的位置,從第二個(gè)c2開(kāi)始,要計(jì)算他們的對(duì)齊數(shù),對(duì)齊數(shù)=該成員大小和默認(rèn)對(duì)齊數(shù)的最小值,即1和8的最小值,顯然是1,所以c2應(yīng)放在1的整數(shù)倍上即下標(biāo)為1的地址上,變量i同理,變量i的實(shí)際大小為4與默認(rèn)對(duì)齊數(shù)的最小值還是4,所以要放在下標(biāo)為4的整數(shù)倍的位置,即下標(biāo)為4的位置,如下圖

所以整個(gè)結(jié)構(gòu)體的大小為8個(gè)字節(jié)

還有一種情況是結(jié)構(gòu)體里嵌套一個(gè)結(jié)構(gòu)體

struct S3
{
 char c1;
 struct S2 s2;
 char d;
};
printf("%d\n", sizeof(struct S3));

c1的大小是1個(gè)字節(jié),和默認(rèn)對(duì)齊數(shù)(8)的最小值還是1,上面我們計(jì)算過(guò)S2里面三個(gè)成員變量的對(duì)齊數(shù),其中最大的是i,即4,和默認(rèn)對(duì)齊數(shù)的最小值是4,char的大小是1,和默認(rèn)對(duì)齊數(shù)的最小值是1,所以S3的結(jié)構(gòu)體內(nèi)存圖如下

所以S3的結(jié)構(gòu)體大小是13個(gè)字節(jié)

1.6.1 為什么存在內(nèi)存對(duì)齊

1.平臺(tái)原因(移植原因):

不是所有的硬件平臺(tái)都能訪問(wèn)任意地址上的任意數(shù)據(jù)的;某些硬件平臺(tái)只能在某些地址處取某些特定類型的數(shù)據(jù),否則拋出硬件異常。

2.性能原因

數(shù)據(jù)結(jié)構(gòu)(尤其是棧)應(yīng)該盡可能地在自然邊界上對(duì)齊。

原因在于,為了訪問(wèn)未對(duì)齊的內(nèi)存,處理器需要作兩次內(nèi)存訪問(wèn),而對(duì)齊的內(nèi)存訪問(wèn)僅需要一次訪問(wèn)。

==總體來(lái)說(shuō):==結(jié)構(gòu)體空間對(duì)齊就是用空間換取時(shí)間的做法

1.7 修改默認(rèn)對(duì)齊數(shù)

我們知道結(jié)構(gòu)體內(nèi)存的大小和默認(rèn)對(duì)齊數(shù)有關(guān),也和我們定義結(jié)構(gòu)體成員變量的順序有關(guān),我們應(yīng)將類型相同的變量定義在一起.這樣可以使結(jié)構(gòu)體所占內(nèi)存盡可能小,同時(shí)也可以通過(guò)修改默認(rèn)對(duì)齊數(shù)的方式

之前我們見(jiàn)過(guò)了 #pragma 這個(gè)預(yù)處理指令,這里我們?cè)俅问褂?,可以改變我們的默認(rèn)對(duì)齊數(shù)

#pragma pack(1)//設(shè)置默認(rèn)對(duì)齊數(shù)為1
struct S2
{
 char c1;
 int i;
 char c2;
};
#pragma pack()//取消設(shè)置的默認(rèn)對(duì)齊數(shù),還原為默認(rèn)

如果覺(jué)得默認(rèn)對(duì)齊數(shù)不合適時(shí)可以適當(dāng)修改,但一般不輕易修改默認(rèn)對(duì)齊數(shù)

1.8 結(jié)構(gòu)體傳參

結(jié)構(gòu)體傳參有兩種方式

將一個(gè)結(jié)構(gòu)體變量傳過(guò)去

//結(jié)構(gòu)體傳參
void print1(struct S s)
{
 printf("%d\n", s.num);
}
int main()
{
 print1(s);  //傳結(jié)構(gòu)體
 return 0;
 }

傳一個(gè)結(jié)構(gòu)體指針

void print2(struct S* ps)
{
 printf("%d\n", ps->num);
}
int main()
{
 print2(&s); //傳地址
 return 0;

我們一般用第二種傳地址的方式,因?yàn)閰?shù)在傳遞的過(guò)程中形參是實(shí)參的一份臨時(shí)拷貝,形參也是要壓棧的,直接傳一個(gè)結(jié)構(gòu)體變量所占的字節(jié)一般要比一個(gè)指針大的多,所以一般選擇傳地址

二. 位段

2.1 什么是位段

位段一般是通過(guò)結(jié)構(gòu)體來(lái)實(shí)現(xiàn)的,位段的聲明和結(jié)構(gòu)體是類似的,有兩個(gè)不同

1.位段的成員必須是 char,int,unsigned int 或signed int

2.位段的成員名后邊有一個(gè)冒號(hào)和一個(gè)數(shù)字

struct A
{
 int _a:2;
 int _b:5;
 int _c:10;
 int _d:30;
};

A就是一個(gè)位段類型,那么A占多少個(gè)字節(jié)呢

2.2 位段的內(nèi)存分配

位段的成員可以是 int unsigned int signed int 或者是char(屬于整形家族)類型

位段的空間上是按照需要以4個(gè)字節(jié)(int)或者1個(gè)字節(jié)(char)的方式來(lái)開(kāi)辟的。

位段涉及很多不確定因素,位段是不跨平臺(tái)的,注重可移植的程序應(yīng)該避免使用位段。

//一個(gè)例子
struct S
{
 char a:3;
 char b:4;
 char c:5;
 char d:4;
};
struct S s = {0};
s.a = 10;
s.b = 12;
s.c = 3;
s.d = 4;
//空間是如何開(kāi)辟的

在VS的編譯器上,會(huì)先配該數(shù)據(jù)類型對(duì)應(yīng)的字節(jié)數(shù),比如char a,先給a分配一個(gè)字節(jié)的大小,但a只占一個(gè)字節(jié)中的3個(gè)比特位,所以剩下5個(gè)比特位,b占4個(gè)比特位,剩下1個(gè)比特位不夠c,因?yàn)閏是char類型所以會(huì)在申請(qǐng)一個(gè)字節(jié)的大小,剛才剩下的一個(gè)比特位就被浪費(fèi)掉了,新的一個(gè)字節(jié)c占五個(gè)字節(jié),剩下三個(gè)字節(jié)不夠d,就會(huì)在申請(qǐng)1個(gè)字節(jié)給d用

綜上S的空間為3個(gè)字節(jié)

所以問(wèn)題來(lái)了給s中的成員賦值時(shí),會(huì)得到什么呢?

對(duì)于a來(lái)說(shuō)10的二進(jìn)制是00001010(char類型一個(gè)字節(jié)),但a中只能存儲(chǔ)3位,所以會(huì)發(fā)生截?cái)嗟玫?10,也就是10進(jìn)制的2

其他的依次類推

2.3 位段的跨平臺(tái)問(wèn)題

  • int 位段被當(dāng)成有符號(hào)數(shù)還是無(wú)符號(hào)數(shù)是不確定的。
  • 位段中最大位的數(shù)目不能確定。(16位機(jī)器最大16,32位機(jī)器最大32,寫(xiě)成27,在16位機(jī)器會(huì)出問(wèn)題。
  • 位段中的成員在內(nèi)存中從左向右分配,還是從右向左分配標(biāo)準(zhǔn)尚未定義。
  • 當(dāng)一個(gè)結(jié)構(gòu)包含兩個(gè)位段,第二個(gè)位段成員比較大,無(wú)法容納于第一個(gè)位段剩余的位時(shí),是舍棄剩余的位還是利用,這是不確定的。

總結(jié): 跟結(jié)構(gòu)相比,位段可以達(dá)到同樣的效果,并且可以很好的節(jié)省空間,但是有跨平臺(tái)的問(wèn)題存在

2.4 位段的應(yīng)用

因?yàn)槲欢伪冉Y(jié)構(gòu)體更能用來(lái)節(jié)省空間,所以一般用在網(wǎng)絡(luò)傳輸?shù)臄?shù)據(jù)報(bào)中,數(shù)據(jù)包中各部分都是用位段來(lái)規(guī)定大小的,因?yàn)閿?shù)據(jù)報(bào)越小,在網(wǎng)絡(luò)上傳輸速度就越快

三. 枚舉

枚舉顧名思義就是一 一列舉

3.1 枚舉類型的定義

enum Day//星期
{
 Mon,
 Tues,
 Wed,
 Thur,
 Fri,
 Sat,
 Sun
};
enum Sex//性別
{
 MALE,
 FEMALE,
 SECRET
};
enum Color//顏色
{
 RED,
 GREEN,
 BLUE
};

以上定義的enum Day,enum Sex,enum Color都是枚舉類型,{}中的內(nèi)容是枚舉類型的可能取值,也叫做枚舉常量

這些可能取值都是有值的,默認(rèn)從0開(kāi)始,依次遞增1,當(dāng)然在聲明枚舉類型的時(shí)候也可以賦初值。

enum Color//顏色
{
 RED=1,
 GREEN=2,
 BLUE=4
};

如果不給初值,默認(rèn)從0開(kāi)始遞增,如果某一個(gè)有初始值,這個(gè)值以下的往下遞增,以上的還是從0開(kāi)始遞增

3.2 枚舉的優(yōu)點(diǎn)

我們可以使用 #define 定義常量,為什么非要使用枚舉?

枚舉的優(yōu)點(diǎn):

  • 增加代碼的可讀性和可維護(hù)性
  • 和#define定義的標(biāo)識(shí)符比較枚舉有類型檢查,更加嚴(yán)謹(jǐn)。
  • 便于調(diào)試
  • 使用方便,一次可以定義多個(gè)常量

3.3 枚舉的使用

enum Color//顏色
{
 RED=1,
 GREEN=2,
 BLUE=4
};
enum Color clr = GREEN;//只能拿枚舉常量給枚舉變量賦值,才不會(huì)出現(xiàn)類型的差異。
clr = 5;//這種C語(yǔ)言可以,但C++中不允許

四. 聯(lián)合(共用體)

4.1 聯(lián)合類型的定義

聯(lián)合也是一種特殊的自定義類型

這種類型定義的變量也包含一系列的成員,特征是這些成員公用同一塊空間(所以聯(lián)合也叫共用體)

//聯(lián)合類型的聲明
union Un
{
 char c;
 int i;
};
//聯(lián)合變量的定義
union Un un;
//計(jì)算連個(gè)變量的大小
printf("%d\n", sizeof(un));//計(jì)算出來(lái)是 4

4.2 聯(lián)合的特點(diǎn)

合的成員是共用同一塊內(nèi)存空間的,這樣一個(gè)聯(lián)合變量的大小,至少是最大成員的大?。ㄒ?yàn)槁?lián)合至少得有能力保存最大的那個(gè)成員)

union Un
{
 int i;
 char c;
};
union Un un;
// 下面輸出的結(jié)果是一樣的嗎?
printf("%d\n", &(un.i));
printf("%d\n", &(un.c));
//上述兩個(gè)輸出的是一樣的
//下面輸出的結(jié)果是什么?
un.i = 0x11223344;
un.c = 0x55;
printf("%x\n", un.i);//0x55223344

聯(lián)合在內(nèi)存中相當(dāng)于是

即char c共用int i的4個(gè)字節(jié)的地址

4.3 聯(lián)合大小的計(jì)算

  • 聯(lián)合的大小至少是最大成員的大小。
  • 當(dāng)最大成員大小不是最大對(duì)齊數(shù)的整數(shù)倍的時(shí)候,就要對(duì)齊到最大對(duì)齊數(shù)的整數(shù)倍
union Un1
{
 char c[5];
 int i;
};
union Un2
{
 short c[7];
 int i;
};
//下面輸出的結(jié)果是什么?
printf("%d\n", sizeof(union Un1));// 8
printf("%d\n", sizeof(union Un2));// 16

對(duì)于Un1,char c[5]的最大對(duì)齊數(shù)是1,int最大對(duì)齊數(shù)是4,所以該聯(lián)合體最大對(duì)齊數(shù)是4,又因?yàn)閏占5個(gè)字節(jié),i占4個(gè)字節(jié),所以至少要是5個(gè)字節(jié),但還要是最大對(duì)齊數(shù)的整數(shù)倍所以只能是8

對(duì)于Un2,short c[7]的最大對(duì)齊數(shù)是2,int是4,所以該聯(lián)合體的最大對(duì)齊數(shù)是4,又因?yàn)閏占14個(gè)字節(jié),i占4個(gè)字節(jié),所以至少要是14個(gè)字節(jié),但還要滿足是最大對(duì)齊數(shù)的整數(shù)倍,所以是16

以上就是詳解C語(yǔ)言中的自定義類型的詳細(xì)內(nèi)容,更多關(guān)于C語(yǔ)言自定義類型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • C/C++ 進(jìn)程通訊(命名管道)的實(shí)例

    C/C++ 進(jìn)程通訊(命名管道)的實(shí)例

    下面小編就為大家?guī)?lái)一篇C/C++ 進(jìn)程通訊(命名管道)的實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-08-08
  • C++控制臺(tái)實(shí)現(xiàn)簡(jiǎn)單人機(jī)對(duì)弈井字棋

    C++控制臺(tái)實(shí)現(xiàn)簡(jiǎn)單人機(jī)對(duì)弈井字棋

    這篇文章主要為大家詳細(xì)介紹了C++控制臺(tái)實(shí)現(xiàn)簡(jiǎn)單人機(jī)對(duì)弈井字棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • C語(yǔ)言 結(jié)構(gòu)體(Struct)詳解及示例代碼

    C語(yǔ)言 結(jié)構(gòu)體(Struct)詳解及示例代碼

    本文主要介紹C語(yǔ)言 結(jié)構(gòu)體的知識(shí),學(xué)習(xí)C語(yǔ)言肯定需要學(xué)習(xí)結(jié)構(gòu)體,這里詳細(xì)說(shuō)明了結(jié)構(gòu)體并附示例代碼,供大家參考學(xué)習(xí),有需要的小伙伴可以參考下
    2016-08-08
  • FFmpeg中avfilter模塊的介紹與使用

    FFmpeg中avfilter模塊的介紹與使用

    FFmpeg中的libavfilter模塊(或庫(kù))用于filter(過(guò)濾器),?filter可以有多個(gè)輸入和多個(gè)輸出,下面就跟隨小編一起簡(jiǎn)單學(xué)習(xí)一下它的巨日使用吧
    2023-08-08
  • Qt 智能指針的具體使用

    Qt 智能指針的具體使用

    本文主要介紹了Qt 智能指針的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2025-03-03
  • 重構(gòu)-C++實(shí)現(xiàn)矩陣的簡(jiǎn)單實(shí)例

    重構(gòu)-C++實(shí)現(xiàn)矩陣的簡(jiǎn)單實(shí)例

    下面小編就為大家?guī)?lái)一篇重構(gòu)-C++實(shí)現(xiàn)矩陣的簡(jiǎn)單實(shí)例。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-06-06
  • C/C++后端學(xué)習(xí)與練習(xí)深入

    C/C++后端學(xué)習(xí)與練習(xí)深入

    這篇文章主要介紹了C/C++對(duì)于后端的學(xué)習(xí)與練習(xí),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-07-07
  • 利用C++模擬實(shí)現(xiàn)STL容器:list

    利用C++模擬實(shí)現(xiàn)STL容器:list

    列表是一種順序容器,它允許在序列中的任何位置執(zhí)行常量時(shí)間插入和刪除操作,并允許在兩個(gè)方向上進(jìn)行迭代。本文將利用C++模擬實(shí)現(xiàn)list,希望對(duì)大家有所幫助
    2022-12-12
  • C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)

    C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)通訊錄管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • C++中的模板類&模板函數(shù)

    C++中的模板類&模板函數(shù)

    這篇文章主要介紹了C++中的模板類&模板函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08

最新評(píng)論