我一直以为C不接受NULL参数,直到我开始学习指针。在某些编程语言中,比如python for one,可以将NULL参数作为参数传递,但在C中我总是认为这会导致 Undefined Behavior 。
我的问题只是一个好奇心,一个功能怎么样,比如......
waitpid(child_pid, &status, options); //pointer &status
...接受一个NULL指针作为参数而不进入 Undefined Behavior ,不要将NULL指针简单地指向什么?
简单地说,为什么这在C中可以接受?
答案 0 :(得分:8)
在某些编程语言中,可以将NULL参数作为参数传递,但在C中我一直认为这会导致未定义的行为。
为指针传递NULL
参数不会导致UB;它试图访问设置为NULL
的指针所指向的内存。
对于未指定内容的情况,传递NULL
是一种非常常见的做法。在执行访问之前,调用者应检查NULL
的参数。例如,该标准允许您将NULL
传递给free
,这使得该功能更加方便。
不是
NULL
指针只是指向什么?
是的,他们这样做。但那"没什么"是全球众所周知的,因此使用NULL
可以让您传达指针指向您调用的函数的事实。换句话说,检查
if (myPointer == NULL)
是明确定义的 * ,因此您可以利用它。
* 除非您使用悬空指针,即已释放的指针,或指向超出范围的对象的指针。您可以通过将NULL
分配给free()
的每个指针来防止第一种情况发生,第二种情况可以通过在范围中声明具有与作用范围相同或更高级别的嵌套的指针来实现。指针指向的自动对象。
答案 1 :(得分:4)
void func_with_optional_arg(char *optional)
{
if (optional == NULL) {
// do something differently
}
/* ... */
}
为什么会调用UB?肯定会取消引用NULL
指针,但是传递一个指针却不会。 NULL
是一个sentinel值,用于确定指针是否有效(不是无效指针不能有其他值,但是我们明确地使用了这个值。)如果将它传递给调用UB的函数那么将是什么它首先存在的意义何在?
而传递NULL非指针值不是吗?
没有" NULL非指针"在C中,所以我不确定你的意思。
答案 2 :(得分:1)
因为函数可以检查指针是否为NULL并避免使用它。一个典型的例子是一个函数,它返回一些返回值,并可以通过指针参数提供一些额外的信息。如果调用者对此类信息不感兴趣(并且被调用者为此做好准备),则将指针参数设置为NULL,并且被调用函数不会尝试将任何内容存储在其指向的位置。
int divide(int dividend, int divisor, int *remainder=NULL)
{
if(remainder!=NULL)
*remainder=dividend%divisor;
return dividend/divisor;
}
waitpid遵循这个习惯用法:如果你不关心状态,你可以传递NULL,避免使用虚拟变量。
通常,您可以使用NULL作为特殊值来表示没有传递有效指针;另一个常见的用法是说"使用默认值"对于某些指针参数。
请注意,这与Python没有太大区别:如果没有出现错误,您无法在“无”上做很多事情,但您可以随时检查值是否为“无”并采取相应措施。
答案 3 :(得分:0)
这完全取决于你如何处理NULL。基本上NULL表示值为0,因此如果您尝试将其用作整数,则不应该有任何问题。 但是请记住,NULL是表示无效内存位置(不存在)的定义,不能用作整数!
另一方面,对于指针,验证指针是否指向有效地址很重要。通常接受指针的函数必须验证传递的值是否有效,否则它最终会尝试访问某些无效的内存位置并崩溃。