ImageVerifierCode 换一换
格式:PPT , 页数:73 ,大小:835.50KB ,
资源ID:6949417      下载积分:10 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.docduoduo.com/d-6949417.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录   微博登录 

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(第五章C程序设计结构(指针)1.ppt)为本站会员(fmgc7290)主动上传,道客多多仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知道客多多(发送邮件至docduoduo@163.com或直接QQ联系客服),我们立即给予删除!

第五章C程序设计结构(指针)1.ppt

1、第5章 指针,三峡大学科技学院,5,5.1指针与指针变量,5.2 指针变量,5.3 指针与数组的关系,5.4 指针与函数的关系,5.5 程序举例,本章目录,本章要点,变量、内存单元和地址之间是什么关系? 如何定义指针变量,怎样才能使用指针变量? 什么是指针变量的初始化? 指针变量的基本运算有哪些?如何使用指针操作所指向的变量? 指针作为函数参数的作用是什么? 如何使用指针实现函数调用返回多个值? 如何利用指针实现内存的动态分配?,例: 寻找保险箱密码,一个关于特工008寻找保险箱密码的故事 关键点分析 得到线索:0217单元的“虎跑号”寄存箱 提示地址:1976单元 找到目标:“龙井号”寄存箱

2、 取出内容:911,寻找密码的途径分析,密码911存放在某个寄存箱内,如果我们知道这个寄存箱的名字,就能够找到密码 如果不知道密码所在的寄存箱名字,知道该寄存箱的地址也照样能够取出密码 如果寄存箱的地址也不知道,但是有另外一个地方存放这个寄存箱的地址,就能顺藤摸瓜,间接找到密码,密码存放示意图,例 利用指针模拟寻找保险箱密码的过程,获取密码的两种方法 int main(void) int key = 911; /* 变量key存放密码 */int *addr = NULL; /* 变量addr存放地址 */addr = ,The key is: 911 If I know the addres

3、s of the key, I also can get it: 911,三峡大学科技学院,指针的意义,对于计算机来讲,编程时用到的各种变量需要在内存中占据存储空间,内存单元有一个唯一的编号来区分,该编号就称为内存地址,也即指针。 指针就是指向某一特定位置的地址。,地址和指针指针的概念,内存单元 地址 内容 变量,int x = 20, y = 1, z = 155; printf(“%d“, x;),直接访问:通过变量名访问,间接访问:通过另一个变量访问 把变量的地址放到另一变量中 使用时先找到后者 再从中取出前者的地址,地址 指针变量,指针,内存单元 地址 内容 变量,int x = 20

4、, y = 1, z = 155; printf(“%d“, x;),地址 指针变量,指针变量:存放地址的变量,某个变量的地址,指向,指针的概念 变量与地址,程序中: int i; float k;,内存中每个字节有一个编号-地址,i,k,编译或函数调用时为其分配内存单元,变量是对程序中数据 存储空间的抽象,指针与指针变量 指针:一个变量的地址 指针变量:专门存放变量地址的变量叫,2000,指针,指针变量,变量的内容,变量的地址,&与*运算符 含义,含义: 取变量的地址 单目运算符 优先级: 2 结合性:自右向左,含义: 取指针所指向变量的内容 单目运算符 优先级: 2 结合性:自右向左,两者

5、关系:互为逆运算 理解,i_pointer-指针变量,它的内容是地址量 *i_pointer-指针的目标变量,它的内容是数据 &i_pointer-指针变量占用内存的地址,i_pointer &i &(*i_pointer) i *i_pointer *(&i),i_pointer = &i = &(*i_pointer) i = *i_pointer = *(&i),直接访问与间接访问 直接访问:按变量地址存取变量值 间接访问:通过存放变量地址的变量去访问变量,例 i=3; -直接访问,3,例 *i_pointer=20; -间接访问,20,例 k=i; -直接访问k=*i_pointer;

