在C语言中,将数组中的每个元素乘以一个数字

10

我正在优化我的一些C代码,它比下面的片段要大得多。作为一个Python程序员,我想知道是否可以像我下面所做的那样简单地将整个数组乘以一个数字。

显然,以下方法并不起作用。是否有其他方法可以达到相同的效果?还是我必须像在for循环中那样遍历整个数组?

void main()
{
    int i;
    float data[] = {1.,2.,3.,4.,5.};

    //this fails
    data *= 5.0;

    //this works
    for(i = 0; i < 5; i++) data[i] *= 5.0;

}

你必须遍历整个数组,没有其他选择。 - Raghu Srikanth Reddy
4个回答

10

没有捷径,你必须逐个遍历数组中的每个元素。

但是请注意,在您的示例中,如果您同时将数据和乘数使用 int 而不是 float,则可以实现加速。


4
谢谢!是的,我的真实数据是浮点数。我只是懒得在这里写出来。 - seb

8
如果您愿意,可以通过BLAS(Basic Linear Algebra Subprograms)实现自己想要的内容,该程序包已进行了优化。这不是C标准,而是一个需要您自己安装的软件包。
以下是实现您所需功能的示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main () {            
    int limit =10;
    float *a =  calloc( limit, sizeof(float));
    for ( int i = 0; i < limit ; i++){
        a[i] = i;
    }
    cblas_sscal( limit , 0.5f, a, 1); 

    for ( int i = 0; i < limit ; i++){
        printf("%3f, " , a[i]);
    }
    printf("\n");
}

函数的名称不太明显,但是阅读指南后,您可能会开始猜测 BLAS 函数的作用。例如,sscal() 可以拆分为 s 表示单精度和 scal 表示缩放,这意味着该函数适用于浮点数。而双精度浮点数的相同函数称为 dscal()
如果您需要使用常量对向量进行缩放并将其添加到另一个向量中,则 BLAS 也有一个函数可供使用:
saxpy()
s      a x p y
float  a*x + y
y[i] += a*x

你可能已经猜到了,还有一个 daxpy() 函数,它适用于 double 类型。


有趣!我会研究一下。 - seb
1
如果您在Ubuntu上工作,我可以补充一下。我在安装时遇到了问题,但解决方法是: sudo aptitude install libblas-dev libopenblas-dev libopenblas-base sudo ldconfig - cybrhuman

1
我担心在C语言中,你必须使用for(i = 0; i < 5; i++) data[i] *= 5.0;。Python允许使用更多的“快捷方式”,但在C语言中,你必须访问每个元素,然后操作这些值。
使用for循环是完成对数组进行操作的最短方法。
编辑:如果有大量数据,有更有效率(从运行时间上)的方法将5乘以每个值。例如,请查看循环平铺。

我不确定我会建议手动展开循环。如果你告诉编译器优化速度,任何半靠谱的编译器都会适当地优化你的循环,不是吗? - simonc
我知道循环展开和-O标志,但我仍在尝试在此基础上进行优化 ;-). - seb

-3
data *= 5.0;

这里的data是一个常量数组的地址。 如果你想要将该数组中的第一个值乘以某个数,请使用以下的*运算符。

*data *= 5.0;

你是不是想说 *=?你的代码展示了如何将5加到第一个元素,而不是将其乘以5。 - simonc

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接