一些C函数如何接受空参数?

一些C函数如何接受空参数?,c,pointers,null,C,Pointers,Null,我一直认为C不接受空参数,直到我开始学习指针。在一些编程语言中,比如python,可以将NULL参数作为参数传递,但在C中,我一直认为这会导致未定义的行为 我的问题只是好奇,像这样的函数怎么能 waitpid(child_pid, &status, options); //pointer &status …接受空指针作为参数,而不会出现未定义的行为,空指针不是只指向零吗 简单地说,为什么这在C中是可以接受的 在某些编程语言中[…]可以将NULL参数作为参数传递,但在C中,我一

我一直认为C不接受空参数,直到我开始学习指针。在一些编程语言中,比如python,可以将NULL参数作为参数传递,但在C中,我一直认为这会导致未定义的行为

我的问题只是好奇,像这样的函数怎么能

waitpid(child_pid, &status, options);  //pointer &status
…接受空指针作为参数,而不会出现未定义的行为,空指针不是只指向零吗

简单地说,为什么这在C中是可以接受的

在某些编程语言中[…]可以将NULL参数作为参数传递,但在C中,我一直认为这会导致未定义的行为

单独为指针传递
NULL
参数不会导致UB;它正试图访问由设置为
NULL
的指针指向的内存

传递
NULL
对于未指定内容的情况是一种非常常见的做法。在执行访问之前,调用者需要检查参数是否为
NULL
。例如,该标准允许您将
NULL
传递给
free
,这使函数更加方便

难道
NULL
指针不直接指向任何东西吗

是的,有。但是“nothing”在全球范围内是众所周知的,因此使用
NULL
可以将指针指向nothing的事实传达给您调用的函数。换句话说,支票

if (myPointer == NULL)
是定义明确的*,因此您可以利用它发挥自己的优势

*除非使用悬空指针,即已释放的指针,或指向超出范围的对象的指针。您可以通过将
NULL
分配给您
free()
的每个指针来防止第一种情况的发生,第二种情况是在与指针指向的自动对象的作用域具有相同或更高嵌套级别的作用域中声明指针

void func_with_optional_arg(char *optional)
{
    if (optional == NULL) {
        // do something differently
    }

    /* ... */
}
为什么会调用UB?取消引用
NULL
指针肯定会,但传递一个指针则不会
NULL
是一个哨兵值,用于确定指针是否有效(不是说无效指针不能有其他值,而是我们显式使用这个值)。如果将它传递给UB调用的函数,那么它的存在点首先是什么

而传递空的非指针值不是吗


C语言中没有“NULL非指针”这样的东西,所以我不确定你在这里的意思。

因为函数可以检查指针是否为NULL并避免使用它。一个典型的例子是一个函数,它返回一些东西作为返回值,并可以通过指针参数提供一些附加信息。如果调用者对这些信息不感兴趣(并且被调用者对此做好了准备),指针参数将设置为NULL,被调用函数将不会尝试在其指向的位置存储任何内容

int divide(int dividend, int divisor, int *remainder=NULL) 
{
    if(remainder!=NULL) 
        *remainder=dividend%divisor;
    return dividend/divisor;
} 
waitpid遵循这样的习惯用法:如果不关心状态,可以传递NULL,避免使用伪变量

通常,您可以使用NULL作为特殊值来表示未传递有效指针;另一个常见用法是对某些指针参数说“使用默认值”


请注意,这与Python并没有太大的不同:在None上执行很多操作都会出现错误,但您可以始终检查值是否为None并相应地执行操作

这完全取决于您如何处理NULL。本质上表示0的值,因此,如果尝试将其用作整数,则不会有任何问题请记住,NULL是表示无效内存位置(不存在)的定义,不能用作整数


另一方面,对于指针,验证指针是否指向有效地址很重要。通常,接受指针的函数必须验证传递的值是否有效,否则它将尝试访问一些无效的内存位置并崩溃。

这取决于函数的编写方式。如果存在与空指针关联的行为,为什么会是未定义的行为?我想说,如果希望有无效的指针,这是可取的。如果在调用的函数中取消引用空指针,它确实会导致未定义的行为。设计用于接受空指针的代码将包含在使用指针之前测试指针是否为空的代码。例如,在
waitpid()
中,指针可能是
int*statloc
,如果(statloc!=NULL)*statloc=status,则代码可能是
。它指向NULL,指针本身不是NULL。指针有一个地址。但是当设置为NULL时,它并没有指向另一个地址。还有一些其他的Q/a,您可能会发现它们很有用。(有点类似。):,,:如果释放UB后指针被传递到它,则if语句将已经调用UB:)@giorgim:这根本不是真的。指针没有被取消引用,我们只是比较它的值,这是完全合法的前后免费的。此外,有各种各样的方法调用UB,而这些方法在被调用的函数中是无法解释的。我想你错了,请看这里的答案:@giorgim:Huh。写了十年的C,我仍然在学习新的东西。我认为这是一个有效的优化案例。好在我从来没有觉得有必要在真正的代码中这样做。谢谢,“定义总是很明确的”-我认为这不是真的。在这里检查答案,please@giorgim你是对的,我假设指针是有效的。我在脚注中解释了这一假设。谢谢很高兴这有帮助;这是个棘手的问题。为什么仅仅检查是UB并不直观,但您可以做什么:(函数如何测试传入的指针是否指向有效内存?这取决于您的