6、 -间接访问,10,例 k=i; k=*i_pointer;,指针变量所指向的变量的类型,int *p; p 是整型指针,指向整型变量 float *fp; fp 是浮点型指针,指向浮点型变量 char *cp;cp 是字符型指针,指向字符型变量,类型名 * 指针变量名,指针声明符,指针变量的定义,指针变量的定义,类型名 * 指针变量名 int * p; 指针变量名是 p,不是*p * 是指针声明符int k, *p1, *p2; 等价于: int k; int *p1; int *p2;,指针变量 指针变量与其所指向的变量之间的关系,指针变量的定义 一般形式: 存储类型 数据类型 *指针名;

7、,合法标识符,指针变量本身的存储类型,指针的目标变量的数据类型,表示定义指针变量 不是*运算符,例 int *p1,*p2;float *q ;static char *name;,注意: 1、int *p1, *p2; 与 int *p1, p2; 2、指针变量名是p1,p2 ,不是*p1,*p2 3、指针变量只能指向定义时所规定类型的变量 4、指针变量定义后,变量值不确定,应用前必须先赋值,指针变量的初始化 一般形式:存储类型 数据类型 *指针名=初始地址值;,赋给指针变量, 不是赋给目标变量,例 int i;int *p=,变量必须已说明过 类型应一致,例 int i;int *p=,用

8、已初始化指针变量作初值,例 main( ) int i;static int *p= (),不能用auto变量的地址 去初始化static型指针,例 main( ) int i=10;int *p;*p=i;printf(“%d”,*p);,危险!,例 main( ) int i=10,k;int *p;p=,指针变量必须先赋值,再使用,零指针与空类型指针 零指针:(空指针) 定义:指针变量值为零 表示: int * p=0;,p指向地址为0的单元, 系统保证该单元不作它用 表示指针变量值没有意义,#define NULL 0 int *p=NULL:,p=NULL与未对p赋值不同 用途: 避

9、免指针变量的非法引用 在程序中常作为状态比较,例 int *p;while(p!=NULL) .,void *类型指针 表示: void *p; 使用时要进行强制类型转换,例 char *p1;void *p2;p1=(char *)p2;p2=(void *)p1;,表示不指定p是指向哪一种 类型数据的指针变量,举例如下:,int pi; /*定义了一个整型的普通变量pi,它占两个字节的内存空间,可存放一个整型数据*/ int * pi;/*定义了一个指针变量pi,它指向一个整型的变量空间*/ char * pc; /*定义了一个指针变量pc,它指向一个字符型的变量空间*/ float *

10、pf; /*定义了一个指针变量pf,它指向一个单精度的变量空间*/ double *pd; /*定义了一个指针变量pd,它指向一个双精度的变量空间*/,注意,(1)在int *pi中,指针变量名是pi,不是*pi,定义时的“*”既不是指针变量的组成部分,也不是运算符; (2)在指针变量的定义中存在这样一个误区,那就是错误的认为语句 int *p,m,n; 中声明了3个指针变量,其实只有第一个(p)是指针变量,而其他两个(m,n)只是int型变量。要同时定义几个指针变量,可以用下面这种方式: int *p, *m, *n, .; 即在每个指针变量的前面加一个*,如int *p1, *p2; 而不

11、是int *p1, p2; (3)指针变量定义后,同普通变量一样,并没有确定的值,因而也没有确定的指向。要使用该指针变量,必须对其赋值; (4)指针变量只能指向定义时所规定类型的变量,类型不匹配时,需要进行强制类型转换。 (5)当定义任何变量时,在编译阶段,计算机会为变量分配内存空间。虽然他们所指向的变量类型不同,但是他们本身占用的内存空间大小是一样的,对于16位编址系统来讲,都占用2个字节的内存。,例 指针的概念,main() int a;int *pa= ,运行结果: a:10 *pa:10 &a:f86(hex) pa:f86(hex) &pa:f88(hex),指针的基本运算,* 间接

