【问题标题】:Passing a vector to a function to calculate length in C将向量传递给函数以计算 C 中的长度
【发布时间】:2015-03-07 18:20:58
【问题描述】:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

struct vector
    {
        double x;
        double y;
        double z;
    };

    struct vector *array;
    double length(struct vector*);
int main()
{
    int num,i;
    double xin;
    double yin;
    double zin;
    char buffer[30];
    char buffer2[30];

    printf("Enter number of vectors:");
    fgets(buffer, 30, stdin);
    sscanf(buffer, "%d", &num);


    array = malloc( sizeof(struct vector) * num);

           for(i=0;i<=num;i++)
           {
               printf("Please enter x y z for the vector:");
               fgets(buffer2,100,stdin);
               sscanf(buffer2, " %lf %lf %lf", &xin, &yin, &zin);

                   array[i].x = xin;
                   array[i].y = yin;
                   array[i].z = zin;
           }

           for(i=0;i<=num;i++)
           {

               printf( "Vector:%lf %lf %lf has a length of %lf\n", array[i].x, array[i].y, array[i].z, length(&array[i]));

           }
}


double length(struct vector* vec)
{

 return sqrt( (vec->x * vec->x) + (vec->y * vec->y) + (vec->z * vec->z) );

}

好的,上面的代码差不多完成了,它询问用户向量的数量,然后它询问用户这些向量的值,然后它会计算长度并相应地打印出来。

我试图在这里检查一些错误,但我似乎无法得到它...我查找了 fgets 和 sscanf 的所有可能返回值,我似乎无法得到它

防御功能

FIRST printf--------input 应该只是一个大于 0 的数字,EOF 应该返回类似 printf("enter a number--bye!") 这样的消息,所以我尝试了

while( sscanf(buffer, "%d", &num) ==1 && num > 0 )

但如果输入 3dadswerudsad 之类的内容,它仍然有效

此外,当用户输入向量的 3 个值时,如果为向量输入了除 3 个双精度之外的任何值,则程序应该以一条消息终止,所以我尝试了

while( sscanf(buffer2, "%lf %lf %lf", &xin, &yin, &zin) ==3 )

但它不会检查这些不正确的输入!!

我要疯了

【问题讨论】:

  • 查看我对您之前问题的回答(我认为这个问题应该是对之前问题的修改。)

标签: c data-structures structure


【解决方案1】:

函数可以实现如下。

double length(struct vector vec)
{
    return sqrt( vec.x*vec.x + vec.y*vec.y + vec.z*vec.z );
}

【讨论】:

  • 投了反对票,因为这个答案与如何检查无效输入的问题无关
【解决方案2】:

你几乎是对的,你需要命名形式和函数并适当地使用它:

double veclength (struct vector v) {
   return sqrt( (v.x * v.x) + (v.y * v.y) + (v.z * v.z) );
}

出于效率和其他原因,您可能会考虑传递一个指针(指向一个常量向量,因为您不修改它)

double veclengthptr (const struct vector* v) {
   return sqrt( (v->x * v->x) + (v->y * v->y) + (v->z * v->z) );
}

然后您可以稍后使用veclength(array[i])veclengthptr(array+i)(与veclengthptr(&amp;a[i]) 相同)

在使用这些函数之前,您应该希望给出原型(可能在某些头文件中):

 double veclength (struct vector);
 double veclengthptr (const struct vector*);

请注意,出于效率原因,您可能希望将这些原型声明为static inline(并在相同翻译单元中提供它们的实现),因此请求inline functions

 static inline double veclength (struct vector);

养成编译所有警告和调试信息的习惯,例如gcc -Wall -Wextra -g

关于您将sscanf(3) 用作sscanf(buf, "%d", &amp;num) 请注意,如果buf 包含3dxde,则通过将3 读入numdxde 未解析)来成功。您可能想在sscanf 中使用%n(阅读其文档!)或使用strtol(3)

【讨论】:

  • 将指针版本声明为double veclengthptr (const struct vector* v) 可能是有意义的,因为它没有修改它的目标
  • 我的 C 技能可能已经有点生疏了,但是您不能将 veclength 声明为 double veclength (const struct vector &amp;v) 并忘记需要指针的函数吗?或者那是只在 C++ 中有效的东西之一?
  • 没有形式 (const struct vector&amp;v) 在 C++ 中有效,但在 C 中无效。C 没有引用。
  • 如果我做 veclengthptr,我的原型是否必须改变??
  • 哈哈它一直在顶部,但我得到了它的工作......非常感谢认真帮助我
猜你喜欢
  • 2011-12-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-07
  • 2016-06-08
  • 1970-01-01
  • 1970-01-01
  • 2017-10-16
相关资源
最近更新 更多