“铺张浪费”的数组
用选择法对10个整数排序。
#include <stdio.h>
int main( void )
{int i,j,min,temp,a[11];
printf("enter data:\n");
for(i=1;i<=10;i++)
{ printf("a[%d]=",i);
scanf("%d",&a[i]);
}
printf("\n");
printf("The orginal numbers:\n");
for(i=1;i<=10;i++)
printf("%5d",a[i]);
printf("\n");
for(i=1;i<=9;i++)
{ min=i;
for(j=i+1;j<=10;j++)
if(a[min]>a[j])min=j;
temp=a[i]; //以下3行将a[i+1]~a[10]中最小值与a[i]对换
a[i]=a[min];
a[min]=temp;
}
printf("\nThe sorted numbers:\n");
for(i=1;i<=10;i++)
printf("%5d",a[i]);
printf("\n");
return0;
}
这道题目要求对10个整数排序,那么定义一个具有10个整数类型元素的数组来存储这10个整数就足够了。可是代码中却出乎寻常地定义了一个具有11个元素的数组:
int a[11];
这种不上路子的写法在初学者当中很常见。其原因可能有两种,一种可能是受其他语言(比如BASIC)的影响,另一种可能是一下子还不能适应或接受C语言数组元素下标从0开始的特点。这从代码中的
for(i=1;i<=10;i++)
其实两种情况都可以归结为一点:没学会或不熟悉如何从0开始计数。
然而,C语言的数组元素的下标就是从0开始的,这一点无法改变。如果要学好C语言,无论感情或能力上是否能接受这一点都必须要接受这条规则。作为C程序员不懂得如何从0开始计数是说不过去的,甚至作为一般的IT业人员,不懂得从0开始计数也是说不过去的。因为计算机中的计数方式和日常生活常见的计数方式最显著的差异恰恰就在这里。
“人们对于不熟悉的东西,都是惯于留有余地的,这在正常情况都是很好的策略。然而,这里的问题是这正表明了人们对事情的把握还不精确,对于软件开发来说,这个就是Bug滋生的温床。”
在写C代码的时候,如果程序需要存储10个int类型元素的数组,就应该定义:
int a[10];
和前面样本代码中的11相比,这里的10写得有根有据,它表示的就是数组具有10个元素。如果对数组进行遍历(逐个访问每个元素),常规的写法是
for( i = 0 ; i < 10 ; i ++ ) { //读或写下标为i的数组元素 }
因此,前面的题目的代码应该这样写:
#include <stdio.h> int main( void ) { int a[10] , i , j ; printf("enter data:\n"); for( i = 0 ; i < 10 ; i++ ) { printf("a[%d]=" , i ); scanf("%d" , &a[i] ); } printf("\nThe orginal numbers:\n"); for( i = 0 ; i < 10 ; i++ ) printf("%5d",a[i]); for( i = 0 ; i < 10 ; i++ ) { int min = i ; //变量应该在离使用它最近的地方定义 for( j = i + 1 ; j < 10; j++ ) if( a[min] > a[j] ) min = j; { int temp = a[i]; a[i] = a[min]; a[min] = temp; } } printf("\nThe sorted numbers:\n"); for( i = 0 ; i < 10 ; i++ ) printf("%5d",a[i]); putchar('\n'); return 0; }
此外,样本中的注释“//以下3行将a[i+1]~a[10]中最小值与a[i]对换”也是错误的,实际上那3行是将a[i]~a[10]中最小值与a[i]对换。
当然,如果能把代码中的10用符号常量表示更好,但这属于另外的问题。