【问题标题】:Writing a C function sprod (n,x,y) that returns the scalar product of 2 1-D arrays of type float编写一个 C 函数 sprod (n,x,y),它返回 2 个浮点类型的一维数组的标量积
【发布时间】:2012-12-03 06:30:26
【问题描述】:

编写一个 C 函数,sprod (n,x,y),它返回 2 个浮点类型的一维数组的标量积。该函数将数组的大小 n(类型 int 变量)和指向每个数组第一个成员的指针 x 和 y 作为输入变量,并返回一个浮点结果。 main() 代码块需要调用 sprod 来计算矩阵乘积 a*b,其中浮点型矩阵 a 和浮点型向量 b 由 b=[1 1 1] 和 a=[1 2 3 4 5 6 7 8 给出9](其中 a 是一个 3x3 矩阵)。

我们可以在 f(;;) 循环中初始化 b,在双 for(;;) 循环中初始化 a(或者使用很多赋值语句)。矩阵乘积应该通过调用函数 sprod 来计算,以形成 a 的每一行与向量 b 的标量积;指向这些行的指针由 a[1]、a[2] 和 a[3] 给出。最后,还应该使用一个 for(;;) 循环来对结果标量产品求和,并使用 printf() 函数将结果打印到屏幕上。

结果应该是矩阵 a 的所有元素的总和。还应打印矩阵 a 和向量 b 的副本。我们将使用数字食谱 C 函数 matrix() 和 vector() 与 free_matrix() 和 free_vector() 来创建 a 和 b 作为动态定义的数组。

在编程方面,我是一个初学者,但我发现我真的很烂。这是我到目前为止所拥有的,当它被编译时它会像疯了一样炸毁(我知道有些东西被遗漏了)。我尝试使用 gdb 来调试它,但我也无法让它工作。任何帮助,将不胜感激。

# include <stdio.h>
# include "nrutil.h"
# include "nrutil.c"

void transp(float **a,int n);
float sprod(int n, float *x, float *y);
int main()
{
  int i,j;
  float var=0.0, sum=0.0, pro=0.0;
  float*b, **a;
  int n=3;
  float index;
  b=vector(0,n-1);
  a=matrix(0,n-1,0,n-1);

  printf("\nVector b\n");
  for(j=0;j<n;j++)
  {
    b[j]=1;
    printf("%.2f\n",b[j]);
  }
  for(i=0;i<n;i++)
  {
    for(j=0;j<n;j++);
    {
      var=var+1;
      a[i][j]=var;
    }
  }
  printf("\n Matrix a\n");
  for(i=0;i<n;i++);
  {
    for(j=0;j<n;j++);
    {
      printf("%.2lf",a[i][j]);
    }
    printf("\n");
  }
  printf("\nProduct of Matrix a and Vector b\n");

  for(i=0;i<n;i++);
  {
    pro=sprod(n,a[i],b);
    printf("%.2f\n",pro);
    sum+=pro;
  }
  printf("\n Sum of Product array\n");
  printf("%.2f\n\n", sum);
  free_ivector(index,0,n-1);
  free_matrix(a,0,n-1,0,n-1);

  return 0;
}

float sprod(int n, float *x, float *y)
{
  float scalar=0.0;
  int j=0;
  int sum=0;

  for(j=0;j<n;j++);
  {
    scalar+=x[j]*y[j];
  }
  return scalar;
 }

自从最初发布此代码以来,我已经改进了我的代码。现在它几乎可以工作了,我只是遇到了第 50 行 free_ivector 代码的问题。终端告诉我:“free_ivector”的参数 1 的类型不兼容。我不太确定那是什么意思。该代码采用大卫邓肯在下面第一个答案中建议的整体格式。

【问题讨论】:

  • 1.你的原型在哪里? 2. 你在代码行 11 中有一个右花括号,但你没有用任何东西填充 a[3,3]? 3. 对于没有任何论据的 lops?尝试帮助我们理解您的代码,进一步改进它! :)
  • @AlbertoBonsanto:不要使用作业标签。
  • @JonathanLeffler 谢谢,我不会再使用它了,但它看起来像一个家庭作业。
  • @AlbertoBonsanto:同意,但是The homework tag is now officially deprecated
  • 原型是什么意思?大括号是一个错误,我不确定 a[3,3] 应该放什么,所以我把它留空。你应该在这里定义矩阵吗?以“float i;”开头的代码部分(中间部分)是应该创建数组的地方。之后“浮动*索引,我;”创建向量 b。这两个上面的部分是主程序。你是什​​么意思没有参数的循环?我以为你可以通过使用 f(;;) 创建一个无限的 for 循环?我不太了解这个,所以这可能会尽可能地改进。

