版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、1在一个函数内部定义的变量是内部变量,它只在在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能本函数范围内有效,也就是说只有在本函数内才能使用它们,在本函数以外是不能使用这些变量的。使用它们,在本函数以外是不能使用这些变量的。这样的变量也称为这样的变量也称为“局部变量局部变量”。 2float f1( int a) /*函数函数f1 */int b,c; a、b、c有效有效 char f2(int x,int y) /*函数函数f2 */ int i,j; x、y、i、j有效有效 void main( ) /*主函数主函数*/int m,n; m、n有效有效
2、 3主函数中定义的变量也只在主函数中有效主函数中定义的变量也只在主函数中有效,而不因为在主函数而不因为在主函数中定义而在整个文件或程序中有效。主函数也不能使用其他中定义而在整个文件或程序中有效。主函数也不能使用其他函数中定义的变量。函数中定义的变量。不同函数中可以使用相同名字的变量不同函数中可以使用相同名字的变量,它们代表不同的对象它们代表不同的对象,互互不干扰。例如不干扰。例如, 上面在上面在f1函数中定义了变量函数中定义了变量b和和c,若在若在f2函数中函数中也定义变量也定义变量b和和c,它们在内存中占不同的单元它们在内存中占不同的单元,互不混淆。互不混淆。形式参数也是局部变量。例如上面形
3、式参数也是局部变量。例如上面f1函数中的形参函数中的形参a,也只在也只在f1函数中有效。其他函数可以调用函数中有效。其他函数可以调用f1函数,但不能引用函数,但不能引用f1函数函数的形参的形参a。在一个函数内部在一个函数内部,可以在复合语句中定义变量可以在复合语句中定义变量,这些变量只在本这些变量只在本复合语句中有效复合语句中有效,这种复合语句也称为这种复合语句也称为“分程序分程序”或或“程序程序块块”。说明:说明:4void main ( )int a,b;int c; c=a+b; /*c在此范围内有效在此范围内有效*/ 5在函数内定义的变量是在函数内定义的变量是内部内部变量变量,而在函数
4、而在函数之外定义的变量称为之外定义的变量称为外部变量外部变量,外部变量是全外部变量是全局变量局变量(也称全程变量也称全程变量)。全局变量可以为本文。全局变量可以为本文件中其他函数所共用。它的有效范围为从定义件中其他函数所共用。它的有效范围为从定义变量的位置开始到本源文件结束。变量的位置开始到本源文件结束。 6int p=1,q=5; /* 外部变量外部变量 */float f1(int a) /* 定义函数定义函数f1 */int b,c; /*全局变量全局变量p,q的作用范围的作用范围*/char c1,c2; /* 外部变量外部变量*/char f2 (int x, int y) /* 定
5、义函数定义函数f2 */int i,j; /*全局变量全局变量p,q的作用范围的作用范围 全局变量全局变量c1,c2的作用范围的作用范围*/void main ( ) /*主函数主函数*/int m,n; 7建议一般情况下不要使用全局变量,原因如下:建议一般情况下不要使用全局变量,原因如下: 全局变量在程序的全部执行过程中都占用存储单元,而不是仅在全局变量在程序的全部执行过程中都占用存储单元,而不是仅在需要时才开辟单元。需要时才开辟单元。 使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。在各个函数执
6、行时都可能改变外判断出每个瞬时各个外部变量的值。在各个函数执行时都可能改变外部变量的值,程序容易出错。因此,要限制使用全局变量。部变量的值,程序容易出错。因此,要限制使用全局变量。全局变量使函数的通用性降低了,因为函数在执行时要依赖于其所全局变量使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外在的外部变量。如果将一个函数移到另一个文件中,还要将有关的外部变量及其值一起移过去。但若该外部变量与其他文件的变量同名时,部变量及其值一起移过去。但若该外部变量与其他文件的变量同名时,就会出现问题,降低了程序的可靠性和通用性。一般要求把程序中就
7、会出现问题,降低了程序的可靠性和通用性。一般要求把程序中的函数做成一个封闭体,除了可以通过的函数做成一个封闭体,除了可以通过“实参实参形参形参”的渠道与外的渠道与外界发生联系外,没有其他渠道。界发生联系外,没有其他渠道。8三、作用域规则三、作用域规则 在程序中,可能会出现变量同名的情况在程序中,可能会出现变量同名的情况 ,C语言中,对于同名语言中,对于同名变量的处理有以下规则:变量的处理有以下规则:1、在同一作用域内,不允许出现同名变量的定义;、在同一作用域内,不允许出现同名变量的定义;2、相互独立的两个作用域内的同名变量分配不同的存储单元,、相互独立的两个作用域内的同名变量分配不同的存储单元
8、,代表不同的变量,互不影响;代表不同的变量,互不影响;3、如果在一个作用域和其所包含的子作用域内出现同名变量,、如果在一个作用域和其所包含的子作用域内出现同名变量,则在子作用域中引用该变量时,内层变量有效,外层变量被屏则在子作用域中引用该变量时,内层变量有效,外层变量被屏蔽。蔽。9例例1 1:外部变量与局部变量同名。:外部变量与局部变量同名。#include #include int a=3,b=5; /* a,b为外部变量 */int a=3,b=5; /* a,b为外部变量 */void main()void main() int a=8; /* a为局部变量 */ int a=8; /*
9、 a为局部变量 */ printf(%d,max(a,b); /* a为局部变量,b为全局变量 */ printf(%d,max(a,b); /* a为局部变量,b为全局变量 */ max(int a,int b) /* a,b为局部变量 */ max(int a,int b) /* a,b为局部变量 */ int c; int c; c=ab?a:b; c=ab?a:b; return (c); return (c); 10 前面已介绍了从变量的作用域(即从空间)角度来分,前面已介绍了从变量的作用域(即从空间)角度来分,可以将变量分为全局变量和局部变量。如果从变量值存在的可以将变量分为全局变
10、量和局部变量。如果从变量值存在的时间(即生存期)角度来分,又可以分为静态存储方式和动时间(即生存期)角度来分,又可以分为静态存储方式和动态存储方式。态存储方式。 所谓静态存储方式是指在程序运行期间由系统分配固定的所谓静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式。而动态存储方式则是在程序运行期间根据存储空间的方式。而动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。因此,存储空间可以需要进行动态的分配存储空间的方式。因此,存储空间可以分为三部分:分为三部分: p 程序区程序区程序运行程序运行p 静态存储区静态存储区全局变量、静态局部变量全局变量、静态局部变量p
11、动态存储区动态存储区形参、自动变量、函数返回地址等形参、自动变量、函数返回地址等11在语言中每一个变量和函数有两个属性:数据类在语言中每一个变量和函数有两个属性:数据类型和数据的存储类别。对数据类型,大家已熟悉(如型和数据的存储类别。对数据类型,大家已熟悉(如整型、字符型等)。存储类别指的是数据在内存中存整型、字符型等)。存储类别指的是数据在内存中存储的方式。存储方式分为两大类:静态存储类和动态储的方式。存储方式分为两大类:静态存储类和动态存储类。具体包含四种:存储类。具体包含四种:自动的自动的(auto),),静态的静态的(static),),寄存器的寄存器的(register),),外部的
12、外部的(extern)。根据变量的存储类别,可以知道变量的作用域和生存根据变量的存储类别,可以知道变量的作用域和生存期。期。 12函数中的局部变量,如不专门声明为函数中的局部变量,如不专门声明为static存储类别,都存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。函数是动态地分配存储空间的,数据存储在动态存储区中。函数中的形参和在函数中定义的变量中的形参和在函数中定义的变量(包括在复合语句中定义的包括在复合语句中定义的变量变量),都属此类,在调用该函数时系统会给它们分配存储,都属此类,在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。因此这空间,在函
13、数调用结束时就自动释放这些存储空间。因此这类局部变量称为自动变量。自动变量用关键字类局部变量称为自动变量。自动变量用关键字auto作存储类作存储类别的声明。例如:别的声明。例如:int f(int ) *定义定义f函数,为形参函数,为形参 *auto int ,;,; *定义、为自动变量定义、为自动变量 * 13 自动变量示例。自动变量示例。#include #include void main()void main() void fun(); void fun(); auto int i; auto int i; for(i=1;i=4;i+) for(i=1;i=4;i+) fun();
14、fun(); void fun()void fun() auto int i=0; auto int i=0; i+; i+; printf(i have been called %d times.n,i); printf(i have been called %d times.n,i); 14 有时希望函数中的局部变量的值在函数调用结有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值。这时就应该指定该局上
15、一次函数调用结束时的值。这时就应该指定该局部变量为部变量为“静态局部变量静态局部变量”,用关键字,用关键字 static 进行进行声明。声明。15对静态局部变量的说明:对静态局部变量的说明:(1) 静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程静态局部变量属于静态存储类别,在静态存储区内分配存储单元。在程序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类序整个运行期间都不释放。而自动变量(即动态局部变量)属于动态存储类别,占动态存储区空间而不占静态存储区空间,函数调用结束后即释放。别,占动态存储区空间而不占静态存储区空间,函数调用结束后即释放。(2) 对静态局部
16、变量是在编译时赋初值的,即只赋初值一次,在程序运行时对静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用它已有初值。以后每次调用函数时不再重新赋初值而只是保留上次函数调用结束时的值。而对自动变量赋初值,不是在编译时进行的,而是在函数调用结束时的值。而对自动变量赋初值,不是在编译时进行的,而是在函数调用时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。时进行,每调用一次函数重新给一次初值,相当于执行一次赋值语句。(3) 如在定义局部变量时不赋初值的话,则对静态局部变量来说,编译时自如在定义局部变量时不赋初值的
17、话,则对静态局部变量来说,编译时自动赋初值(对数值型变量)或空字符(对字符变量)。而对自动变量来说,动赋初值(对数值型变量)或空字符(对字符变量)。而对自动变量来说,如果不赋初值则它的值是一个不确定的值。这是由于每次函数调用结束后存如果不赋初值则它的值是一个不确定的值。这是由于每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的值储单元已释放,下次调用时又重新另分配存储单元,而所分配的单元中的值是不确定的。是不确定的。(4) 虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用虽然静态局部变量在函数调用结束后仍然存在,但其他函数是不能引用它的。它的。1
18、6将将改为静态局部变量。改为静态局部变量。#include #include void main()void main() void fun(); void fun(); int i; int i; for(i=1;i=4;i+) for(i=1;i=4;i+) fun(); fun(); void fun()void fun() static int i=0; static int i=0; i+; i+; printf(i have been called %d times.n,i); printf(i have been called %d times.n,i); 17 静态变量示例。静
19、态变量示例。#include #include void main()void main() int i; int i; for(i=1;i=5;i+) for(i=1;i=5;i+) printf(%d!=%dn,i,fac(i); printf(%d!=%dn,i,fac(i); int fac(int n)int fac(int n) static int f=1; static int f=1; f=f*n; f=f*n; return f; return f; 18四、四、register变量变量 一般情况下,变量(包括静态存储方式和动态存储一般情况下,变量(包括静态存储方式和动态存
20、储方式)的值是存放在内存中的。当程序中用到哪一个方式)的值是存放在内存中的。当程序中用到哪一个变量的值时,由控制器发出指令将内存中该变量的值变量的值时,由控制器发出指令将内存中该变量的值送到运算器中。送到运算器中。 经过运算器进行运算,如果需要存数,经过运算器进行运算,如果需要存数,再从运算器将数据送到内存存放。再从运算器将数据送到内存存放。 19如果有一些变量使用频繁(例如在一个函数中执行如果有一些变量使用频繁(例如在一个函数中执行次循环,每次循环中都要引用某局部变次循环,每次循环中都要引用某局部变量),则为存取变量的值要花费不少时间。为提高执量),则为存取变量的值要花费不少时间。为提高执行
21、效率,语言允许将局部变量的值放在行效率,语言允许将局部变量的值放在CPU中的寄中的寄存器中,需要用时直接从寄存器取出参加运算,不必存器中,需要用时直接从寄存器取出参加运算,不必再到内存中去存取。由于寄存器的存取速度远高于对再到内存中去存取。由于寄存器的存取速度远高于对内存的存取速度,因此这样做可以提高执行效率。这内存的存取速度,因此这样做可以提高执行效率。这种变量叫做种变量叫做寄存器变量寄存器变量,用关键字,用关键字 register 作声明。作声明。20 寄存器变量示例。寄存器变量示例。#include #include void main()void main() int i; int i
22、; for(i=1;i=5;i+) for(i=1;i=5;i+) printf(sum(%d)=%dn,i,sum(i); printf(sum(%d)=%dn,i,sum(i); int sum(int n)int sum(int n) register int i,s=0; /* 定义寄存器变量 */ register int i,s=0; /* 定义寄存器变量 */ for(i=0;i=n;i+) for(i=0;i=n;i+) s=s+i; s=s+i; return(s); return(s); 21说明:说明:(1)只有局部自动变量和形式参数可以作为寄)只有局部自动变量和形式参数
23、可以作为寄存器变量,其它(如全局变量)不行。存器变量,其它(如全局变量)不行。(2)一个计算机系统中的寄存器数目是有限的,)一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。不能定义任意多个寄存器变量。(3)静态局部变量不能定义为寄存器变量。)静态局部变量不能定义为寄存器变量。22五、五、 extern 变量变量 extern变量是外部变量,也称全局变量,它是在变量是外部变量,也称全局变量,它是在函数的外部定义的变量,它的作用域是从变量的定函数的外部定义的变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,义处开始,到本程序文件的末尾。在此作用域内,全局变量
24、可以为程序中各个函数所引用。编译时将全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。外部变量分配在静态存储区。 有时需要用有时需要用 extern 来声明外部变量,以扩展外来声明外部变量,以扩展外部变量的作用域。部变量的作用域。231、在一个文件内声明外部变量、在一个文件内声明外部变量例例4.17:外部变量示例。:外部变量示例。#include #include int a=1;int a=1;void main()void main() extern int m; /*扩展外部变量作用域*/ extern int m; /*扩展外部变量作用域*/ printf(fun(
25、%d)=%dn,a+m,fun(a+m); printf(fun(%d)=%dn,a+m,fun(a+m); int m=3;int m=3;int fun(int x)int fun(int x) int t; int t; t=2*x+m; t=2*x+m; return(t); return(t); 24(1) 对于多文件程序,在对于多文件程序,在tc20环境中要先将其加入一个工程文件环境中要先将其加入一个工程文件中,我们可以使用任何文字编辑器将中,我们可以使用任何文字编辑器将C源文件写入这个工程文件源文件写入这个工程文件(.PRJ)中,一行一个文件名(含扩展名),编辑完成将其保)中,一
26、行一个文件名(含扩展名),编辑完成将其保存为存为 *.prj 文件。文件。(2) 打开打开tc20编辑框,选择编辑框,选择”project”-”project name”项。项。输入你的输入你的 *.prj文件名。例如,你的文件名。例如,你的*.prj文件在文件在d:下下,输入输入d:*.prj,再选择,再选择“Compile”菜单下的菜单下的“Make EXE file”命令进命令进行编译和连接,产生可执行的文件,执行即可。行编译和连接,产生可执行的文件,执行即可。(3)VC+中先建工程,再依次加入多个源程序文件,编译、连接中先建工程,再依次加入多个源程序文件,编译、连接后,即可运行。后,即
27、可运行。2. 在多文件的程序中声明外部变量在多文件的程序中声明外部变量25输入输入3个实数,求以这个实数,求以这3个实数为边长构成的三角形的面个实数为边长构成的三角形的面积和长方形体积。积和长方形体积。文件文件file1.c中的内容为:file1.c中的内容为:#include #include double a,b,c; /*定义外部变量*/double a,b,c; /*定义外部变量*/double s1();double s1();double s2();double s2();void main() void main() printf(请输入a,b,c三条边的长:); printf(
28、请输入a,b,c三条边的长:); scanf(%lf,%lf,%lf,&a,&b,&c); scanf(%lf,%lf,%lf,&a,&b,&c); if(a+bc & a+cb & b+ca) if(a+bc & a+cb & b+ca) printf(s1()=%6.2lfn,s1(); printf(s1()=%6.2lfn,s1(); printf(s2()=%6.2lfn,s2(); printf(s2()=%6.2lfn,s2(); else else printf(s2()=%6.2lfn,s2();
29、 printf(s2()=%6.2lfn,s2(); 文件file2.c中的内容为:文件file2.c中的内容为:26六、用六、用static声明外部变量声明外部变量有时在程序设计中希望某些外部变量只限于被本文有时在程序设计中希望某些外部变量只限于被本文件引用,而不能被其他文件引用。这时可以在定义外件引用,而不能被其他文件引用。这时可以在定义外部变量时加一个部变量时加一个 static 声明。声明。例如:例如:file1.c file2.cstatic int a; extern int a;void main ( ) void fun (int n) a=a*n; 此时,在此时,在file2
30、.c中无法使用中无法使用file1.c中的全局变量中的全局变量a。27七、关于变量的声明和定义七、关于变量的声明和定义对变量而言,声明与定义的关系稍微复杂一些。对变量而言,声明与定义的关系稍微复杂一些。在声明部分出现的变量有两种情况:一种是需要建立在声明部分出现的变量有两种情况:一种是需要建立存储空间的存储空间的(如:如:int a; ),另一种是不需要建立存储,另一种是不需要建立存储空间的(如:空间的(如:extern a;)。前者称为;)。前者称为“定义性声定义性声明明”(defining declaration) ,或简称定义,或简称定义(definition)。)。 后者称为后者称为“
31、引用性声引用性声明明”(referencing declaration)。广义地说,声明包括。广义地说,声明包括定义,但并非所有的声明都是定义。对定义,但并非所有的声明都是定义。对“int a;” 而言,而言,它既是声明,又是定义。而对它既是声明,又是定义。而对“extern a;” 而言,它而言,它是声明而不是定义。是声明而不是定义。28一般为了叙述方便,把建立存储空间的声明称为一般为了叙述方便,把建立存储空间的声明称为定义,而把不需要建立存储空间的声明称为声明。定义,而把不需要建立存储空间的声明称为声明。显然这里指的声明是狭义的,即非定义性声明。例显然这里指的声明是狭义的,即非定义性声明。
32、例如:如:void main() extern a; /*是声明不是定义。声明是声明不是定义。声明a是一是一 个已定义的外部变量个已定义的外部变量*/ int a; 294.10 内部函数和外部函数内部函数和外部函数 函数本质上是全局的函数本质上是全局的,因为一个函数要被另外的函因为一个函数要被另外的函数调用数调用,但是但是,也可以指定函数不能被其他文件调用。也可以指定函数不能被其他文件调用。根据函数能否被其他源文件调用根据函数能否被其他源文件调用,将函数区分为将函数区分为内部内部函数函数和和外部函数外部函数。如果一个函数只能被本文件中其他函数所调用如果一个函数只能被本文件中其他函数所调用,它
33、称为内它称为内部函数。在定义内部函数时部函数。在定义内部函数时,在函数名和函数类型的前面加在函数名和函数类型的前面加static。即。即static 类型标识符类型标识符 函数名函数名(形参表形参表)如如 static int fun ( int a , int b )内部函数的存储类别为静态存储类别,因此内部函数也称内部函数的存储类别为静态存储类别,因此内部函数也称为静态函数。为静态函数。30输入两数,求它们的和与积。输入两数,求它们的和与积。本例包含本例包含2个文件,个文件,file1.c的功能是输入数据,求它们的的功能是输入数据,求它们的和;和;file2.c的功能是求它们的积。(此例需
34、先建工程文件)的功能是求它们的积。(此例需先建工程文件)文件文件file1.c中的内容为:file1.c中的内容为:#include #include int mul(int a,int b);int mul(int a,int b);int sum(int a,int b);int sum(int a,int b);void main() void main() int a,b; int a,b; printf(请输入 a,b的值:); printf(请输入 a,b的值:); scanf(%d,%d,&a,&b); scanf(%d,%d,&a,&b); pr
35、intf(%d+%d=%dn,a,b,sum(a,b); printf(%d+%d=%dn,a,b,sum(a,b); printf(%d*%d=%dn,a,b,mul(a,b); printf(%d*%d=%dn,a,b,mul(a,b); int sum(int a,int b)int sum(int a,int b) return(a+b); return(a+b); 文件file2.c中的内容为:文件file2.c中的内容为:31(1) 在定义函数时在定义函数时,如果在函数首部的最左端加关键字如果在函数首部的最左端加关键字extern,则表示此函数是外部函数,可供其他文件调用。如函数首则表示此函数是外部函数,可供其他文件调用。如函数首部可以写为部可以写为extern int fun (int a, int b)这样,函数这样,函数fun就可以为其他文件调用。就可以为其他文件调用。C语言规定,如果语言规定,如果在定义函数时省略在定义函数时省略extern,则隐含为外部函数。本书前面所则隐含为外部函数。本书前面所用的函数都是外部函数。用的函数都是外部函数。(2) 如果函数的定义位于其它文件中,在需要调用此函数的如果函数的定义位于其它文件中,在需要调用此函
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 采购项目奖金分配制度
- 钉钉采购单制度
- 八年级数学3月学情自测卷01(答案版)(新教材人教版)
- 2025年财政杠杆撬动绿色生活方式转型:固定与浮动补贴的激励逻辑与效能评估报告
- 《第五单元复习课》名师教学设计
- 《自由平等的追求》教学设计
- 《一个学派的诞生》阅读练习
- 竞选大队长演讲稿8篇
- 适合春节朗诵的诗歌13篇
- 饲料买卖合同(汇编15篇)
- ATLAS空压机常见故障分析和处置
- 念奴娇 过洞庭教学课件
- 医师注册健康体检表
- 高速公路工程安全监理大纲
- 2023版思想道德与法治专题1担当复兴大任 成就时代新人PPT
- 现代设计理论与方法(上)
- ISO2553-2019焊接符号-培训资料
- GB/T 33130-2016高标准农田建设评价规范
- T∕CMATB 7001-2020 冷冻肉冷藏规范
- 六年级比例教材分析课件
- 宠物店如何给宠物做SPA
评论
0/150
提交评论