数组详细讲解课件_第1页
数组详细讲解课件_第2页
数组详细讲解课件_第3页
数组详细讲解课件_第4页
数组详细讲解课件_第5页
已阅读5页,还剩75页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Chap 7 数 组7.1 输出所有大于平均值的数7.2 找出矩阵中最大值所在的位置7.3 判断回文本章要点什么是数组? 为什么要使用数组? 如何定义数组?如何引用数组元素?二维数组的元素在内存中按什么方式存放?什么是字符串? 字符串结束符的作用是什么?如何实现字符串的存储和操作,包括字符串的输入和输出?怎样理解C语言将字符串作为一个特殊的一维字符数组?例7-1 输入10个整数,计算这些数的平均值,再输出所有大于平均值的数。7.1.1 程序解析7.1.2 一维数组的定义和引用7.1.3 一维数组的初始化7.1.4 使用一维数组编程7.1 输出所有大于平均值的数7.1.1 程序解析输出大于均值的

2、数int main(void) int i; double average, sum; /* average存放平均值 */ int a10; /* 定义1个数组a,它有10个整型元素 */ printf (Enter 10 integers: ); sum = 0; for( i = 0; i average: ); for( i = 0; i average ) printf( %d , ai ); printf ( n ); return 0;Enter 10 integers:55 23 8 11 22 89 0 -1 78 186average = 47.10average: 55

3、89 78 1860123456789552381122890-178186for( i = 0; i 10; i+ ) scanf ( %d, &ai ); sum = sum + ai; a a0 a1 a9数组数组:相同类型数据的有序集合,在内存中连续存放。 由数组名和下标惟一地确定每个数组元素 每个元素都属于同一类型一批相同类型的变量使用同一个数组变量名,用下标来相互区分。优点:表述简洁,可读性高;便于使用循环结构7.1.2 一维数组的定义和引用1、定义 类型名 数组名 数组长度类型名:数组元素的类型数组名:数组(变量)的名称,标识符数组长度:常量表达式,给定数组的大小int a10;

4、 定义一个含有10个整型元素的数组 achar c200;定义一个含有200个字符元素的数组 cfloat f5;定义一个含有5个浮点型元素的数组 f数组长度为常量2、数组的内存结构内存地址下标值40289402684024740226402054018440163401424012140100aint a10; 假设系统规定 int 类型占用2个字节,则对于数组a,其内存分配形式 只要知道了数组第一个元素的地址以及每个元素所需的字节数,其余各个元素的存储地址均可计算得到。 数组名是一个地址常量,存放数组内存空间的首地址。3、引用先定义,后使用只能引用单个的数组元素,不能一次引用整个数组int

5、 a10;10个数组元素:a0、a1、 a9数组元素:数组名下标下标:整型表达式下标取值范围:0,数组长度-1数组元素的使用方法与同类型的变量相同scanf(%d, &ai);sum = sum + ai;printf(%d , ai);下标不要越界不能使用a10定义数组类型名 数组名数组长度引用数组元素数组名下标int a10;a0 = a9 = 0;ai = i;区分数组的定义和数组元素的引用下标不要越界数组长度为常量7.1.3 一维数组的初始化定义数组时,对数组元素赋初值类型名 数组名数组长度 = 初值表;int a10 = 1,2,3,4,5,6,7,8,9,10;a0=1, a1=2

6、,. a9=10静态数组、动态数组的初始化static int b5 = 1, 2, 3, 4, 5; 静态存储的数组如果没有初始化,所有元素自动赋0static int b5;动态存储的数组如果没有初始化,所有元素为随机值auto int c5; 等价与 int c5;static int b5 = 1, 2, 3;b0 = 1, b1 = 2, b2 = 3, b3 = 0, b4 = 0 auto int fib20 = 0, 1;fib0 = 0, fib1 = 1, 其余元素不确定如果对全部元素都赋初值,可以省略数组长度int a 10 = 0, 1, 2, 3, 4, 5, 6,

