检查动态数组中是否确实存在值?C++

Check if value really exists in a dynamic array? c++

本文关键字:存在 C++ 动态 数组 是否 检查      更新时间:2023-10-16

我想知道是否有办法在C++中检查动态数组的值是否真的存在。

int *x = new int[5];

好的,所以我认为默认情况下 x 的每个值都将为 0。但是,问题是,当我用值填充它时,我实际上可能会输入 0。因此,这将导致混淆什么告诉我们值是否真的存在(0 似乎是告诉我们它是 NULL 的成语,但在这种特殊情况下我不能使用该习语,因为 0 可能是给我的值)。

有没有另一种方法可以检查动态数组中的值是否未定义?

首先,正如乔纳森所说,不能保证数组将被初始化为 0 。您可以单独初始化它,也可以使用int *x = new int[5]();为您进行初始化。

至于你怎么知道哪些是有效的。最简单的方法是存储结构而不是int。像这样:

struct T {
    T() : valid(false), value(0) {
    }
    bool valid;
    int  value;
};
T *p = new T[5]; // each element will be initialized to false/0 because T has a constructor.

然后你可以做:

p[0].value = 10;
p[0].valid = true;

等等。

编辑:作为更高级的选项,您可以使用运算符重载使 valid 标志自动设置,如下所示:

struct T {
    T() : valid(false), value(0) {
    }
    T &operator=(int x) {
        valid = true;
        value = x;
        return *this;
    }
    bool valid;
    int  value;
};
T *p = new T[5]; // each element will be initialized to false/0 because T has a 
p[1] = 10;       // p[1] is now true/10

基本上,为元素分配一个整数值会自动将其标记为有效。尽管在这个特定示例中,我尚未演示如何将值"取消设置"回"无效"。这对您的用例或编码风格可能有意义,也可能没有意义,只是一些值得深思的东西。

如果它是动态分配的,它不会为你归零;你必须通过将所有条目设置为某个默认值来自己初始化数组。如果零是有效条目,则考虑使用负数。 如果所有正值和负值都是有效条目,则考虑使用包含整数值的结构,以及初始化为 false 的布尔标志。

在 C 语言中,这将是:

typedef struct {
    bool valid;
    int  value;
} node;
node x[] = new node[5];

如果你不能牺牲一个值,比如说,最小的负值或最大的正int,表示"未设置",你需要跟踪侧面设置的内容。在C++您可以使用std::vector<bool>

int *x  = new int[5];
std::vector<bool> isSet(5, false);
if (!isSet[3]) {
    x[3] = 123;
    isSet[3] = true;
}

如果您要使用的值将是密集/连续的,请使用std::vector(其size()成员将告诉您当前有效的项目数)。如果值稀疏,请改用std::set

无论哪种方式,你最好忘记new T[size]存在,更不用说让自己受到实际使用它的疯狂

我不会对这项工作使用动态数组,因为正确管理资源涉及许多复杂性。在我看来,你应该看看std::vector,这会把你的代码变成这样的东西:

#include <vector>
...
    std::vector<int> x();
    x.resize(5);

现在,这将使您能够不再担心资源管理是婊子,而是专注于真正重要的事情(即处理您的 Xses)。

但是,问题是,当我用值填充它时,我实际上可能会输入 0。因此,这将导致混淆什么告诉我们该值是否真的存在

对于"0"是否真的存在没有混淆。如果数组中有您没有放在那里的 0,它仍然存在。恰好在数组中的零和你放在那里的零之间没有区别。如果您需要区分已为其赋值的元素与未初始化的元素,则必须在其他地方跟踪该信息。

bool *b = new bool[5](); // initialize the array to all false
int *x = new int[5]; // don't initialize the array
x[3] = 0; // set the fourth element in the array to 0
b[3] = true; // record that the fourth element in the array has been set
(注意,你不应该使用

原始数组,你不应该使用new/delete)


int *x = new int[5];

好的,所以我认为默认情况下 x 的每个值都将为 0。

不是你构造该数组的方式;数组中的任何int都没有初始化。它们可以有任何价值。通常,当您在"调试"模式下构建内存时,内存将自动为您初始化零,但这不是由C++指定的。

除了我的其他答案之外,如果您认为有效索引会很稀疏,另一种方法是使用 std::map 作为关联数组,如下所示:

std::map<int, int> x;
x[0] = 10;
x[2] = 123;
// indexes 0 and 2 are set, the rest do not exist.

要测试某个值是否预设,只需执行以下操作:

if(x.find(n) != x.end()) {
    // there is a value at index n
} else {
    // no value found at index n
}

如果你的有效索引是连续的,你不妨用std::vector,或者我的原始答案。