以下C代码实现了什么?

时间:2014-04-21 18:53:12

标签: c

我正在做一个过去的考试问题,我被要求描述下面的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。但如果是这样的话,与我已经完成的任何其他问题相比,这个问题会非常容易。

2 个答案:

答案 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但未声明,如果编译,它们也必须是外部变量。鉴于ji都未更改,相同的值(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)

要完成上面给出的答案,所有未声明的变量应该被理解为已在更大的范围内声明。如果你确定它确实是ij(并且两者都是int)那么它将是零矩阵或者是1的马力(如果i = j)。