7、7, 8, 9针对部分元素的初始化建议不要省略数组长度7.1.4 使用一维数组编程数组和循环for ( i = 0; i n; i+ ) printf ( %d , ai );数组下标作为循环变量,通过循环,逐个处理数组元素 一维数组示例例 7-2 用数组计算fibonacci数列的前10个数,并按每行打印5个数的格式输出。1, 1, 2, 3, 5, 例 7-3 顺序查找法。输入5个整数,将它们存入数组a中,再输入1个数x,然后在数组中查找x,如果找到,输出相应的最小下标,否则,输出“Not Found”。例 7-4 输入n(n10),再输入n个数(1) 输出最小值和它所对应的下标(2) 将

8、最小值与第一个数交换,输出交换后的n个数例 7-5 选择排序法。输入一个n(1n10 ),再输入n个整数,用选择法将它们从小到大排序后输出。例 7-6 调查电视节目欢迎程度。某电视台要进行一次对该台8个栏目(设相应栏目编号为18)的受欢迎情况,共调查了1000位观众,现要求编写程序,输入每一位观众的投票,每位观众只能选择一个最喜欢的栏目投票,统计输出各栏目的得票情况。补充 二分查找法。设已有一个10个元素的整形数组a,且按值从小到大有序。输入一个整数x,然后在数组中查找x,如果找到,输出相应的下标,否则,输出“Not Found”。用数组计算fibonacci数列的前10个数,并按每行打印5个

9、数的格式输出。1, 1, 2, 3, 5, 8, 13, 用数组计算并存放fibonacci数列的前10个数f0 = f1 = 1fn = fn-1 + fn-2 2n9例 7-2 计算fibonacci数列#include int main(void) int i; int fib10 = 1, 1; /* 数组初始化 */ for ( i = 2; i 10; i+ ) fibi = fibi - 1 + fibi - 2; for ( i = 0; i 10; i+ ) printf ( %6d, fibi ); if ( (i + 1) % 5 = 0 ) /* 5个数换行 */ pr

10、intf(n); return 0; 例 7-2 源程序 1 1 2 3 5 8 13 21 34 55输入5个整数,将它们存入数组a中,再输入1个数x,然后在数组中查找x,如果找到,输出相应的下标,否则,输出“Not Found”。输入:2 9 8 1 9 9输出:1输入:2 9 8 1 6 7输出:Not Found例7-3 在数组中查找一个给定的数#include int main(void) int i, flag, x; int a5; printf ( Enter 5 integers: “ ); for ( i = 0; i 5; i+ ) scanf ( %d, &ai );

11、printf (Enter x: “ ); scanf ( %d, &x ); flag = 0; for ( i = 0; i 5; i+ ) if ( ai = x ) printf ( Index is %dn, i ); flag = 1; break; if ( flag = 0 ) printf(Not Foundn); return 0; 例 7-3 源程序Enter 5 integers: 2 9 8 1 9Enter x: 9Index is 1Enter 5 integers: 2 9 8 1 9Enter x: 7Not Foundflag的作用?#include int

12、 main(void) int i, flag, x; int a5; printf(“Enter 5 integers: ); for(i = 0; i 5; i+) scanf(%d, &ai); printf(“Enter x: ); scanf(%d, &x); flag = 0; for(i = 0; i 5; i+) if(ai = x) printf(Index is %dn, i); flag = 1; break; if(flag = 0) printf(Not Foundn); return 0; 例 7-3 思考(1)Enter 5 integers: 2 9 8 1 9

13、Enter x: 9Index is 1Index is 4去掉break语句,结果?#include int main(void) int i, sub, x; int a5; printf(“Enter 5 integers: ); for(i = 0; i 5; i+) scanf(%d, &ai); printf(“Enter x: ); scanf(%d, &x); sub = -1; for(i = 0; i 5; i+) if(ai = x) sub = i; if(sub != -1) printf(Index is %dn, sub); else printf(Not Fou

