我有一个 c 语言代码,我有一个返回 int 值的函数。但是,如果条件不完整,我需要该函数中的一个变量来给我值 N/A(不是它在开始时初始化的大数字)。任何提示如何做到这一点?非常感谢...
4 回答
C 中没有 N/A。最接近它的是值指针。您可以有一个函数返回指向 int 的指针,并在条件未满足的情况下返回 NULL。
基本上有两种可能性,返回一个指向静态存储的指针,或者一个指向使用 malloc 分配的存储的指针。
int *may_fail_static(int input) {
static int result;
if (input == 42)
return NULL;
else {
result = 3 * input;
return &result;
}
}
int *may_fail_malloc(int input) {
int *result;
if (input == 42)
return NULL;
else {
result = malloc(sizeof *result);
if (result == NULL) {
fprintf(stderr, "Out of memory!\n");
exit(1);
}
*result = 3 * input;
return result;
}
}
两者都有缺点:静态版本不可重入(不是线程安全的)。malloc 版本具有显着的分配开销,客户端必须在使用后显式释放存储空间。
这就是为什么在 C 语言中,您通常会找到此类函数:
/* Returns 0 on success, or -1 on failure */
int may_fail(int input, int *result) {
if (input == 42)
return -1;
else {
*result = 3 * input;
return 0;
}
}
客户可以通过以下方式使用它:
int x;
if (may_fail(42, &x) == -1) {
fprintf(stderr, "ERROR: may_fail failed!\n");
exit(1);
}
/* Answer value is now stored in x. Go ahead */
有几种方法
1.使用代理值AKA哨兵值
在这种情况下,最简单的方法是您可以为 N/A 保留值,这作为正常返回值无效。常见的例子是许多库函数,它们返回读/写/某事的字节数,或 -1 表示错误。如果您有一个已知范围的有效值,则在此范围之外定义一些合适的值来表示 N/A。
#include <limits.h>
// define NA_VALUE to be smallest possible int
#define NA_VALUE (INT_MIN)
int getInt1(const char *key) {
if (test_if_key_exits(key)) {
return get_int_for_key(key);
}
else {
return NA_VALUE;
}
}
void testfunc1(const char *key) {
int value = getInt1(key);
if (value != NA_VALUE) std::cout << value;
else std::cout << "n/a";
}
2.除了返回值外,使用out参数
更通用的替代方法是返回布尔值(或者可能是数字错误代码,甚至const char*
返回错误字符串或 NULL 以表示成功),然后使用指针参数作为实际返回值,如下所示:
bool getInt2(const char *key, int *result) {
if (test_if_key_exits(key)) {
// in case result is NULL, do not use it, just return true
if (result) *result = get_int_for_key(key);
return true;
}
else {
return false;
}
}
void testfunc2(const char *key) {
int value;
if (getInt2(key, &value))std::cout << value;
else std::cout << "n/a";
}
您也可以反转这一点,将 int 作为返回值返回,并将 out 参数用于状态。如果您希望始终返回某个值,甚至是默认值(如果没有别的),并且允许 out 参数指示它是默认值,这可能很有用。
3. 返回指向值的指针,或者NULL
第三种方法是返回一个指向值的指针,或者NULL
为 NA,但是你问的是int
返回值,所以这可能不实用,有一些缺点。在您可以返回指向某些现有数据的指针的情况下,它最有用。@JoSo 的答案中解释了这种替代方法和缺点。
我见过在 C 库中使用的四种方法:
/*
* return a defined unexpected value, like -1,
* otherwise the return the result
*
* return -1 if failed, otherwise on success
*/
int my_function(void) {
return -1;
}
/*
* the result is stored in `ret`, and the state
* is returned
*
* return -1 if failed, otherwise on success
*/
int my_function(int *ret) {
return -1;
}
/*
* the state is stored in an argument
*
* state = -1 if failed, otherwise on success
*/
int my_function(int *state) {
*state = -1;
return 0;
}
/*
* with pointers and addresses
*
* return NULL on failed, otherwise on success
*/
int *my_function(void) {
return NULL;
}
I agree with Jo so. Another thing you can do -- set errno(3) to some meaning value in your function and then check its value outside.