我是C的新手,来自新语言(如Java和C ++)的背景,我不知道如何处理运行时错误,例如发送给函数的错误参数。
例如说我想写一个函数来操作一个字符串(假设任何有效的int是一个可接受的返回值):
int foo (char s[]) {
if ( strlen(s) < 1)
// ERROR
....
....
return someInt;
}
如果我希望函数立即停止,如何在Ansi C中处理这种情况?在C ++或Java中,我会抛出一个异常来被调用者捕获。
答案 0 :(得分:3)
您始终可以使用返回值:
if( /* some bad parameters */ )
return -1;
然后:
int value = foo( something );
if( value == -1 )
// error
else
// no error
或传递另一个参数:
int foo( char s[], int* value )
{
if( /* error */ )
return 1;// error code 1
// ...
*value = something;
return 0;
}
然后,当您调用该函数时,您可以验证它是否已正确执行:
if( foo( "something", &result ) )
{
//ok
}
else
{
// not ok
}
这两种方法都意味着如果出现错误,调用者将手动验证
答案 1 :(得分:2)
如果我希望该功能立即停止
两件事。
如果您希望仅该函数停止执行并返回调用者,请使用return
语句。此外,您可能希望使用一些预定义或用户定义的错误代码作为失败案例返回值,以便将失败原因与调用者区分开来。
如果您希望程序本身终止,请致电exit()
。
答案 2 :(得分:1)
在任何C程序中执行错误处理的标准方法是为错误代码保留函数的返回值。
大多数情况下,这是自定义枚举类型。例如:
typedef enum
{
FOO_OK,
FOO_ERR_STRLENGTH,
FOO_ERR_DIVIDE_BY_ZERO,
...
} foo_err_t;
foo_err_t foo_func (/* parameters */)
{
if (strlen(s) < 1)
{
return FOO_ERR_STRLENGTH;
}
...
return FOO_OK;
}
然后您正确记录该功能,并说明它可能返回的错误代码,以及导致它们的原因。
错误时应该做什么通常不是你的惯例的事情,而是应该由调用者决定的事情。特别是,您的例程永远不应该决定终止整个程序。该决定应该由最外面的调用者(调用栈的顶部),即从main()开始。
答案 3 :(得分:0)
如果我正确地考虑您的问题,大多数类型错误都会在编译时被捕获。如果您想早点返回,只需拨打return
即可。通常,错误处理,C程序员将为错误添加goto
:
struct Data *
create_data ()
{
struct Data *data = malloc(sizeof(struct Data));
if (data == NULL)
goto exit;
/* do stuff with data */
exit:
return data;
}
如果没有内存,那将返回NULL。但是你可能想要提前退出另一个原因。所以,如果你需要优雅地退出程序(并释放你所有的东西),你就需要一个中心出口点。
我通常有像
这样的功能void bail (const char *fmt, ...)
{
va_list argp;
va_start(argp, fmt);
vfprintf(stderr, fmt, argp);
va_end(argp);
exit(EXIT_FAILURE);
}
它打印到STDERR
并返回非0退出。您可以轻松修改此项以接受您需要释放的任何数据。
答案 4 :(得分:0)
您的主要选择是:
0
表示成功)并通过参考参数输出函数的输出。其他选项包括使用全局(或线程局部)变量来表示错误状态(不是一个好主意恕我直言),或者返回包含返回信息和错误状态的struct
。