12、访问运算符,访问指针所指向的变量 *p:指针变量 p 所指向的变量,*p,如果指针的值是某个变量的地址,通过指针就能间接访问那个变量。 1、取地址运算和间接访问运算 把 a 的地址赋给 p,即 p 指向 a,指针变量的类型和它所指向变量的类型相同,# include int main (void) int a = 3, *p; p = ,例:指针取地址运算和间接访问运算,a = 3, *p = 3 a = 10, *p = 10 Enter a: 5 a = 5, *p = 5 a = 6, *p = 6,(1) 当 p = 指针p所指向的变量,即a (3) &*p 与 &a 相同,是地址*&

13、a 与 a 相同,是变量 (4) (*p)+ 等价于 a+将 p 所指向的变量值加1*p+ 等价于 *(p+)先取 *p,然后 p 自加,此时p不再指向a,说明,int a = 1, x, *p; p = ,三峡大学科技学院,说明:*p+与(*p)+的区别,“*”与“+”优先级别相同,均是单目运算符,遵循右结合性,所以在*p+表达式中,p优先和“+”运算符结合,相当于*(p+),同时遵循其后缀运算方式(先引用,再自增),所以先取*p的值,也即p当前指向元素的值,p自己再自增,指向下一个数组元素。而在表达式(*p)+中,先计算*p,得到p指向元素的值,再将其值自加。假设有:int a10, *p

14、=a; a0=1;则运算完*p+后,该表达式值是1,p的值是&a1;而(*p)+运算完后,表达式的值是2,p的值依旧是a或&a0。,# include int main (void) int a = 1, b = 2, t;int *p1, *p2;p1 = ,例: 通过指针改变变量的值,a = 1, b = 2, *p1 = 1, *p2 = 2 a = 2, b = 1, *p1 = 2, *p2 = 1,2、赋值运算,*p1 *p2,int a = 3, *p1, *p2; p1 = p2 也指向 a,相同类型的指针才能相互赋值,例: 指针赋值,int main (void) int a

15、, b, c, *p1, *p2;a = 2; b = 4; c = 6;p1 = ,a = 2; b = 4; c = 6; *p1 = 2, *p2 = 4,a = 2; b = 4; c = 6; *p1 = 6, *p2 = 2,此句只改变p1、p2的指针指向,a、b、c的值并不改变,例 int main (void ) int a=1, b=2; int *p1 = ,指针变量的初始化,a = 1; b = 2; *p1 = 1, *p2 = 2 a = 1; b = 2; *p1 = 2, *p2 = 1,对指针的操作 / 对指针所指向变量的操作,*p1 和 *p2 的值都由 1

16、和 2 变成了 2 和 1 (1) 直接改变指针的值,对指针的操作,对指针所指向变量的操作,(2) 改变指针所指变量的值,指针作为函数的参数,函数参数包括实参和形参,两者的类型要一致,可以是指针类型。 如果实参是某个变量的地址,相应的形参就是指针。,int main (void) int a = 1, b = 2;int *pa = ,调用哪个函数,可以交换main ()中变量a和b的值?,例: swap1(),swap1 (a, b);void swap1 (int x, int y) int t;t = x; x = y; y = t; ,使用的是变量调用,即只调用。 实参变量到型参变量是

