我目前正在将一些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
)。
然而,这会产生错误(索引超出范围,显然),原始代码不会。
我哪里错了?
答案 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 ...;