我不是 C 程序员,但我正在将 C 程序翻译成 Delphi。一切进展顺利,除了我无法弄清楚这样的陈述的含义:
if (result1)
*result1 = t2;
似乎总是要执行分配,然后针对某些条件进行测试?
如果有帮助,完整的 C 程序列在http://en.wikipedia.org/wiki/Talk%3ATrilateration 。
我不是 C 程序员,但我正在将 C 程序翻译成 Delphi。一切进展顺利,除了我无法弄清楚这样的陈述的含义:
if (result1)
*result1 = t2;
似乎总是要执行分配,然后针对某些条件进行测试?
如果有帮助,完整的 C 程序列在http://en.wikipedia.org/wiki/Talk%3ATrilateration 。
In C, there is an assimilation between integers and booleans: any number not zero means true. In C 99 the bool
type was added (following the steps of C++), but these so common uses are difficult to erradicate (and there is also a lot of legacy source code using this convention).
The true meaning of that sentence is:
if ( result1 != NULL ) {
*result1 = t2;
}
This means that result1
is a pointer, and if the probable memory allocation previous to this line was successful, then it is used to store the value t2
.
So, what does this have to do with pointers? Well, a pointer is basically an integer (a memory address), and NULL is (very commonly, but not always) zero. So "result1" can be interpreted as result1 != NULL
or even result1 != 0
.
Finally NULL
is returned when a memory allocation (or any other memory operation) was unsuccessful, so it is quite common to test that the pointer is alive (i.e., it is not NULL
) before using it.
它测试指针result1
是否不是null
。如果true
t2
将被赋值为result1
在 C/C++ 中,取消引用指针是未定义的行为。NULL
简而言之,如果您这样做,可能会发生非常糟糕的事情。
因此,NULL
在取消引用之前检查指针始终是一个好习惯。
上述代码就是这样做的。
result looks like a pointer to a pointer. if it's not null, point the pointer it's pointing to to t2.
if result1 is not null result1 points to an address point that address to t2
result1
是一个指针;它的值是另一个对象在内存中的位置。
在 C 布尔上下文中,零值积分表达式的计算结果为false
,而任何非零值整数表达式的计算结果为true
。在指针上下文中,零值整数表达式被视为NULL 指针常量,它表示定义明确的“无处”,并被视为无效指针值。
所以if (result1)
测试指针的值;如果为 0,则表示result1
没有指向任何有意义的地方,并且由于 0 也表示,因此不会执行语句false
的主体。if
这是一种速记的写作方式if (result1 != NULL)
。如果值不为 0,那么它是一个有效的指针值(希望如此;见下文),测试通过,表达式*result1 = t2
将 的值写入指向的t2
位置。 result1
关于指针的几点说明:首先,非 NULL 指针值不一定是有效指针,因为它的值可能与活动对象的地址不对应。试图取消引用(访问指向的内存)无效指针的行为是未定义的;您的程序可能会彻底崩溃,或者它可能会继续在错误的状态下执行,或者它可能工作得很好。因此,通常认为在声明所有指针时将它们初始化为 NULL 并在不再使用它们所指向的任何内容时将它们设置为 NULL 是一种很好的做法。
其次,虽然空指针常量始终为零值,但实现使用的空指针值不一定是。映射这些值由编译器决定,因此就您的源代码而言,NULL 始终表示 0;只是不要假设底层操作系统是这样的。
if (result1 != NULL)
{
*result1 = t2;
}
如果 result1 是null
指针,则该行*result = t2
应导致 SEGFAULT。
如果您想通过函数参数传递返回结果,这实际上是 C 中的一种常见模式。C函数中没有var
参数,因此您可以通过将指向值的指针作为参数传递来模拟这个想法,然后函数可以通过分配给指针指向的位置来设置值。
其中的行main
如下所示:
result = trilateration(&o1, &o2, p1, r1, p2, r2, p3, r3, MAXZERO);
创建指向变量 o1 和 o2 的内存地址的指针(这就是&
意思)。然后函数中的行
*result1 = t2;
分配t2
给任何result1
指向的东西,在这种情况下是o1
.
线
if (result1)
测试指针是否为“真”(假与 0 相同,在 C 中任何非零值都为真),因此与
if (result1 != NULL) // NULL is effectively the same as 0.
这样做的原因是,将 NULL 作为函数的第一个参数传递是合法的。如果您只对获取两个结果值之一感兴趣,您可能想要这样做。所以,你可以安全地做
result = trilateration(NULL, &o2, p1, r1, p2, r2, p3, r3, MAXZERO);
如果你不关心计算o1
。