/**************************020 二维数组*************************************
* 打印出一个魔方阵,所谓魔方阵指的是每一行、每一列以及对角线之和均相等。
* 方阵排列规则:
* ⑴将1放在第一行中间一列;
* ⑵从2开始直到n×n止各数依次按下列规则存放;每一个数存放的行比前一个数的行数减1,列数加1(例如上面的三阶魔方阵,5在4的上一行后一列);
* ⑶如果上一个数的行数为1,则下一个数的行数为n(指最下一行);例如1在第一行,则2应放在最下一行,列数同样加1;
* ⑷当上一个数的列数为n时,下一个数的列数应为1,行数减去1。例如2在第3行最后一列,则3应放在第二行第一列;
* ⑸如果按上面规则确定的位置上已有数,或上一个数是第一行第n列时,则把下一个数放在上一个数的下面。例如按上面的规定,4应该放在第1行第2列,但该位置已经被占据,所以4就放在3的下面;
* C语言精彩编程百例,第20 */
#include <stdio.h>
void main()
{
int array[16][16];
int i,j,k,m,n;
m=1;
while(m==1)
{
printf("请输入n(0<n<15),n是奇数\n");
scanf("%d",&n);
if((n!=0)&&(n<=15)&&(n%2!=0))
{
printf("矩阵阶数是 %d\n",n);
m=0;
}
}
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
array[i][j]=0;
j=n/2+1;
array[1][j]=1;
for(k=2;k<=n*n;k++)
{
i=i-1;
j=j+1;
if((i<1)&&(j>n))
{
i=i+2;
j=j-1;
}
else
{
if(i<1) i=n;
if(j>n) j=1;
}
if(array[i][j]==0)
array[i][j]=k;
else
{
i=i+2;
j=j-1;
array[i][j]=k;
}
}
for(i=1;i<=n;i++)
{
for(j=1;j<=n;j++)
printf("%5d",array[i][j]);
printf("\n");
}
}
对应的汇编
.file "020.c"
.def ___main; .scl 2; .type 32; .endef
.text
LC0:
.ascii "\307\353\312\344\310\353n(0<n<15),n\312\307\306\346\312\375\12\0"
LC1:
.ascii "%d\0"
LC2:
.ascii "\276\330\325\363\275\327\312\375\312\307 %d\12\0"
LC3:
.ascii "%5d\0"
LC4:
.ascii "\12\0"
.align 2
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
pushl %ebp
movl %esp, %ebp
subl $1064, %esp #光这个二位数组就站了16*16*4的空间
andl $-16, %esp
movl $0, %eax
movl %eax, -1056(%ebp)
movl -1056(%ebp), %eax
call __alloca
call ___main
movl $1, -1048(%ebp) #m=1
L4:
cmpl $1, -1048(%ebp) # m==1
je L6
jmp L5
L6:
subl $12, %esp # printf("请输入n(0<n<15),n是奇数\n");
pushl $LC0
call _printf
addl $16, %esp
subl $8, %esp #scanf("%d",&n);
leal -1052(%ebp), %eax
pushl %eax
pushl $LC1
call _scanf
addl $16, %esp
cmpl $0, -1052(%ebp) # n!=0
je L4
cmpl $15, -1052(%ebp) # n<=15
jg L4
movl -1052(%ebp), %eax # n是奇数
andl $1, %eax
testl %eax, %eax
je L4
subl $8, %esp
pushl -1052(%ebp) # printf("矩阵阶数是 %d\n",n);
pushl $LC2
call _printf
addl $16, %esp
movl $0, -1048(%ebp)
jmp L4
L5:
movl $1, -1036(%ebp) # i=1
L8:
movl -1036(%ebp), %eax # i<=n
cmpl -1052(%ebp), %eax
jle L11
jmp L9
L11:
movl $1, -1040(%ebp) # j=1
L12:
movl -1040(%ebp), %eax # j<=n
cmpl -1052(%ebp), %eax
jle L15
jmp L10
L15:
movl -1036(%ebp), %eax # eax=i
sall $4, %eax # eax=eax*16 (16是每行元素个数)
addl -1040(%ebp), %eax # eax=j+i*16
movl $0, -1032(%ebp,%eax,4) # [ebp+eax*4-1032]=[ebp+(j+i*16)*4-1032] (4是 int占4个字节)
leal -1040(%ebp), %eax # j++
incl (%eax)
jmp L12
L10:
leal -1036(%ebp), %eax # i++
incl (%eax)
jmp L8
L9:
movl -1052(%ebp), %edx # n
movl %edx, %eax # eax=edx
sarl $31, %eax #算术右移,左侧用原符号位补齐
shrl $31, %eax #逻辑右移,左侧用0补齐,在最低位保留原来的符号位
leal (%eax,%edx), %eax # eax =eax + 原来的符号位
sarl %eax # eax/2
incl %eax
movl %eax, -1040(%ebp) # j=n/2+1
movl -1040(%ebp), %eax # eax=j
movl $1, -968(%ebp,%eax,4) # [ebp+j*4-968]=[ebp+(j+1*16)*4-1032]=array[1][j] =1
movl $2, -1044(%ebp) # k=2
L16:
movl -1052(%ebp), %eax # eax=n
imull -1052(%ebp), %eax # eax=n*n
cmpl %eax, -1044(%ebp) # 比较k和n*n
jle L19
jmp L17
L19:
leal -1036(%ebp), %eax # eax= &i
decl (%eax) # i--
leal -1040(%ebp), %eax # eax=&j
incl (%eax) # j++
cmpl $0, -1036(%ebp) # i 和 1-1 比较
jg L20
movl -1040(%ebp), %eax # eax =j
cmpl -1052(%ebp), %eax # j 和 n 比较
jle L20
leal -1036(%ebp), %eax # eax =&i
addl $2, (%eax) # i =i+2
leal -1040(%ebp), %eax # eax =&j
decl (%eax) # j=j-1
jmp L21
L20:
cmpl $0, -1036(%ebp) # i 和 1-1 比较
jg L22
movl -1052(%ebp), %eax # eax =n
movl %eax, -1036(%ebp) # i=n
L22:
movl -1040(%ebp), %eax # eax=j
cmpl -1052(%ebp), %eax # j 和 n 比较
jle L21
movl $1, -1040(%ebp) # j=1
L21:
movl -1036(%ebp), %eax # eax =i
sall $4, %eax # eax =i*16
addl -1040(%ebp), %eax # eax=i*16+j
cmpl $0, -1032(%ebp,%eax,4) # array[i][j]==0
jne L24
movl -1036(%ebp), %eax # eax =i
sall $4, %eax # eax = i*16
movl %eax, %edx # edx = i*16
addl -1040(%ebp), %edx # edx = i*16+j
movl -1044(%ebp), %eax # eax = k
movl %eax, -1032(%ebp,%edx,4) # array[i][j]==k
jmp L18
L24:
leal -1036(%ebp), %eax # eax =&i
addl $2, (%eax) # i =i+2
leal -1040(%ebp), %eax # eax =&j
decl (%eax) # j=j-1
movl -1036(%ebp), %eax # eax =i
sall $4, %eax # eax=i*16
movl %eax, %edx # edx=i*16
addl -1040(%ebp), %edx # edx=i*16+j
movl -1044(%ebp), %eax # eax=k
movl %eax, -1032(%ebp,%edx,4) # array[i][j]==k
L18:
leal -1044(%ebp), %eax # eax=&k
incl (%eax) # k++
jmp L16
L17:
movl $1, -1036(%ebp) # i=1
L26:
movl -1036(%ebp), %eax # eax=i
cmpl -1052(%ebp), %eax # 比较 i 和 n
jle L29
jmp L3
L29:
movl $1, -1040(%ebp) # j=1
L30:
movl -1040(%ebp), %eax # eax=j
cmpl -1052(%ebp), %eax # 比较j和n
jle L33
jmp L31
L33:
subl $8, %esp # printf("%5d",array[i][j]);
movl -1036(%ebp), %eax # eax =i
sall $4, %eax # eax =i*16
addl -1040(%ebp), %eax # eax =j
pushl -1032(%ebp,%eax,4) # array[i][j]
pushl $LC3
call _printf
addl $16, %esp
leal -1040(%ebp), %eax # j++
incl (%eax)
jmp L30
L31:
subl $12, %esp #printf("\n");
pushl $LC4
call _printf
addl $16, %esp
leal -1036(%ebp), %eax
incl (%eax)
jmp L26
L3:
leave
ret
.def _scanf; .scl 2; .type 32; .endef
.def _printf; .scl 2; .type 32; .endef
二维数组特色的地方:
movl -1036(%ebp), %eax # eax=i
sall $4, %eax # eax=eax*16 (16是每行元素个数)
addl -1040(%ebp), %eax # eax=j+i*16
movl $0, -1032(%ebp,%eax,4) # [ebp+eax*4-1032]=[ebp+(j+i*16)*4-1032] (4是 int占4个字节)