我目前正在将一些 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 为:
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
)。
然而,这会产生错误(显然索引超出范围),而原始代码不会。
我哪里错了?
最佳答案
行内:
sumstatout[isum] = sumstat[isum*n + nquantiles*j] - sumstat[isum*n + nquantiles*0]
我看到两件奇怪的事情:
1)isum*n
中的n
是从哪里来的? n
不是原始表达式的一部分。
2) nquantiles
在原代码中是一个指针,所以不能这样使用。
在 C 中它应该是:
sumstatout[isum] = sumstat[isum + *nquantiles*j] - sumstat[isum]
原始 C 代码将(连续的)内存区域视为二维矩阵。像这样:
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 ...;
关于c - 将 C 移植到 Go,难以理解一些指针语法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48582434/