你什么时候能够返回NULL作为C函数的返回值?

我想知道你是否可以告诉我你什么时候能够返回NULL ,这是C中函数的结果。

例如, int lenght()不能返回NULL因为在return语句中需要一个int

但是函数struct node* find(int key) ,当使用链表时允许我返回NULL。

NULL是指针值 – 或者更确切地说是空指针值。

NULL表示函数无法找到指针应指向的位置 – 例如,如果要打开文件,但它不起作用,则文件指针将返回为NULL 。 因此,您可以测试指针的值并检查它是否有效。

如果你正在写一个例程

 int length() 

然后你可以返回一个负值,如果长度无法读取你发送它的长度 – 这将是一种指示错误的方式,因为通常长度永远不会是负面的….

这是一个惯例问题 ,你应该清楚地掌握一个并记录下来(至少在评论中)。

有时指针确实应该总是指向一个有效的地址(参见这个 intSwap示例,两个参数都应该是有效的指针)。 在其他时候,它应该是这样一个有效的地址,或者是NULL 。 从概念上讲,指针类型按照惯例是一种求和类型 (在真正的指针地址和特殊的NULL值之间)。

请注意,C语言没有强制某些给定指针始终有效且非空的类型(或符号)。 顺便说一句,特别是GCC,你可以用__attribute__使用nonnull空来注释一个函数来表示给定的参数永远不会为空。

一个典型的例子是 FILE*指针。 记录fopen函数能够返回NULL (失败时)或一些有效指针。 但是fprintf函数期望一个有效的指针(并将NULL传递给它,因为第一个参数是一些未定义的行为 ,通常是一个分段错误 ;而UB非常糟糕 )。

一些非可移植程序甚至使用几个“特殊”指针值(不应该取消引用),例如(在Linux / x86-64上) #define SPECIAL_SLOT (void*)((intptr_t)-1) (我们知道在Linux它永远不是一个有效的地址)。 然后我们可以有一个约定,指针是指向有效内存区域的有效指针,或NULLSPECIAL_SLOT (因此,如果被视为抽象数据类型 ,它是两个不同的无效指针的总和类型NULLSPECIAL_SLOT和集合有效地址)。 另一个例子是MAP_FAILURE ,它是Linux上mmap(2)的结果。

顺便说一句,当使用C中的指针来堆积分配的数据(通过malloc间接获得)时,您还需要有关谁负责释放数据的约定(通过使用free ,通常通过提供的函数来释放数据及其所有内部资料) )。

好的C编程需要许多关于指针的明确约定 ,并且必须精确地理解它们并将它们很好地记录下来。 在GTK中查找示例[s]。 另请阅读restrict

什么时候能够返回NULL作为C函数的返回值

通常,当且仅当函数返回指针类型时:

 T * function( | void>); /* With T being any valid type. */ 

还有其他的极端情况,这取决于使用中的C实现。

NULL绝对是一个指针。 因此,如果您的函数需要返回指针并且由于某种原因不能,则应返回明显的“无效指针”,即NULL。

NULL可以定义为0(void *)0 (参见6.3.2.3p3和7.19p3 )。

因此,它可能总是在返回指针类型的函数中用作返回值,并且根据实现,它可能可用作返回数值类型的函数中的返回值,尽管后者是个坏主意,因为预期为NULL与指针结合使用。