14、ndn); return 0; 例 7-3 思考(2)Enter 5 integers: 2 9 8 1 9Enter x: 9Index is 4sub的作用?#include int main(void) int i, min, n; int a10; printf(“Enter n: ); scanf(%d, &n); printf(“Enter %d integers: , n); for(i = 0; i n; i+) scanf(%d, &ai); min = a0; for(i = 1; i n; i+) if(ai min) min = ai; printf(min is %d

15、 n, min); return 0;例 7-4 求最小值Enter n: 6Enter 6 integers: 2 9 -1 8 1 6min is -1方法!虽得到了最小值,但不能确定最小值所在下标!输入n(n10), 再输入n个数, 输出最小值和它所对应的下标。用index记录最小值对应的下标aindex就是最小值例 7-4(1) 求最小值及其下标流程图#include int main(void) int i, index, n; int a10; printf(“Enter n: ); scanf(%d, &n); printf(“Enter %d integers: , n); f

16、or(i = 0; i n; i+) scanf(%d, &ai); index = 0; for(i = 1; i n; i+) if(ai aindex) index = i; printf(min is %dtsub is %dn, aindex, index); return 0;求最小值及下标Enter n: 6Enter 6 integers: 2 9 -1 8 1 6min is -1 sub is 2 输入n(n10), 再输入n个数,将最小值与第一个数交换,输出交换后的n个数。用index记录最小值对应的下标aindex就是最小值最小值与第一个数交换aindex a0例 7-

17、4(2) 交换最小值例 7-5 选择法排序 输入n(n10), 再输入n个数,用选择法将它们从小到大排序后输出。设 n=5 ,输入为:3 5 2 8 1第1次: 1 5 2 8 3 第2次: 2 5 8 3 第3次: 3 8 5 第4次: 5 8 0123435281下标 值3 5 2 8 1 (n=5)5个数(a0a4)中找最小数,与a0交换(1) 1 5 2 8 3 a4 a04个数(a1a4)中找最小数,与a1交换(2) 1 2 5 8 3 a2 a13个数(a2a4)中找最小数,与a2交换(3) 1 2 3 8 5 a4 a22个数(a3a4)中找最小数,与a3交换(4) 1 2 3

18、5 8 a4 a3选择法(1)(1) n个数 (a0an-1) 中找最小数,与 a0 交换(2) n-1个数 (a1an-1) 中找最小数,与 a1 交换 (n-1) 2个数 (an-2an-1) 中找最小数,与 an-2 交换(1) 5个数 (a0a4) 中找最小数,与 a0 交换(2) 4个数 (a1a4) 中找最小数,与 a1 交换(3) 3个数 (a2a4) 中找最小数,与 a2 交换(4) 2个数 (a3a4) 中找最小数,与 a3 交换选择法(2)n个数重复n-1次流程图输入数组ak=0kn-1aiaindexindex=i假(0)假(0)真(非0)真(非0)i=i+1交换aind

19、ex和ak输出数组aindex=ki=k+1k=k+1in假(0)外循环控制: n 个数选择排序共需要n-1次内循环控制:在下标范围k,n-1内找最小值所在位置index选择法排序 (程序段) for(k = 0; k n-1; k+) index = k; for(i = k + 1; i n; i+) if(ai aindex) index = i; temp = aindex; aindex = ak; ak = temp; Enter n: 5Enter 10 integers: 3 5 2 8 1After sorted: 1 2 3 5 8某电视台要调查观众对该台8个栏目(设相应栏

20、目编号为18)的受欢迎情况,共调查了1000位观众。现要求编写程序,输入每一位观众的投票情况(每位观众只能选择一个最喜欢的栏目投票),统计并输出各栏目的得票情况。数组 count 保存各栏目的得票数counti:记录编号为 i ( 18 ) 的栏目的得票数counti+例 7-6 投票情况统计例7-6 源程序# includeint main( void ) int count9; int i, response; for ( i = 1; i = 8; i+ ) counti = 0; /* 各栏目计数器清0 */ for ( i = 1; i = 1 & response = 8 ) co