标签: c math


【解决方案1】:

对于那些对编程甚至只是 C 感到不舒服的人来说,这是一个有点困难的问题,因为它涉及指针和传递数组引用。不过,我认为您知道的足够多,可以查找所需的每个特定项目的示例,因此您的第一个目标(您可能知道)是将事情分解为子问题并单独解决它们(如果需要,还可以迭代) .由于您当前的代码可以在布局方面使用一些帮助,因此我已将问题陈述改编为您可以逐个处理的内容。用执行此操作的代码替换每个“TODO”注释,我相信你会完成的。

#include <stdio.h>
#include "nrutil.h"

float sprod(int n, float *x, float *y)
{
    float result = 0.0;
    // TODO: Calculate result (hint: for loop repeating n times,
    // and each iteration you'll update result)

    return result;
}

int main()
{
    // TODO: Create and initialize matrix A
    // TODO: Create and initialize matrix B
    // TODO: Print A and B
    // TODO: For each row of A, call sprod() with that row of A
    // and B as inputs, and save each sprod() result
    // TODO: Sum the results
    // TODO: Print the sum

    return 0; // (0 indicates success; if you were to have
              //  failure cases, you could return other values)
}

使用上述方法还有助于在进行时进行编译(因此,能够使用调试器)。使用 GDB 的绝对最低要求如下:

  • 使用 GCC -g 开关编译——即gcc -g myprog.c
  • gdb &lt;program name&gt;(程序名称通常默认为 a.exe 或 a.out)
  • break &lt;line number&gt;设置断点
  • run启动程序
  • n 下一条语句
  • quit退出

此外,如果是老师提供的,我认为原始问题陈述中还有一些内容有点令人困惑(如果只是您的释义,我在吹毛求疵):

  • for(;;) 会导致无限循环,除非您在其中使用 goto 语句(非常不典型)或 break 语句(有些不典型),这两种语句都不适用于此处。所以说“for循环”会更有意义。
  • 为了清楚起见,C 具有从零开始的索引,这意味着除非 matrix() 明确定义它,否则您的行将是 a[0]、a[1] 和 a[2](而不是 a[1 ]、a[2] 和 a[3])。

【讨论】:

  • 谢谢。这让我们更容易理解需要做什么。
【解决方案2】:

给出一个想法:

#include <stdio.h>
#include <math.h>
#define ROW 3
#define MAT 9

float printinv( int n, float * a, float * b );

int main ( void ){
    int i, k;
    float a[ ROW ] = { 1, 2, 3 };
    float b[ MAT ] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    float *c;
    c = &b[0];


    printf( "A = " );
    for( i = 0; i < ROW; i++ ){
        if( i == 0 )
            printf( "[" );
        if ( i != ROW - 1 )
            printf( "  %5.2f", a[ i ] );
        else {
            printf( "  %5.2f", a[ i ] );
            printf( "  ]" );
        }
    }

    printf( "    B = " );
    for( i = k = 0; k < MAT; k++ ){
        if( i == 0 && k == 0) 
            printf("[");
        else if( i == 0 && k > 0 )
            printf( "                                     [");
        if( i != ROW - 1 ){
            printf( "  %5.2f", b[ k ] );
            i++;
        }
        else{
            printf( "  %5.2f", b[ k ] );
            printf( "  ]\n" );
            i = 0;
        }
    }

    printf( "C = " );
    for( i = 0; i < ROW; i++ ){
        if( i == 0 ) 
            printf("[");
        if( i != ROW - 1 )
            printf( "  %5.2f", printinv( MAT, ( c + i ), a ) );
        else{
            printf( "  %5.2f", printinv( MAT, ( c + i ), a ) );
            printf( "  ]\n" );
        }
    }
    getchar();

}

float printinv( int n, float * b, float * a )
{
    int i, k;
    float result;
    float x, y;

    for( result = i = 0; i < ROW; i++ ){
        k = i * ROW;
        result += b[ k ] * a[ i ];
        x = b[ k ]; 
        y = a[ i ];
    }
    return result;
}

输出:

【讨论】:

  • -这段代码有什么作用?这是如何获取标量产品的示例吗? printinv 还有什么作用?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-17
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 1970-01-01
  • 2022-11-22
  • 1970-01-01
相关资源
最近更新 更多