二维数组的排列: 引用二维数组元素、对二维数组进行输入和输出,i 作为行下标, j 作为列下标,程序如下: #include <stdio.h> int main() { int a[2][3],i,j; printf("please intput by line:\n"); for(i=0;i<2;i++) for(j=0;j<3;j++) scanf("%d",&a[i][j]); printf("This is the latest putout:\n"); for(i=0;i<2;i++) { for(j=0;j<3;j++) printf("%4d",a[i][j]); printf("\n"); } return 0; } --------------------------------------------------------------------------------- 解析: 1. 无关于输入的方式,而在于 2 * 3 == 6 故里面有6个元素,当输入满6个的时候,自动输出。 2. 输入的方式有下面的几种,结果都按二维数组的方式来进行排列,i为行下标,j作为列下标 -------------------------------------------- please intput by line: 1 2 3 10 20 30 This is the latest putout: 1 2 3 10 20 30 --------------------------- please intput by line: 1 2 3 4 5 6 This is the latest putout: 1 2 3 4 5 6 ----------------------------- please intput by line: 1234567890 2 3 4 5 6 This is the latest putout: 1234567890 2 3 4 5 6 --------------------------------- please intput by line: 1 2 3 4 5 6 This is the latest putout: 1 2 3 4 5 6 ----------------------------- 3. 通过以上输入方式的对比就可以看出异同了。 总结: 1. 需要注意i为行下标,j作为列下标的循环输入,以及输出时的for嵌套语句 因为输入是先按行一个一个录入的,第一行满了就会继续进行第二行的录入。 输出的时候也是同样的,只是里面加入了换行,以保持输出数组的整齐性。 2. 如果要先进行,列录入,后进行,行录入,然后按行输出,秩序改写程序如下: #include <stdio.h> int main() { int a[2][3],i,j; printf("please intput by line:\n"); for(i=0;i<3;i++) for(j=0;j<2;j++) scanf("%d",&a[j][i]); //注意j为行下标 printf("This is the latest putout:\n"); for(i=0;i<2;i++) { for(j=0;j<3;j++) printf("%4d",a[i][j]); printf("\n"); } return 0; } ----------------------------------------------------------------------- 看结果,会完全不一样:(当然这是按列录入,按行输出) please intput by line: 1 2 3 4 5 6 This is the latest putout: 1 3 5 2 4 6 ----------------------------- 3. 如果要变成3行2列,则程序改写程序如下: #include <stdio.h> int main() { int a[3][2],i,j; printf("please intput by line:\n"); for(i=0;i<3;i++) for(j=0;j<2;j++) scanf("%d",&a[i][j]); printf("This is the latest putout:\n"); for(i=0;i<3;i++) { for(j=0;j<2;j++) printf("%4d",a[i][j]); printf("\n"); } return 0; } 其结果为: please intput by line: 1 2 3 4 5 6 This is the latest putout: 1 2 3 4 5 6 ----------------------------------------------------------------------- 4. 同样如果要成为按列录入,则如下所示: #include <stdio.h> int main() { int a[3][2],i,j; printf("please intput by line:\n"); for(i=0;i<2;i++) for(j=0;j<3;j++) scanf("%d",&a[j][i]); printf("This is the latest putout:\n"); for(i=0;i<3;i++) { for(j=0;j<2;j++) printf("%4d",a[i][j]); printf("\n"); } return 0; } 其结果为: please intput by line: 1 2 3 4 5 6 This is the latest putout: 1 4 2 5 3 6 --------------------------------------------------------------------- 二维数组与指针: 通过建立一个指针数组引用二维数组元素 int *p[3],a[3][2],i,j; for(i=0;i<3;i++)p[i] = a[i]; 这里等号右边的a[i]是常量,表示a数组每行的首地址,等号左边的p[i]是指针变量,循环执行的结果使p[0]、p[1]、p[2]分别指向a数组每行的开头,这时候数组p和数组a之间的关系如下图所示: 这样的话那么a数组元素a[i][j]的引用形式*(a[i]+j)就完全等价于*(p[i]+j) 即: *(p[i]+j) 等价于 *(a[i]+j) *(*(p+i)+j) 等价于 *(*(a+i)+j) (*(p+i))[j] 等价于 (*(a+i))[j] p[i][j] 等价于 a[i][j] 例子一: #include <stdio.h> int main() { int aa[3][3] = {{2},{4},{6}},i,*p = &aa[0][0]; for(i=0;i<2;i++) { if(i==0) aa[i][i+1] = *p + 1; else ++p; printf("%d",*p); } printf("\n"); return 0; } --------------------------------------------------------------- 其最后的结果为23 解析: 1. 当i=0时,aa[0][1]=*p+1=2+1=3 但是最后让输出的是*p的值,所以跟这里没有关系,所以*p = 2 2. 当i=1时,++p即是地址加1,即 p=aa[0][0]的地址加1就成为了aa[0][1],而又aa[0][1] = 3,故*p = 3 3. 所以最后的结果是23 例子二: #include <stdio.h> int main() { int a[3][4] = {1,3,5,7,9,11,13,15,17,19,21,23}; int (*p)[4] = a,i,j,k = 0; for(i=0;i<3;i++) for(j=0;j<2;j++)k+=*(*(p+i)+j); printf("%d\n",k); return 0; } [root@SLC-one c_test]# ./9.16 60 ----------------------------------------------------------- 其结果为60 解析: 1. 首先来看a[3][4]的初值排列,这里千万不要弄错。三行四列否则后面算出来的结果肯定会不一样。 1 3 7 9 9 11 13 15 17 19 21 23 --------------------- 2. k+=*(*(p+i)+j) 其实就等价于 k = k + *(p[i]+j) = k + p[i][j] = k + a[i][j] 3. 那么再由两次的for循环可以看出其实就是求 三行两列 的值的和即:1+3+9+11+17+19=60 4. 如果跟上面2后面的式子来算也是如此即: k = k + a[i][j] k = k + a[0][0] = 0+1 = 1 k = k + a[0][1] = 1+3 = 4 k = k + a[1][0] = 4+9 = 13 k = k + a[1][1] = 13+11 = 24 k = k + a[2][0] = 24+17 = 41 k = k + a[2][1] = 41+19 = 60 所以结果就是这么来的。 例子三: #include <stdio.h> void sub(int n, int uu[]) { int t; t = uu[n--]; t+=3*uu[n]; n++; if(t>=10) { uu[n++]=t/10; uu[n]=t%10; } else uu[n]=t; } int main(void) { int i,n,aa[10]={0}; scanf("%d%d%d",&n,&aa[0],&aa[1]); for(i=1;i<n;i++) sub(i,aa); for(i=0;i<=n;i++) printf("%d",aa[i]); printf("\n"); return 0; } [root@SLC-one c_test]# ./9.23 3 2 1 2721 ------------------------------------------------ 输入3 2 1其最终结果为2721 解析: 1. 这里题中一定要注意[n--]和[n++]因为他们都在用过自己本身的值之后才再次加1的 2. 所以解题如下: 当main函数中的第一个for循环的i=1时; 那么定义函数sub中n=1,而uu[]其实就是aa[] 则有: t=uu[1]=1; t=1+3*uu[0]=7; n=1; uu[1]=7即aa[1]=7; 当main函数中的第一个for循环的i=2时: 那么定义函数sub中n=2,而uu[]依然就是aa[] 则有: t=uu[2]=0; //因为在开始的时候有aa[10]={0}赋过初值 t=0+3*uu[1]=21; n=2; uu[2]=2.1; uu[3]=21%10=1; 最终因为是以%d来进行输入,所以aa[2]=2 aa[3]=1 3. 那么最终循环输出aa数组的前3个数组(包含第三个元素)元素依次为: aa[0] = 2 aa[1] = 7 aa[2] = 2 aa[3] = 1 所以最终的结果为2721 例子四: #include <stdio.h> int main() { int a[]={1,2,3,4,5,6,7,8,9,0},*p; p=a; printf("%x\n",p); printf("%x\n",p+9); return 0; }