如果我需要在c++中区分0和NULL
What if I need to differentiate 0 from NULL in C++?
**请不要批评代码本身的目的。出自Pat Morin的《开放数据结构》一书。不是我的首选,它是指定的阅读/练习。我只是想知道是否有一种求导的方法,或者一种更好的方法。教科书——> http://opendatastructures.org/ods-cpp/* *
**另一个注意事项:我来自Java,这将是允许的。我的代码仍然可以编译,它只是"修复"它**
我很惊讶以前没有出现过这样的问题,因为这似乎是一个如此简单的问题。也许它被埋了,或者我用的术语不对。我有一个for循环遍历vector中的数据。我需要返回被搜索的值,如果它被找到。如果找不到怎么办?这是我的代码。
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是我可能需要记录和搜索的有效值之一。事实上,它实际上返回0,而不是"NULL"。研究表明这是一回事。我该如何指定或区分?除了返回一个不会在程序中出现的晦涩数字(比如-1或-9999999)。例如,搜索您的帐户余额。没有数字是不可能的。
为什么要从查找函数返回您正在搜索的值?你已经知道了这个值,它就是你传递给函数的值。返回找到的元素的位置,因为这个信息更有用。当没有找到该值时,您可以返回一个特殊位置,如-1。或者您可以遵循标准库的模型并返回end迭代器,该迭代器表示距离范围结束后1的位置。
可以用几种方法编写这个函数
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() ) { /*...*/ }
关于你在文章标题中提出的一般性问题
如果我需要在c++中区分0和NULL怎么办?
那么你需要使用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 foundn");
else printf("%dn", XOR_MSB(value));
value = find(true);
if (value == NULL) printf("not foundn");
else printf("%dn", XOR_MSB(value));
return 0;
}
你说的是一个邪恶的做法,来自Java和c#开发人员,你可以返回null
作为无效的结果。
在c++中是做不到的。Java和c#几乎在堆上声明所有东西,并且访问对象总是由引用完成。这意味着你总是从函数返回一个指针,并且你总是可以返回一个null作为返回值。
在c++中,当函数不返回指针时,是不可能的。例如,函数std::string returnString()
不能返回null作为返回值。
多了,不应该返回null作为无效输出。这在很多层面上都是错误的,即使在c#和Java中也是如此!如果函数失败,只需抛出异常,或者将返回值作为引用参数传递,并使函数返回true或false。
您还可以找到不太激进的解决方案,如返回-1(如javascript中的indexOf()
)或返回std::string::npos
或std::vector:end
之类的东西,它们更符合c++ STL。
这就是boost::optional<T>
的作用。实际上,这种类型表示"可能有T
,但可能没有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
,这实际上是更安全的,它更安全的原因之一是因为你的错误代码将无法编译。
- 如何在 c++ 中'NULL'字符串
- 当字段可以为null时,如何使用C++接口在Avro中写入数据
- 如何在映射中返回null
- 构造函数中的 QQuickItem 父项 null
- fopen 在 gdb 中返回 NULL
- 在这个函数中是有缺陷的,因为取消引用 null 是无效的,所以我想更改代码
- 为什么在C++中增加指针后打印了一个值而不是 NULL/0?
- 如果我在相应 char 数组的声明中为其提供额外的元素,是否会自动设置 NULL?
- 在 C++ Builder 中使用 NULL 构造 DynamicArray
- 如何在 C++ 中使用 NULL(或 0)初始化静态字符数组
- 指针永远不会在链表深层复制构造函数中达到 null
- 如何在 Visual C++ 中从返回类型为 map 的函数返回 null?
- 在只读方案中,何时需要以 null 结尾的字符串?
- 如何在C++中返回Null作为引用
- &*NULL 在C++中是否定义良好?
- 为什么在C++中使用delete后指针不为NULL
- C++中的指针否定 (!ptr == NULL)
- 赋值null中的不兼容类型
- "- < /dev/null"在"gcc -dM -E - < /dev/null"中是什么意思?
- 不初始化指针和将指针初始化为null的区别是什么?