【问题标题】:Pointer Arithmetic equivalence指针算术等价
【发布时间】:2022-01-23 19:13:32
【问题描述】:

我已经用 C 编写了这个函数。

这两个语句是等价的吗?

void dot_prod(float *A, int m, float *B, float *C) {
    int i, j, z, k;
    for (i = 0; i < m; i++) {
        for (j = 0; j < m; j++) {
            for (k = 0; k < m; k++) {
                C[i * m + k] += A[i * m + j] * B[m * j + k];
                //*(C + i * m + k) += *(A + i * m + j) * (*(B + m * j + k)); // is equivalent?
            }
        }
    }
}

C[i * m + k] += A[i * m + j] * B[m * j + k]

相当于

*(C + i * m + k) += *(A + i * m + j) * (*(B + m * j + k))?

【问题讨论】:

    标签: c pointers


    【解决方案1】:

    差不多了。

    C[i * m + k] += A[i * m + j] * B[m * j + k]
    

    等价于

    *(C + (i * m + k)) += *(A + (i * m + j)) * (*(B + (m * j + k)))
    

    这与没有额外括号的情况不同,因为索引中的加法可能会溢出,在这种情况下,指针/整数加法不一定是关联的,具体取决于int 和指针的大小。

    【讨论】:

    • 我们可以说后一种表达方式更安全吗?
    • @tail 不,它们完全相同。两者都不安全。但是第一个更清楚地说明了正在发生的事情,这也是避免错误的好方法。
    • 如果您在原始代码中将int 替换为size_t,所有版本都会变得更安全——size_t 保证对于任何索引都足够大(int 可能不会)并且是无符号的,所以也有干净的溢出语义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-28
    • 2012-07-27
    • 1970-01-01
    相关资源
    最近更新 更多