21、untresponse+; else printf ( invalid: %dn, response ); printf ( result:n“ ); for ( i = 1; i = 8; i+ ) printf( %4d%4dn, i, counti ); return 0;input your response: 3input your response: 6input your response: 9this is a bad response: 9input your response: 8result:1 22 03 4补充 二分法查找设已有一个10个元素的整形数组a,且按值从小到

22、大有序排列。输入一个整数x,然后在数组中查找x,如果找到,输出相应的下标,否则,输出“Not Found”。例7-3顺序的查找算法简单明了,其查找过程就是对数组元素从头到尾的遍历过程。当数组很大时,查找效率不高。二分查找的效率较高,前提是数组元素必须有序排列。二分法查找流程图二分法查找 (程序段) low = 0; high = n - 1; /* 开始时查找区间为整个数组 */ while ( low = high ) /* 循环条件 */ mid = (low + high) / 2; /* 中间位置 */ if ( x = amid ) break; /* 查找成功,中止循环 */ el

23、se if ( x amid ) high = mid - 1; /* 新查找区间为前半段,high前移 */ else low = mid + 1; /* 新查找区间为后半段,low后移 */ if ( low = high ) printf(Index is %d n, mid); else printf( Not Foundn);将1个3*2的矩阵存入1个3*2的二维数组中,找出最大值以及它的行下标和列下标,并输出该矩阵。 7.2.1 程序解析7.2.2 二维数组的定义和引用7.2.3 二维数组的初始化7.2.4 使用二维数组编程7.2 找出矩阵中最大值所在的位置 7.2.1 程序解析求

24、矩阵的最大值 例 7-7 将1个3*2的矩阵存入1个3*2的二维数组中,找出最大值以及它的行下标和列下标,并输出该矩阵。 row 记录最大值的行下标col 最大值的列下标arowcol 就是最大值int main(void) int col, i, j, row; int a32; printf(“Enter 6 integers:n) ; for(i = 0; i 3; i+) for(j = 0; j 2; j+) scanf(%d, &aij); for(i = 0; i 3; i+) for(j = 0; j 2; j+) printf(%4d, aij); printf(n); ro

25、w = col = 0; for ( i = 0; i 3; i+ ) for ( j = 0; j arowcol ) row = i; col = j; printf ( max = a%d%d = %dn, row, col, arowcol ); return 0; 例7-7 源程序Enter 6 integers: 3 2 10 -96 -13 2 10 -96 -1max = a10 = 10二维数组多维数组的空间想象二维数组: 一个表格或一个平面矩阵一维数组: 一列长表或一个向量多维数组: 多维空间的一个数据列阵三维数组: 三维空间的一个方阵7.2.2 二维数组的定义和引用1、定

26、义类型名 数组名行长度列长度int a32;定义1个二维数组a,3行2列,6个元素int b510;定义1个二维数组a,5 行 10 列, 50 个元素 2、引用先定义,后使用数组元素的引用:数组名行下标 列下标行下标和列下标:整型表达式行下标的取值范围是0,行长度-1列下标的取值范围是0,列长度-1int a32; 3 行 2 列, 6 个元素a00 a01 a10 a11 a20 a21 下标不要越界二维数组在内存中的存放方式int a32;3 行 2 列, 6 个元素表示1个3行2列的矩阵a00 a01 a10 a11 a20 a21 二维数组的元素在内存中按行/列方式存放a00a01a

27、10a11a20a21 7.2.3 二维数组的初始化1、分行赋初值int a33 = 1,2,3, 4,5,6, 7,8,9 ;static int b43 = 1,2,3, , 4,5 ;数组a1 2 3 4 5 67 8 9数组b1 2 30 0 04 5 00 0 02、顺序赋初值int a33 = 1,2,3,4,5,6,7,8,9 ;static int b43 = 1,2,3,0,0,0,4,5 ;省略行长度对全部元素都赋了初值,int a 3 = 1,2,3,4,5,6,7,8,9 ;或分行赋初值时,在初值表中列出了全部行static int b 3 = 1,2,3, , 4,5

