当没有有效值返回时,在C中怎么办?

时间:2017-02-12 12:21:59

标签: c function declaration

我有一个由几个参数和一个唯一id定义的元素数组,我创建了一个函数,它返回与某个唯一id相关联的元素,问题是如果输入了一个无效的ID(一个不是&#39) ; t由数组存储),没有有效值返回我的函数。

我的问题是,如果函数没有必要返回某些内容,我的代码将无法编译,有没有办法告诉编译器这可以在这里做到这一点?

谢谢。

4 个答案:

答案 0 :(得分:7)

有几种方法可以做到这一点。

最简单的方法是返回一个不在有效值范围内的值。

另一种方法是声明另一个参数,该参数是指向充当错误的变量的指针。或者返回错误值并将有效值作为参数声明为参考。

例如

int /* error */ f( T *valid_value );

另一种方法是返回两个值的结构,其中一个值是报告失败或成功的布尔值。

答案 1 :(得分:2)

您必须定义一个无效值,这样的值只是一个不属于有效值集的值。

例如:

如果有效值为 [0,inf),那么 -1 是一个好的无效值

答案 2 :(得分:1)

我会返回指向元素的指针而不是元素本身。比如这个。

struct Element* e = find(elements, m, 1234);
if(e) //check and see if it is not null
{
   //handle found case
}
else
{
   //handle not found case
}

然后你可以做这样的事情。

project(${TARGET_NAME})

cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
set(CMAKE_VERBOSE_MAKEFILE ON)

set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_CXX_STANDARD 14)

set(POSITION_INDEPENDENT_CODE FALSE)

macro(NAMELIST erg in)
    set(os "")
    set(srcs ${in})
    separate_arguments(srcs)
    foreach(is ${srcs})
        set(os ${os} ${is})
    endforeach(is)
    set(${erg} ${os})
endmacro(NAMELIST)

macro(FINDMODULES erg in)
    set(os "")
    set(srcs ${in})
    separate_arguments(srcs)
    foreach(is ${srcs})
        find_package(Qt5${is} REQUIRED)
        set(os ${os} Qt5::${is})
    endforeach(is)
    set(${erg} ${os})
endmacro(FINDMODULES)

NAMELIST(SRCS ${TARGET_SRCS})
FINDMODULES(QLIBS ${QMODULES})

if(INC_PATH)
    NAMELIST(INCS ${INC_PATH})
    set(INCLUDES ${INCS})
endif(INC_PATH)

if(TARGET_EXTLIBS)
    NAMELIST(EXTRA_LIBS ${EXTRA_LIBS} "${TARGET_EXTLIBS}")
endif(TARGET_EXTLIBS)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)

include_directories(${INCLUDES})

if(BUILD_LIB)
    set(CMAKE_SHARED_LIBRARY_LINK_C_FLAGS "-shared")
    set(CMAKE_SHARED_LIBRARY_LINK_CXX_FLAGS "-shared")

    add_library(${TARGET_NAME} SHARED ${SRCS})
    target_link_libraries(${TARGET_NAME} ${QLIBS} ${EXTRA_LIBS})
    set_property(TARGET ${TARGET_NAME} PROPERTY VERSION "1.0.0")
    set_property(TARGET ${TARGET_NAME} PROPERTY SOVERSION 1 )
    install(TARGETS ${TARGET_NAME} LIBRARY DESTINATION lib)
    install(TARGETS ${TARGET_NAME} LIBRARY DESTINATION lib NAMELINK_ONLY)
else()
    if(USE_LIB_PATH)
        add_executable(${TARGET_NAME} ${SRCS})
        target_link_libraries(${TARGET_NAME} -L${OUT_PATH}/lib lib${USE_LIB}.so.1
            ${QLIBS} ${EXTRA_LIBS})
    else()
        add_executable(${TARGET_NAME} ${SRCS})
        target_link_libraries(${TARGET_NAME} ${QLIBS} ${EXTRA_LIBS})
    endif(USE_LIB_PATH)
    install(TARGETS ${TARGET_NAME} RUNTIME DESTINATION bin)
endif(BUILD_LIB)

答案 3 :(得分:0)

  

.....有没有办法告诉编译器这样做可以吗?

不,没有办法做到这一点。

函数必须始终返回相同类型的值(即您在声明中给出的类型)或永远不返回任何内容(即声明为void foo(...))。

在某些情况下,您无法返回值并返回"没有"在其他情况下。同样,在某些情况下,您不能返回整数,而在其他情况下则不能返回结构。在所有情况下,返回值必须相同。

一般的工作是引入一种方法告诉调用者该函数未能找到所请求的元素。如其他答案中所述,有多种方法可以做到这一点。哪种解决方案取决于您的代码和需求。

我通常更喜欢该函数返回int,其中零值表示"失败"非零意味着成功"。然后我会"返回"使用指针的元素。像这个伪代码:

int foo(struct MyStruct *p, .....)
{
     if (found.....)
     {
          *p = the_found_element;
          return 1;
     }
     return 0; 
 }


 struct MyStruct ms;
 if (foo(&ms, ....))
 {
     // okay - carry on using ms
     ...
 }
 else
 {
     // failure - don't use ms as it is invalid
     ... 
  }