数组
本节我们将用C写一个小程序随机生成10个数,并对其进行排序。我们将使用一种新的变量结构:数组。
借助数组可以声明并使用一组同类型的数据。比如您现在需要创建五个整数。一种办法是直接进行声明:
int a, b, c, d, e;
这当然可以,但如果您需要一千个整数呢?一种更好的办法是声明一个包含五个整数的数组:
int a[5];
这个数组中的五个整数可以分别使用下标进行访问。C中所有数组的下标都是从零到n-1。所以int a[5];包含了五个元素。例如:
int a[5];
a[0] = 12;
a[1] = 9;
a[2] = 14;
a[3] = 5;
a[4] = 1;
使用下标访问数组带来的一个好处是可以用循环来遍历下标。例如,下面的代码把数组的所有元素初始化为零:
int a[5];
int i;
for (i=0; i<5; i++)
a[i] = 0;
下面的代码将数组元素按顺序初始化,然后打印输出:
#include
int main()
{int a[5];int i;for (i=0; i<5; i++)
a[i] = i;for (i=0; i<5; i++)
printf("a[%d] = %dn", i, a[i]);}
在C中到处都会用到数组。下面的代码是一种使用数组的常见情形。请打开编辑器并录入以下代码:
#include
#define MAX 10
int a[MAX];
int rand_seed=10;
/* 摘自 K&R
- 返回0-32767之间一个随机数字。*/
int rand()
{rand_seed = rand_seed * 1103515245 +12345;return (unsigned int)(rand_seed / 65536) % 32768;}
int main()
{int i,t,x,y;/* fill array */
for (i=0; i < MAX; i++){a[i]=rand();printf("%dn",a[i]);}
return 0;}
这段代码引入了几个新概念。#define声明了一个名为MAX的常量并让它等于10。为在代码中醒目起见,常量名习惯上全用大写字母。int a[MAX];这行告诉我们在C中如何声明整型数组。注意,数组声明出现的位置决定了它是整个程序的全局变量。
下面的一行int rand_seed=10也声明了一个全局变量,名为rand_seed。它在每次程序开始时被初始化为10,作为下面随机数生成代码的初始种子。实际中随机数发生器的种子应该以一个随机数作为初值,如系统时间。本例中的rand函数,在每次程序运行时都会给出相同的随机数序列。
int rand()这行代码是一个函数声明:rand函数没有参数且返回一个整数。后面我们会学习更多关于函数的知识。下面的四行是rand函数的实现,我们可以暂时忽略。
主函数没什么特别的。先声明了四个整型变量,接下来的for循环用10个随机数填充数组。注意数组a包含了10个独立的整数。您可以用方括号指明具体元素。例如a[0]代表数组中的第一个整数,a[1]代表第二个,以此类推。用/*开始并用*/结束的行称为注释。编译器完全忽略注释行。您可以把程序说明(自己看或供其他程序员阅读)放在注释中。
现在请用下面的代码替换这里很快会加入新内容那行注释:
/* 将数组用冒泡法排序 */
for (x=0; x < MAX-1; x++)
for (y=0; y < MAX-x-1; y++)
if (a[y] > a[y+1])
{t=a[y];a[y]=a[y+1];a[y+1]=t;}
/* 打印排序后的数组 */
printf("--------------------n");
for (i=0; i < MAX; i++)
printf("%dn",a[i]);
以上代码将随机数排序,并按顺序打印。每次运行程序您都会得到同样的结果。要想改变参加排序的值,在每次运行程序前请改变rand_seed的值。
要真正读懂这段代码的简单办法只有一个,就是“手动”执行一下程序。为简单起见令MAX等于4。准备一张纸并假设您自己就是计算机。在纸上画出数组,然后填入四个随机、无序的数字。现在按照代码中的排序部分一边逐行执行,一边在纸上记录执行过程。您会发现每次执行完内层循环后,较大的那些数被推向数组尾部,而较小的那些数则向数组首部靠拢。
动手一试
在代码前一部分,试将填充数组的for循环缩减为一行代码。请确保结果和原来的程序相同。
将冒泡排序的代码提出来建立它自己的函数。函数头是void bubble_sort()。然后将冒泡排序使用的变量也移入函数变成局部变量。因为数组是全局的,所以不需要传递参数。
改变随机数种子的初始值。
C 常见错误
C不提供边界检查。所以如果您的数组指标越界了,C不会有任何提示。程序会最后崩溃或输出无意义的数据。
即使不传递参数,函数调用也要包含()。例如,C接受x=rand;,但这不能完成函数调用,而是把rand函数的内存地址赋值给了x。必须写成x=rand();才行。