28、, 数组a1 2 3 4 5 67 8 9数组b1 2 30 0 04 5 00 0 0建议不要省略7.2.4 使用二维数组编程行下标和列下标分别做为循环变量, 通过二重循环,遍历二维数组通常将行下标做为外循环的循环变量 列下标 内循环定义1个 3*2 的二维数组a,数组元素的值由下式给出,按矩阵的形式输出a。aij = i + j ( 0i2, 0j1 )例7-8 生成一个矩阵并输出 int a32;a00 a01 a10 a11 a20 a21 0 11 22 3#include int main(void) int i, j; int a32; for ( i = 0; i 3; i+

29、) for ( j = 0; j 2; j+ ) aij = i + j; for ( i = 0; i 3; i+ ) for ( j = 0; j 2; j+ ) printf ( %4d, aij ); printf ( n ); return 0; a00 a01 a10 a11 a20 a21 i = 0 j = 0i = 0 j = 1i = 1 j = 0i = 1 j = 1i = 2 j = 0i = 2 j = 1 例7-8 源程序0 11 22 3二维数组的输入例7-7中,int a32;for(i = 0; i 3; i+) for(j = 0; j 2; j+) sc

30、anf(%d, &aij);a00 a01 a10 a11 a20 a21 for(j = 0; j 2; j+) for(i = 0; i 3; i+) scanf(%d, &aij);Enter 6 integers: 3 2 10 -9 6 -1 3 2 10 -9 6 -1max = a10 = 10Enter 6 integers: 2 10 -9 6 -13 -9 2 610 -1max = a20 = 10int aNN; N是正整数aij:i、j的取值范围0,N-1用二维数组a表示N*N方阵时,对应关系:a00 a01 a02 主对角线 a10 a11 a12 上三角a20 a

31、21 a22 下三角 付对角线矩阵与二维数组i=ji=ji+j=N-1输入一个正整数n (1n6),根据下式生成1个n*n的方阵,然后将该方阵转置(行列互换)后输出。 aij = i * n + j + 1(0in-1,0jn-1)分析:int a66; n=3时例7-9 方阵转置 1 2 34 5 67 8 91 4 7 2 5 83 6 9a01 a10 a02 a20a12 a21aij aji#include int main(void) int i, j, n, temp; int a66; printf ( Enter n: “ ); scanf ( %d, &n ); /* 给二

32、维数组赋值 略*/ /* 行列互换*/ for(i = 0; i n; i+) for(j = 0; j n; j+) if ( i = j ) /* 只遍历上三角阵 */ temp = aij; aij = aji; aji = temp; /* 按矩阵的形式输出a 略 */ return 0; 例7-9 源程序 /* 行列互换*/ for(i = 0; i n; i+) for(j = 0; j n; j+) if(i = j) temp = aij; aij = aji; aji = temp; 1 2 3 4 5 67 8 9主对角线:i = j上三角: i =ji=01 4 7 2

33、5 63 8 9i=11 4 72 5 83 6 9例7-9 说明for( j = i; j n; j+) /* 行列互换*/for ( i = 0; i n; i+ ) for ( j = 0; j n; j+ ) temp = aij; aij = aji; aji = temp; 1 2 3 4 5 67 8 9例7-9 思考i=01 4 7 2 5 63 8 9i=11 2 74 5 83 6 9i=21 2 3 4 5 67 8 9例7-10 日期计算自定义1个函数day_of_year(year, month, day),计算并返回年year、月month和日day对应的是该年的第

34、几天。 day_of_year(2000, 3, 1) 返回61day_of_year(1981, 3, 1) 返回60分析: 月 0 1 2 3 11 12非闰年 0 31 28 31 30 31闰年 0 31 29 31 30 31int tab213 = 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 例7-10 源程序int day_of_year(int year, int month, int day) int k, leap; int tab213 = 0,

35、 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 ; leap = (year%4=0 & year%100!=0) | year %400=0; for ( k=1; kmonth; k+ ) day = day + tableapk; return day;例7-11 输入一个以回车符为结束标志的字符串(少于80个字符),判断该字符串是否为回文。回文就是字符串中心对称,如“abcba”、“abccba”是回文,“abcdba”不是回文。7.3.1 程序解析7.3.2 一维字

