douzhi7754 2018-02-02 12:13
浏览 56
已采纳

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

I'm currently porting some C (as part of a wider R package) to Go. Because the C in question is used as part of an R package, it has to make extensive use of pointers. The R package is changepoint.np.

As somebody who isn't experienced in C, I've managed to understand most of it. However, the following code has me a bit stumped:

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)));
    }
}

Specifically, this line (in the inner for loop):

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

I've read various pages and Stackoverflow questions/answers about C pointers and arrays, and if I understood them correctly, this line would be translated into 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]

Where n is the number of columns (*n in the C code), and nquantiles is the number of rows (*nquantiles in the C code).

However this produces an error (index out of range, obviously) where the original code does not.

Where am I going wrong?

  • 写回答

1条回答 默认 最新

  • 普通网友 2018-02-02 12:25
    关注

    In the line:

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

    I see two strange things:

    1) Where did the n in isum*n come from? The n is not part of the orginal expression.

    2) nquantiles is a pointer in the original code so it can't be used that way.

    In C it should rather be:

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

    The original C code treats a (contiguous) memory area as a 2D matrix. Like this:

    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
    

    That is equivalent to:

    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 ...;
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)