如果我需要在 C++ 中区分 0 和 NULL 怎么办?
What if I need to differentiate 0 from NULL in C++?
** 请不要批评代码本身的用途。它来自 Pat Morin 的开放数据结构一书。不是我的第一选择,它已分配 reading/practice。我只是想知道是否有办法区分,或者有更好的方法来解决这个问题。教科书--> http://opendatastructures.org/ods-cpp/**
** 另一个注意事项:我来自 Java,那里是允许的。我的代码仍然可以编译,只是 "fixes" it**
我很惊讶以前没有出现过这样的问题,因为这似乎是一个如此简单的问题。也许它被掩埋了,或者我没有使用正确的术语。
我有一个 for 循环遍历向量中的数据。如果找到,我需要 return 正在搜索的值。如果找不到怎么办?这是我的代码。
int find(int x) {
for(int i=0;i<bag.size();i++){
// if x is equal to data, return data
if (bag[i]==x){
return bag[i]; // ends loop as soon as one instance is found
}
}
// if we made it this far, no match was found.
return NULL;
}
很简单。假设 0 是我可能需要记录和搜索的有效值之一。事实上,它实际上是 returns 0,而不是 "NULL"。研究表明它是一回事。我如何指定或区分?除了 return 一个不会出现在程序中的模糊数字,因为我们可能并不总是拥有这种奢侈(比如 -1 或 -9999999)。例如,搜索您的帐户余额。没有数字是不可能的。
为什么要 return 从查找函数中搜索的值?您已经知道该值,它是您传递给函数的值。 Return 找到的元素的位置,因为此信息更有用。当找不到该值时,您可以 return 一个特殊的位置,例如 -1。或者您可以遵循标准库的模型和 return 结束迭代器,它表示超出范围末尾的位置。
你在谈论一种邪恶的做法,来自 Java 和 C# 开发人员,在那里你可以 return null
作为无效结果。
好吧,你不能用 C++ 来做。
Java 和 C# 声明了堆上的几乎所有内容,并且访问对象始终由引用完成。这意味着您始终 return 来自函数的指针,并且您始终可以 return 空值作为 return 值。
当函数不是 return 指针时,这在 C++ 中是不可能的。例如,函数 std::string returnString()
不能 return null 作为 return 值。
此外,您不应该 return null 作为无效输出。即使在 C# 和 Java 中,这在很多层面上都是错误的!如果您的函数失败,只需抛出异常,或将您的 return 值作为引用参数传递并使函数 return 为真或假。
您还可以找到不太激进的解决方案,例如 returning -1(例如 javascript 中的 indexOf()
)或 return 诸如 std::string::npos
或std::vector:end
对 C++ STL 进行了更多调整。
这就是 boost::optional<T>
的用途。实际上,此类型表示 "There may be a T
, but there may not be a T
"。用户可以检查是否有 T
。理想情况下,您不会依赖 T
的任何特殊值,而是使用 optional<T>
代替。 optional<T>
是完全通用的,几乎可以应用于您可能需要使用的任何 T
,它不依赖于 T
.
的某些特殊值或状态
boost::optional<int> find(int x) {
for(int i=0;i<bag.size();i++){
// if x is equal to data, return data
if (bag[i]==x){
return bag[i]; // ends loop as soon as one instance is found
}
}
// if we made it this far, no match was found.
return boost::none;
}
int main() {
if (auto opt = find(5))
std::cout << *opt;
}
永远不要使用 NULL
,这是一件很糟糕的事情。始终使用 nullptr
,它实际上更安全,它更安全的原因之一是因为您的错误代码无法编译。
您可以通过多种方式编写函数
bool find( int x )
{
std::vector<int>::size_type i = 0;
while ( i < bag.size() && bag[i] != x ) i++;
return i != bag.size();
}
或
std::vector<int>::size_type find( int x )
{
std::vector<int>::size_type i = 0;
while ( i < bag.size() && bag[i] != x ) i++;
return i;
}
或
#include <algorithm>
//...
std::vector<int>::iterator find( int x )
{
return std::find( beg.begin(), bag.end(), x );
}
并通过以下方式对应使用功能
if ( find( x ) ) { /*...*/ }
if ( find( x ) != bag.size() ) { /*...*/ }
if ( find( x ) != bag.end() ) { /*...*/ }
至于你在标题中的一般问题post
What if I need to differentiate 0 from NULL in C++?
那么你需要使用 nullptr
而不是 NULL 来区分 0 和 NULL。:)
#define XOR_MSB(x) (x^0x80000000)
int find(bool found) {
return found ? XOR_MSB(0) : NULL;
}
int main()
{
int value = find(false);
if (value == NULL) printf("not found\n");
else printf("%d\n", XOR_MSB(value));
value = find(true);
if (value == NULL) printf("not found\n");
else printf("%d\n", XOR_MSB(value));
return 0;
}
** 请不要批评代码本身的用途。它来自 Pat Morin 的开放数据结构一书。不是我的第一选择,它已分配 reading/practice。我只是想知道是否有办法区分,或者有更好的方法来解决这个问题。教科书--> http://opendatastructures.org/ods-cpp/**
** 另一个注意事项:我来自 Java,那里是允许的。我的代码仍然可以编译,只是 "fixes" it**
我很惊讶以前没有出现过这样的问题,因为这似乎是一个如此简单的问题。也许它被掩埋了,或者我没有使用正确的术语。
我有一个 for 循环遍历向量中的数据。如果找到,我需要 return 正在搜索的值。如果找不到怎么办?这是我的代码。
int find(int x) {
for(int i=0;i<bag.size();i++){
// if x is equal to data, return data
if (bag[i]==x){
return bag[i]; // ends loop as soon as one instance is found
}
}
// if we made it this far, no match was found.
return NULL;
}
很简单。假设 0 是我可能需要记录和搜索的有效值之一。事实上,它实际上是 returns 0,而不是 "NULL"。研究表明它是一回事。我如何指定或区分?除了 return 一个不会出现在程序中的模糊数字,因为我们可能并不总是拥有这种奢侈(比如 -1 或 -9999999)。例如,搜索您的帐户余额。没有数字是不可能的。
为什么要 return 从查找函数中搜索的值?您已经知道该值,它是您传递给函数的值。 Return 找到的元素的位置,因为此信息更有用。当找不到该值时,您可以 return 一个特殊的位置,例如 -1。或者您可以遵循标准库的模型和 return 结束迭代器,它表示超出范围末尾的位置。
你在谈论一种邪恶的做法,来自 Java 和 C# 开发人员,在那里你可以 return null
作为无效结果。
好吧,你不能用 C++ 来做。 Java 和 C# 声明了堆上的几乎所有内容,并且访问对象始终由引用完成。这意味着您始终 return 来自函数的指针,并且您始终可以 return 空值作为 return 值。
当函数不是 return 指针时,这在 C++ 中是不可能的。例如,函数 std::string returnString()
不能 return null 作为 return 值。
此外,您不应该 return null 作为无效输出。即使在 C# 和 Java 中,这在很多层面上都是错误的!如果您的函数失败,只需抛出异常,或将您的 return 值作为引用参数传递并使函数 return 为真或假。
您还可以找到不太激进的解决方案,例如 returning -1(例如 javascript 中的 indexOf()
)或 return 诸如 std::string::npos
或std::vector:end
对 C++ STL 进行了更多调整。
这就是 boost::optional<T>
的用途。实际上,此类型表示 "There may be a T
, but there may not be a T
"。用户可以检查是否有 T
。理想情况下,您不会依赖 T
的任何特殊值,而是使用 optional<T>
代替。 optional<T>
是完全通用的,几乎可以应用于您可能需要使用的任何 T
,它不依赖于 T
.
boost::optional<int> find(int x) {
for(int i=0;i<bag.size();i++){
// if x is equal to data, return data
if (bag[i]==x){
return bag[i]; // ends loop as soon as one instance is found
}
}
// if we made it this far, no match was found.
return boost::none;
}
int main() {
if (auto opt = find(5))
std::cout << *opt;
}
永远不要使用 NULL
,这是一件很糟糕的事情。始终使用 nullptr
,它实际上更安全,它更安全的原因之一是因为您的错误代码无法编译。
您可以通过多种方式编写函数
bool find( int x )
{
std::vector<int>::size_type i = 0;
while ( i < bag.size() && bag[i] != x ) i++;
return i != bag.size();
}
或
std::vector<int>::size_type find( int x )
{
std::vector<int>::size_type i = 0;
while ( i < bag.size() && bag[i] != x ) i++;
return i;
}
或
#include <algorithm>
//...
std::vector<int>::iterator find( int x )
{
return std::find( beg.begin(), bag.end(), x );
}
并通过以下方式对应使用功能
if ( find( x ) ) { /*...*/ }
if ( find( x ) != bag.size() ) { /*...*/ }
if ( find( x ) != bag.end() ) { /*...*/ }
至于你在标题中的一般问题post
What if I need to differentiate 0 from NULL in C++?
那么你需要使用 nullptr
而不是 NULL 来区分 0 和 NULL。:)
#define XOR_MSB(x) (x^0x80000000)
int find(bool found) {
return found ? XOR_MSB(0) : NULL;
}
int main()
{
int value = find(false);
if (value == NULL) printf("not found\n");
else printf("%d\n", XOR_MSB(value));
value = find(true);
if (value == NULL) printf("not found\n");
else printf("%d\n", XOR_MSB(value));
return 0;
}