我正在做一个过去的考试问题,我被要求描述下面的c代码实现了什么,并用有意义的变量名称和良好的编程实践重写它。
代码如下:
void h(int ** a, int b){
for(int x=1; x<=b; x++)
for(y=1; y<=b; y++)
a[x-1][y-1]= (i/j)*(j/i);
}
我不明白这段代码是如何工作的:
1)y永远不会在for循环中声明。
2)如果i和j未被声明,i和j的算法对我来说没有意义。
我原本以为这是一个摄入量,而我和j只是x和y。但如果是这样的话,与我已经完成的任何其他问题相比,这个问题会非常容易。
答案 0 :(得分:4)
该代码可能用于创建一个单位矩阵,其前导对角线为1,其他位置为0。
该代码的Fortran等价物被用作Kernighan和Plauger在经典Elements of Programming Style中的第一个坏代码示例。
在内存中工作,Fortran代码大致是:
DO 10 I = 1, N
DO 10 J = 1, N
10 A(I,J) = (I/J)*(J/I)
(可能有两个标签,10和20说,以及一个或两个继续声明,但我认为就是这样。当时,第1-5列保留用于数字标签,第6列是延续指示符,程序占用第7-72列,第73-80列是可选的语句序列号。)
由于使用了y
但未声明,如果它被编译,y
必须是外部变量(全局变量或具有文件范围的变量:extern int y;
或{{1在函数外部或int y;
。
由于使用static int y;
和i
但未声明,如果编译,它们也必须是外部变量。鉴于j
和i
都未更改,相同的值(0或1,取决于j
)实际上是否分配给i != j
的每个元素。
实现相同(坏)算法的更接近'正确'的代码应该是:
a
当然,这不是很像C,但它确实避免了被零除的问题。但是,可以编写更简洁的代码:
void h(int **a, int b)
{
for (int x = 1; x <= b; x++)
for (int y = 1; y <= b; y++)
a[x-1][y-1] = (x/y)*(y/x);
}
应该将该功能重命名为更有意义的功能。
答案 1 :(得分:0)
要完成上面给出的答案,所有未声明的变量应该被理解为已在更大的范围内声明。如果你确定它确实是i
和j
(并且两者都是int)那么它将是零矩阵或者是1的马力(如果i = j)。