{ int i, n;
char line[100]={'\0'};
printf("请输入选手人数:");
fgets(line,sizeof(line), stdin);
N=atoi(line);
if(N<=0) exit(-1);
if(isodd(N))
n=N+1;
else
n=N;
//schedule是行化的二维数组
schedule=(int *)calloc(n*n, sizeof(int));
A=(int **)calloc(n, sizeof(int *));
if(!schedule || A==NULL) exit(-2);
for(i=0;i<n;i++) //把A等价为二维数组
{
A[i]=schedule+i*n;
A[i][0]=i+1;//初始化这个数组的第一列
}
return;
}我得到的二维数组A只需要表示n*n或者n*(n-1)的表格,为什么schedule要分配n*n个int的空间?A不是还分配了n个int*吗?if(!schedule || A==NULL)这一句话又有什么用?还有最后初始化的结果就只能把数组第一列弄成1到n吗?
财富值不太多TAT,求谅解。
能逐句解释下这段函数的作用吗?有点急,这周就交报告的时候,还要给助教详细解释神马的
1、问:我得到的二维数组A只需要表示n*n或者n*(n-1)的表格,为什么schedule要分配n*n个int的空间?
答:因为这里A分配的实际上是n个指针,这n个指针确实有内存,但是它们所指的地方还未指定内存,所以要为schedule要分配n*n个int的空间,用来让A的n个指针去指。
还有,schedule是行化了的二维数组,你要访问第0行的0~n-1个元素倒还方便,直接schedule[0] ~ schedule[n-1]即可,但是你要访问比如说第二行的0 ~ n-1个元素就麻烦了,不能直接用schedule[2][0] ~ schedule[2][n-1],因为schedule是指向int的指针,它是一维的,不能这么写。而是schedule[2 * n + 0] ~ schedule[2 * n + n - 1]。
所以,为了方便使用数组的形式访问元素,将A到schedule进行了映射,A是指向指针的指针
A=(int **)calloc(n, sizeof(int *)); 所以可以A[i][j]。
映射方法A[i]=schedule+i*n;
再回头看看schedule[2 * n + 5]是不是被映射成了A[2][5]了?很方便吧。
我画了一个图,来标明映射关系
2、问:if(!schedule || A==NULL)这一句话又有什么用?
答:用来检查calloc内存是否分配成功。calloc若失败,返回NULL,所以!A和A==NULL其实是一样的。
3、问:还有最后初始化的结果就只能把数组第一列弄成1到n吗?
答:你要是想把每列都初始化,可以在写一个循环。比如:
for(i=0;i<n;i++)我这里举得例子,是把A初始化为每一行都是0~n-1。
4、补充一点,这里之所以用calloc分配内存,而不是用平常的schedule[100][100],是因为选手人数还未确定,所以必须要动态分配。
像1楼这种声明明显是错误的,不能在数组初始化维数中出现变量n,必须是常量或const类型。
还有,程序退出的时候,别忘了free掉两个分配的内存哦。
free(A);
free(schedule);