36、符数组7.3.3 字符串7.3.4 使用字符串编程7.3 判断回文7.3.1 程序解析-判断回文int main ( void ) int i, k; char line80; printf(Enter a string: ); k = 0; while ( (linek = getchar() ) != n ) k+; linek = 0; i =0; /* i是字符串首字符的下标 */ k = k -1; /* k是字符串尾字符的下标 */ while ( i= k) printf(It is a plalindromen); else printf(It is not a plalind

37、romen); return 0; Enter a string: abcbaIt is a plalindrome Enter a string: abcdbaIt is not a plalindrome 7.3.2 一维字符数组字符串的存储和运算可以用一维字符数组实现一维字符数组的定义、引用、初始化与其他类型的一维数组一样。char str80; 定义一个含有80个字符型元素的数组str char t5=H, a, p, p, y;初始化数组 t t0 t1 t4t H a p p y输出数组 t 的所有元素for ( i=0; i 对字符数组的操作1. 字符串的存储数组初始化字符串可以

38、存放在一维字符数组中 static char s6 = H, a, p, p, y, 0 ;字符数组初始化:用字符串常量static char s6 = Happy ;static char s6 = Happy;数组长度 = 字符串的有效长度 + 1char t5; Happy 能存入t吗? s0 s1 s5s H a p p y 0字符串的存储auto char s80 = Happy;字符串遇 0 结束第一个 0 前面的所有字符和 0 一起构成了字符串 Happy0 之后的其他数组元素与该字符串无关 s0 s1 s5s H a p p y 0 ? ?字符串由有效字符和字符串结束符 0 组

39、成 2. 对字符串的操作把字符串放入一维字符数组(存储)对字符串的操作 = 对字符数组的操作普通字符数组:数组元素的个数是确定的,一般用下标控制循环字符串:没有显式地给出有效字符的个数,只规定在字符串结束符 0 之前的字符都是字符串的有效字符,一般用结束符 0 来控制循环循环条件:si != 0 for(i = 0; si != 0; i+) putchar(si);for(i = 0; i 80; i+) putchar(si);for(i = 0; i 对字符数组的操作存储数组初始化static char s6 = a;赋值s0 = a; s1 = 0;输入 0 代表空操作,无法输入输入时

40、,设定一个输入结束符将输入结束符转换为字符串结束符 0a 2 个字符 a 和 0a 1 个字符常量区分a 和 a7.3.4 使用字符串编程 语言将字符串作为一个特殊的一维字符数组来处理。存储:把字符串放入一维字符数组数组初始化、赋值、输入对字符串的操作 = 对字符数组的操作对一维字符数组的操作:针对字符串的有效字符和字符串结束符检测字符串结束符 0 输入一个以回车符为结束标志的字符串(少于80个字符),统计其中数字字符(09)的个数。分析:数组长度取上限80以 n 做为输入结束符例7-12 统计数字字符个数int main(void) int count, i; char str80; pri

41、ntf ( Enter a string: ); i = 0; while ( (stri = getchar( ) != n ) i+; stri = 0; /* 输入结束符字符串结束符 */ count = 0; for(i = 0; stri != 0; i+) if ( stri = 0 ) count+; printf ( count = %dn, count ); return 0; 例7-12源程序字符串的输入Enter a string: Its 512count = 3如何改变输入结束符?能省略stri = 0吗? 0 1 2 3 4 5 6 7 8sI t s 5 1 2 0 ? ?输入一个以回车符为结束标志的字符串(少于10个字符),提取其中所有的数字字符( 09 ),将其转换为一个十进制整数输出。 分析:数组长度取上限10以 n 做为输入结束符123 =123例7-13 字符串转换123 =123n = 0; for ( i = 0; si != 0; i+ ) if ( si = 0 ) n = n * 10 + (si - 0);0 1 2 3 s1 2 3 0 ? ?i sisi-001112223330n = n*10+(si-0)0*10+1 = 1 1*10+2 =1

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论