将C移植到Go,无法理解某些指针语法

时间:2018-02-02 12:13:02

标签: c arrays pointers go

我目前正在将一些C(作为更广泛的R包的一部分)移植到Go。因为有问题的C被用作R包的一部分,所以它必须广泛使用指针。 R包是changepoint.np

作为一个没有C经验的人,我设法了解了大部分内容。但是,下面的代码让我有点难过:

double *sumstat; /* matrix in R: nquantile rows, n cols */
int *n;          /* length of data */
int *minseglen;  /* minimum segment length */
int *nquantiles; /* num. quantiles in empirical distribution */

...[abridged for brevity]...

int j;
int isum;
double *sumstatout;
sumstatout = (double *)calloc(*nquantiles,sizeof(double));
for (j = *minseglen; j < (2*(*minseglen)); j++) {
    for (isum = 0; isum < *nquantiles; isum++) {
        *(sumstatout+isum) = *(sumstat+isum+(*nquantiles*(j))) - *(sumstat+isum+(*nquantiles*(0)));
    }
}

具体来说,这一行(在内部for循环中):

*(sumstatout+isum) = *(sumstat+isum+(*nquantiles*(j))) - *(sumstat+isum+(*nquantiles*(0)));

我已经阅读了有关C指针和数组的各种页面和Stackoverflow问题/答案,如果我理解正确,这一行将被翻译为Go as:

n := len(data)
nquantiles := int(4 * math.Log(float64(len(data))))

sumstatout[isum] = sumstat[isum*n + nquantiles*j] - sumstat[isum*n + nquantiles*0]

其中n是列数(C代码中的*n),nquantiles是行数(C代码中的*nquantiles)。

然而,这会产生错误(索引超出范围,显然),原始代码不会。

我哪里错了?

1 个答案:

答案 0 :(得分:3)

在行中:

sumstatout[isum] = sumstat[isum*n + nquantiles*j] - sumstat[isum*n + nquantiles*0]

我看到两件奇怪的事情:

1)n中的isum*n来自哪里? n不是原始表达式的一部分。

2)nquantiles是原始代码中的指针,因此不能以这种方式使用。

在C中它应该是:

sumstatout[isum] = sumstat[isum + *nquantiles*j] - sumstat[isum]

原始C代码将(连续的)内存区域视为2D矩阵。像这样:

int i, j;
int cols = ..some number..;
int rows = ..some number..;
double* matrix = malloc(cols * rows * sizeof *matrix);
for (i = 0; i < rows; ++i)
    for (j = 0; j < rows; ++j)
        *(matrix + i*cols       +       j) = ... some thing ...;
                   ^^^^^^              ^^^
                 Move to row i        Move to column j

这相当于:

int i, j;
int cols = ..some number..;
int rows = ..some number..;
double matrix[rows][cols];
for (i = 0; i < rows; ++i)
    for (j = 0; j < cols; ++j)
        matrix[i][j] = ... some thing ...;