17、单项上值传递,例: swap2(),swap2 (pa, pb); /* swap2 ( ,传递时,地址未变,改变*pa和*pb的值,就交换了a和b的值,因此,存放变量的值改变了。即达到了交换的目的。,实参为指针变量pa和pb,其值分别是变量a和b的地址,地址传递,例: swap3(),swap3 (pa, pb); /* swap2 ( ,交换形参指针px和py的值时,但形参变量的改变不会影响实参,实参变量到型参变量是单项上值传递。,实参为指针变量pa和pb,其值分别是变量a和b的地址,地址传递,指针作为函数参数的应用,swap2 (pa, pb); void swap2 (int *px,

18、 int *py) int t;t = *px; *px = *py; *py = t; ,要通过函数调用来改变主调函数中某个变量的值: (1) 在主调函数中,将该变量的地址或者指向该变量的指针作为实参 (2) 在被调函数中,用指针类型形参接受该变量的地址 (3) 在被调函数中,改变形参所指向变量的值,After calling swap1: a=1, b=2 After calling swap2: a=2, b=1 After calling swap3: a=1, b=2,三峡大学科技学院,从上面的过程可以总结出: 访问变量可用两种方式:变量名以及存放该变量地址的指针变量; 在函数中,通

19、过将地址传递给被调用函数(swap),可以使得被调用函数利用自己定义的局部指针变量去间接地访问主调函数(main)中的变量,从而达到改变main函数中的局部变量的目的。达到了利用函数返回多个值的作用。这种调用方式被称为传址调用。,通过指针实现函数调用返回多个值,例 输入年和天数,输出对应的年、月、日。 例如:输入2000和61,输出2000-3-1。 定义函数month_day(year, yearday, *pmonth, *pday)用2个指针作为函数的参数,带回2个结果 int main (void) int day, month, year, yearday; void month_d

20、ay(int year,int yearday, int *pmonth,int *pday);printf(“input year and yearday: ”); scanf (“%d%d“, ,void month_day ( int year, int yearday, int * pmonth, int * pday) int k, leap;int tab 213 = 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ,0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 ,; /* 建

21、立闰年判别条件leap */leap = (year%4 = 0 ,input year and yearday: 2000 61 2000-3-1,改变了形参所指向变量的值所以主函数month和day的值随之改变,形参接收地址,三峡大学科技学院,指针变量的使用,用不同的方式访问变量。 main() int * p1, * p2, * p3, * p4;int a,b, c, d;p1= 运行: 10 12 a=6,b=8,c=10,d=12,冒泡排序-,数组与指针的异同点:相同之处:指针名和数组名都代表内存地址 不同之处:指针名是变量,它所代表的地址是可以改变的。数组名是常量,一旦被定义内存

22、空间就被分配,其地址是不能改变的。,http:/ swap2 (int *, int *); void bubble (int a , int n); int main(void) int n, a8; int i; printf(“Enter n (n=8): “);scanf(“%d“, ,void bubble (int a , int n) int i, j;for( i = 1; i aj+1)swap2 ( ,void swap2 (int *px, int *py) int t;t = *px; *px = *py; *py = t; ,Enter n (n=8): 8 Ente

23、r a8 : 7 3 66 3 -5 22 -77 2 After sorted, a8 = -77 -5 2 3 3 7 22 66,数组和地址间的关系,int a100, *p;数组名代表一个地址,它的值是数组首元素的地址(基地址)a+i 是距数组a的基地址的第i个偏移,sum = 0; for(i = 0; i 100; i+)sum = sum + ai ;,*(a+i),下标运算符 的含义,指针和数组的关系,任何由数组下标来实现的操作都能用指针来完成 int a100, *p; p = a; 或 p = ,&ai ai a+i *(a+i),p+i *(p+i) &pi pi,p =

24、 a; sum = 0; for(i = 0; i 100; i+)sum = sum + pi;,等价,等价,用指针完成对数组的操作,int a100, *p; 移动指针,p,sum = 0; for(p = a; p = ,p,p,p,# include int main (void) double a2, *p, *q;p = ,例: 使用指针计算数组元素个数和数组元素的存储单元数,1 8,指针p和q之间元素的个数,指针p和q之间的字节数,地址值,double *p, *q; q - p 两个相同类型的指针相减,表示它们之间相隔的存储单元的数目 p + 1 或 p-1 指向下一个存储单元

25、 或指向上一个存储单元 其他操作都是非法的 指针相加、相乘和相除,或指针加上和减去一个浮点数 p q 两个相同类型指针可以用关系运算符比较大小,指针的算术运算和比较运算,# include int main(void) int i, a10, *p;long sum = 0;printf(“Enter 10 integers: “);for(i = 0; i 10; i+) scanf(“%d“, ,使用指针计算数组元素之和,Enter 10 integers: 10 9 8 7 6 5 4 3 2 1 sum=55,p,p,p,p,例题: void main() int a =5,8,7,6

26、,2,7,3;int y,*p= 运行结果:5 6此外注意,p+是允许的,但是a+是不允许的操作,因为p是变量,而a是常量。,三峡大学科技学院,例:指针变量的指向超出数组范围。 main() int i,*p,a7;p=a;for(i=0;i7;i+)scanf(“%d“,p+); /*循环结束后,此时p已指向a6后面的一个存储空间*/printf(“n“);for(i=0;i7;i+,p+)printf(“%d “,*p); /*打印的是a6之后的连续7个未定义的整型空间内的未知的值*/ 运行: 5 8 7 6 2 7 3 2438 11290 -12345 7896 -3459 运行结果是

27、一些未知的数。,三峡大学科技学院,例可改为: main() int i,*p,a7;p=a;for(i=0;i7;i+)scanf(“%d“,p+); /*循环结束后,此时p已指向a6后面的一个存储空间*/ printf(“n“); p=a; /*让p重新归位,指向a数组的第一个元素*/for(i=0;i7;i+,p+)printf(“%d “,*p); /*打印的是a0开始的连续7个数组元素的值*/ ,数组元素作为函数实参时,函数形参为变量 与变量作为函数实参相同,值传递,数组名作为函数的参数,double fact (int n); int main(void ) int i, n = 5

28、;double sum;sum = 0;for(i = 1; i = n; i+ )sum = sum + fact (i);printf(“sum = %en“, sum); ,double fact (int n) int i; double result = 1; for (i = 1; i = n; i+)result = result * i ;return result ; ,int a5=1, 4, 5, 7, 9;,fact(ai-1);,1!+4!+5!+7!+9!,数组名是指针常量,相当于指针作为函数的参数 数组名做为实参,形参是指针变量(数组),数组名作为函数的参数,in

29、t sum (int *array, int n) int i, s = 0;for(i=0; in; i+)s += arrayi; return(s); ,例6-12 int main(void ) int i;int b5 = 1, 4, 5, 7, 9;printf(“%dn“, sum(b, 5);return 0; ,(1) 实参是数组名 (2) 形参是指针变量可以写成数组形式,int array ,*(array+i),int sum (int *array, int n) int i, s = 0;for(i=0; in; i+)s += arrayi; return(s);

30、,int main(void ) int i;int b5 = 1, 4, 5, 7, 9;printf(“%dn“, sum(b, 5);return 0; ,sum(b, 5),b0+b1+.+b4,sum(b, 3),b0+b1+b2,sum(b+1, 3),b1+b2+b3,sum(&b2, 3),b2+b3+b4,#include int main(void) int i, a10,n;void reverse(int p , int n);printf(“Enter n: “);scanf(“%d“, ,例: 将数组元素逆序存放,void reverse(int p , int n

31、) int i, j, t;for(i=0, j=n-1; ij; i+, j-)t = pi; pi = pj; pj = t; ,Enter n:10 Enter 10 integers: 10 9 8 7 6 5 4 3 2 1 1 2 3 4 5 6 7 8 9 10,数组名做为函数的参数,在函数调用时,将实参数组首元素的地址传给形参(指针变量),因此,形参也指向实参数组的首元素。如果改变形参所指向单元的值,就是改变实参数组首元素的值。 或:形参数组和实参数组共用同一段存贮空间,如果形参数组中元素的值发生变化,实参数组中元素的值也同时发生变化。,指针实现,void reverse(in

32、t *p, int n) int *pj, t;for(pj=p+n-1; ppj; p+, pj-)t=*p; *p=*pj; *pj=t; ,#include int main(void) int i, a10,n;void reverse(int p , int n);printf(“Enter n: “);scanf(“%d“, ,冒泡排序算法分析,相邻两个数比较,小的调到前面,大的调到后面,9 8 8 8 8 8 5 4 4 0 8 9 5 5 5 5 4 5 0 4 5 5 9 4 4 4 6 0 5 4 4 4 9 6 6 0 6 6 6 6 6 9 0 8 0 0 0 0 0

33、9,ajaj+1,j=0 to 4,j=0 to 3,j=0 to 2,j=0 to 6-1-i,9 8 8 8 8 8 5 4 4 0 8 9 5 5 5 5 4 5 0 4 5 5 9 4 4 4 6 0 5 4 4 4 9 6 6 0 6 6 6 6 6 9 0 8 0 0 0 0 0 9,9 8 5 4 6 0 i=1 j=0: 8 9 5 4 6 0 j=1: 8 5 9 4 6 0 j=2: 8 5 4 9 6 0 j=3: 8 5 4 6 9 0 j=4: 8 5 4 6 0 9,int main(void ) int i, j, n, t, a10; n = 6;for(i =

34、 0; i aj+1) t = aj;aj = aj+1;aj+1 = t;return 0; ,int main(void ) int i, a10; for(i=0; i10; i+)scanf(“%d“, ,void sort(int *array, int n) int i, j, t;for(i=1; iarrayj+1)t = arrayj;arrayj = arrayj+1;arrayj+1 = t; ,字符串:字符数组字符指针程序解析 字符数组和字符指针,加密问题,程序解析加密,# define MAXLINE 100 void encrypt(char *s); int ma

35、in (void) char line MAXLINE;printf (“Input the string: “);gets(line);encrypt (line);printf (“After being encrypted: %sn“, line);return 0; ,void encrypt ( char *s) for ( ; *s != 0; s+)if (*s = z)*s = a;else*s = *s+1; ,Input the string:hello hangzhou After being encrypted: ifmmp!ibohaipv,6.4.2 字符串和字符指

36、针,字符串常量 “array“ “point“ 用一对双引号括起来的字符序列 被看做一个特殊的一维字符数组,在内存中连续存放 实质上是一个指向该字符串首字符的指针常量 char sa = “array“; char *sp = “point“;,char sa = “array“; char *sp = “point“; rintf(“%s ”, sa); /*数组名sa作为输出的参数*/ printf(“%s ”, sp); /*字符指针sp作为输出的参数*/ printf(“%sn”, “string”); /*字符串常量作为输出的参数*/,array point string,print

37、f(“%s ”, sa+2); /*数组元素sa2的地址作为输出的参数*/ printf(“%s ”, sp+3); /*字符指针sp+3作为起始地址*/ printf(“%sn“, “string“+1);,ray nt tring,数组名sa、指针sp和字符串 “string“ 的值都是地址,字符数组与字符指针的重要区别,char sa = “This is a string“; char *sp = “This is a string“;,sa,sp,如果要改变数组sa所代表的字符串,只能改变数组元素的内容 如果要改变指针sp所代表的字符串,通常直接改变指针的值,让它指向新的字符串,存放

38、的是字符串的首地址,示例,char sa = “This is a string“; char *sp = “This is a string“;strcpy (sa, “Hello“); sp = “Hello“;sa = “Hello”; 非法 数组名是常量,不能对它赋值,字符指针先赋值,后引用,定义字符指针后,如果没有对它赋值,指针的值不确定。 char *s ; scanf(“%s”, s);char *s, str20; s = str; scanf(“%s”, s);定义指针时,允许先将它的初值置为空 char *s = NULL,不要引用未赋值的指针,这样将会造成难以预料的结果,

39、加密函数的两种实现,void encrypt (char s ) int i;for(i = 0; si != 0; i+)if (si = z)si = a;elsesi = si+1; ,void encrypt ( char *s) for ( ; *s != 0; s+)if (*s = z)*s = a;else*s = *s+1; ,例 下列定义的含义 (1)int *p3; (2)int (*p)3; (3)int *p(int); (4)int (*p)(int); (5)int *(*p)(int); (6)int (*p3)(int); (7)int *(*p3)(int);,

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报