1. 数组越界
在C语言中,如果数组越界,编译器无法辨识。但是输出值未可知。所以最好用for循环来确定一个数组的边界,例如:
void main() { int a[3]={1,2,3}; printf("%d", a[4]); /*编译器无法辨别数组a[4]已经越界*/ }
正确的是:
void main() { int i, a[3]={1,2,3}; for (i=0,i<3;i++) { printf("%d", a[i]); } }
2. 二维数组与for循环
二维数组就像是一个平面的长宽。一维是列,二维是行,例如: a[3][2]。C语言中,都是通过for循环遍历二维数组。
3. 数组和 static static int a[3][4]={{1}, {0,6}, {0,0,11}};
如果没有static,则a[0][1] ~ a[0][3]的值是不确定的,如果加上static, 缺省的值会用0补充。例如:int a[2][3]={{1,2}, {4}}。
4. 对所有元素赋初值,一维长度可以省略,但二维长度不能省略。
对所有元素都赋初值(即没有一位元素是省略的,像例3一样),则数组的一维长度可以省略,但二维长度不能省略。
例如:static int a[3][4]={1,2,3,4,5,6,7,8,9,10,11,12}; 可以写成 static int a[][4]={1,2,3,4,5,6,7,8,9,10,11,12};
注意:在声明然后赋初值的语句中,下标里的数字是数组的长度,和后面提取数组元素所用的数值是不同的,例如:
int a[3]={1,2,3}; /* 这里3是数组的长度,但是第一位元素还是从a[0]开始计算的*/ printf("%d", a[2]); /* 所以这里a[2]是数组最高位的数值*/
5. 多维数组习题
1 /* File: multi_array.c 2 *------------------ 3 * 在二维数组a[3][4]中选出各行最大的元素组成一个一维数组b[3], 4 * 并输出数组b。 5 */ 6 #include <stdio.h> 7 void main() 8 { 9 int a[][4]={25, 88, 69, 72, 33, 29, 78, 96, 9, 54, 48, 90}; 10 int i, j, b[3]; 11 int m; 12 for (i=0;i < 3;i++) { 13 b[i] = a[i][0]; /* 把列数组的第一个值赋给b[i]*/ 14 for (j=1;j < 4;j++) { 15 if (b[i] < a[i][j]) { 16 b[i]=a[i][j]; /*遍历列数组,如果有比b[i]大的,就赋值给它*/ 17 } 18 } 19 20 printf("%d ", b[i]); 21 } 22 }
1 /* File: bignum.c 2 *------------------ 3 * 4 */ 5 #include <stdio.h> 6 void main() 7 { 8 int a[3][4]; 9 int i, j,m[3]; 10 /* 输入3X4的矩阵*/ 11 for (i=0;i<3;i++) 12 for (j=0;j<4;j++) 13 scanf("%d", &a[i][j]); 14 /*找到最大的值,并记录行列号码*/ 15 m[0]=a[0][0]; 16 for (i=0;i<3;i++) { 17 for (j=0;j<4;j++) { 18 if (m[0]<a[i][j]) { 19 m[0]=a[i][j]; 20 m[1]=i;m[2]=j; 21 } 22 } 23 } 24 printf("the big num is %d\n", m[0]); 25 printf("and it locates at %d line and %d row\n", m[1]+1, m[2]+1); 26 }
对a[4][4]矩阵按列排序。
for (j=0;j<3;j++) { for (k=j+1;k<4;k++) { t=a[j][i]; a[j][i]=a[k][i]; a[k][i]=t; } }
以上的遍历相当与每一个j元素都与其后的所有元素比较,如果发现比j元素小的,就替换。然后在比较j+1个元素。这样的排序方法非常通用。
两两相加的算法就是这样简单
for (i=0;i<9;i++) a[i]=x[i]+x[i+1];
6. 选择排序法
实例:
1 /* File: ttt.c 2 *------------------ 3 *选择法排序 4 *把一个长度为5的数组排序 5 */ 6 #include <stdio.h> 7 void main() 8 { 9 int a[]={23,43,12,44,11}; 10 int m, i, j; 11 /*先输出数组*/ 12 for (i=0;i<5;i++) printf("%d ", a[i]); 13 printf("\n"); 14 /*选择法排序*/ 15 for (i=5;i>0;i--) 16 for (j=0;j<i+1;j++) 17 if (a[j]>a[j+1]) { 18 m=a[j];a[j]=a[j+1];a[j+1]=m; 19 } 20 /*再输出数组*/ 21 for (i=0;i<5;i++) printf("%d ", a[i]); 22 }
一个循环减小,一个循环增大,在排序中经常用到。两值替换只能让一个最大值冒泡到最末,或最始。
7. 数组遍历,从行到列。也可以从列到行。
5例里,i是行下标,j是列下标。但是实际上循环也可以从列下标开始。例如如下的例子,按列求和。
1 /* File: average.c 2 *------------------ 3 * 4 */ 5 #include <stdio.h> 6 void main() 7 { 8 int a[5][3]; 9 int i, j; 10 float m=0, n=0; 11 for (i=0;i < 5;i++) 12 for (j=0;j < 3;j++) 13 scanf("%d", &a[i][j]); 14 /* 计算每名学生的平均分*/ 15 for (i=0;i < 5;i++) { 16 for (j=0;j < 3;j++) { 17 m+=a[i][j]; 18 } 19 printf("%f ", m/3.0); 20 m=0; 21 } 22 printf("\n"); 23 /* 计算每门课程的平均分*/ 24 for (j=0;j < 3;j++) { 25 for (i=0;i < 5;i++) { 26 n+=a[i][j]; 27 } 28 printf("%f ", n/5.0); 29 n=0; 30 } 31 printf("\n"); 32 }
注释:在有除法的时候,变量最好使用float。
8. printf() 不能直接输出数组,字符串常量除外。
不要用%s输出char a[]={'a', 'b', 'c', 'd'}的字符串数组。除非 char a[]={'a', 'b', 'c', 'd', '\0'} 或者 char b[4]={'a', 'b', 'c', 'd'} 或者 char b[10]={'a', 'b', 'c', 'd'} 或者 char a[]="abcd"。
9. 二维数组命令行输入问题
int a[3][2]; int i, j; for (i=0; i < 3; i++) for (j=0; j < 2;j++) scanf("%d", &a[i][j]);
就如同
int a[][4]={25, 88, 69, 72, 33, 29, 78, 96, 9, 54, 48, 90};
一样赋初值。不必考虑换行和空格给数组分配带来意想不到的错误。
来源:https://www.cnblogs.com/nathaninchina/archive/2012/04/12/c_notebook1.html