C-带有可变函数参数的分割故障



我的程序无错误地编译,但是当我运行它时,它在输入这样一个半径的值后会退出故障。

我已经构造了它以获取可变数量的参数,但我怀疑这可能与我在" shape_area"函数操作过程中调用每个参数的方式有关。

任何人都可以帮助解释我在这里做错了什么?

#include <stdio.h>
#include <math.h>
#include <stdarg.h>
double shape_area(double shapetype, ...);
int main(void)
{
    int shapetype;
    double radius, side, length, width, area;
    printf("nnPlease enter the type of shape you wish to get the area of:n");
    printf("| 1-Circle | 2-Square  | 3-Rectangle |n");
    scanf("%d", &shapetype);
    // Circle
    if(shapetype == 1)
    {
        printf("nPlease enter the radius of your circle: ");
        scanf("%lf", &radius);
        area = shape_area(shapetype, radius);
    }
    // Square
    else if(shapetype == 2)
    {
        printf("nPlease enter the side length of your square: ");
        scanf("%lf", &side);
        area = shape_area(shapetype, side);
    }
    // Rectangle
    else if(shapetype == 3)
    {
        printf("nPlease enter the side length of your square: ");
        scanf("%lf", &length);
        printf("nPlease enter the side length of your square: ");
        scanf("%lf", &width);
        area = shape_area(shapetype, length, width);
    }
    else
    {
        printf("nnInvalid Input!n");
        return (0);
    }
    printf("nnArea of Shape: %lfnn", area);
    return (0);
}
double shape_area(double shapetype, ...)
{
    va_list args;
    double temparea;
    double radius;
    double side;
    double length;
    double width;
    radius = va_arg (args, double);
    side = radius;
    length = radius;
    width = va_arg (args, double);
    if(shapetype == 1)
    {
        temparea = M_PI*radius*radius;
    }
    if(shapetype == 2)
    {
        temparea = side*side;
    }
    if(shapetype == 3)
    {
        temparea = length*width;
    }
    va_end (args);
    return temparea;
}

您需要使用va_start

初始化args列表
double shape_area(double shapetype, ...)
{
va_list args;
va_start(args,shapetype);
.
.

warzon正确地指出了您需要使用va_start,但这是弄清楚将来发生的事情:

# The -g is the important part here, -O0 will help too if you don't care about optimization.
$ gcc -Wall -std=gnu99 -O0 -Wextra -Werror -g -foptimize-sibling-calls -o shape shape.c
$ gdb ./shape
...
(gdb) b shape_area # Set a breakpoint.
Breakpoint 1 at 0x80485b8: file shape.c, line 63.
(gdb) run
Please enter the type of shape you wish to get the area of:
| 1-Circle | 2-Square  | 3-Rectangle |
1
Please enter the radius of your circle: 3
63         radius = va_arg (args, double);
(gdb) next # Run the line that assigns the radius.
65         side = radius;
(gdb) p radius
$1 = 0

您要么在此之前击中segfault,要么看到va_arg的不正确值。这导致了VA_ARGS的人页面,其中指出:

参数ap是由va_start()初始化的va_list ap。

应该导致AHA时刻,因为您忘了致电va_start()。总的来说,如果您要获得赛车手,那么第一件事就是启动调试器。它很可能会指向问题。

您所做的错误是,我认为将所有不同的公式都塞入一个函数中。当然,@Warzon在这种情况下需要va_start是正确的,但是我认为这种方法没有优势,除非可以想象,问题是您的使用。shape_area中的大多数共享代码与va_list机制的开销有关!

如果要传递有关多种类型之一的形状的信息(并且由于C不是OO而无法使用继承),则最好创建structstruct s的union。但是,在您的程序中,您也可以制作circle_areasquare_arearectangle_area并致电适当的。这也避免了需要记录shapetype参数!

的需要

相关内容

  • 没有找到相关文章

最新更新