获取结构数组 c 中的元素个数

新手上路,请多包涵

我需要找到结构数组中的元素数

我有这个结构

struct Features {
    int feature1;
    string feature2;
    string feature3;
    string feature4;
    bool feature5;
};

然后我把它变成了一个数组

Features *feature = new Features[100];

然后我输入了一些值

for(int i = 0; i < 3; i++)
{
    feature[i].feature1 = 5;
    feature[i].feature2 = "test";
    feature[i].feature3 = "test2";
    feature[i].feature4 = "test3";
    feature[i].feature5 = true;
}

现在我想得到数组的大小,应该是 3 (2)

我该怎么做呢?

 cout << (sizeof feature / sizeof *feature) << endl;

似乎不起作用,因为它打印了不正确的值。 (它继续打印4)

对不起,如果这是一个愚蠢的问题,我还在学习 C++

原文由 jLynx 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 706
2 个回答

不,实际上数组的大小是 100,而不是 3,因为您使用 new 分配了一个 100 元素数组。您在数组中初始化 3 个元素的事实并不重要。它仍然是一个 100 个元素的数组。

但无论是 3 还是 100,都无所谓。跟踪分配数组的大小由您决定。 C++ 不适合你。

但是,如果您确实希望 C++ 跟踪数组的大小,请使用 std::vector 。这就是它的用途。

原文由 Sam Varshavchik 发布,翻译遵循 CC BY-SA 3.0 许可协议

cout << (sizeof feature / sizeof *feature) << endl;

应该

cout << (sizeof(feature) / sizeof(*feature)) << endl;

注意括号。遗憾的是,由于几个原因,它无法告诉您您想要什么。

  1. feature 是一个指针。

指针是存储中的一个位置,一个地址,并且您可能遇到的任何系统上的所有地址系统都将具有相同的大小,并且可能是 4 或 8 个字节。让我们暂时假设 4 并将其代入等式。

 cout << (4 / sizeof(*feature)) << endl;

这肯定会打印 0,因为 *feature 肯定大于 4 并且在整数数学中 4 / <anything greater than 4> 将被截断为 0。

如果定义 feature

 Features feature[100];

除非需要更改指向的数据块的大小,否则没有理由不更改。无论如何,现在功能不仅仅是指向某个任意内存块的指针。它正好是 100 块 Features 。它的大小为 100 * sizeof(feature[0])。这是数组和指针之间的根本区别,所以下次有人告诉你“数组是指针!”你可以叫他们去 骂人删除 自己。

例如:

 cout << (sizeof(feature) / sizeof(feature[0])) << endl;

将打印 100,而不是当 feature 是指针时我们返回的 0。 0 != 100。数组不是指针。在很多情况下,数组可以像指针一样 _使用_。

 Feature feature2d[100][100];
Feature ** feature2dptr = feature2d;

不是其中之一。当您必须将二维数组传递给函数时,请记住这一点。

  1. 数组知道它的大小,但不知道使用了多少。

从大小我们可以像上面那样计算容量,但坦率地说,这是一个愚蠢的赌注。 feature 可以定义

constexpr int MAX_FEATURES = 100;
Features feature[MAX_FEATURES];

然后不是这个:

 cout << (sizeof(feature) / sizeof(feature[0])) << endl;

我们打印出不那么复杂的

cout << MAX_FEATURES << endl;

但这仍然不是我们想要的。

那么我们如何正确地做到这一点呢?

首选的 C++ 解决方案是使用 std::vectorvector 为你做各种很酷的事情,比如调整自己的大小并计算实际使用了多少。此外,与典型的指针和动态数组方法不同,它符合三规则。 什么是三法则? 嗯,这真的很重要。我建议阅读链接。

定义一个 vectorFeatures

 std::vector<Features> feature;

存储一个 Feature

 Feature temp;
feature.push_back(temp);

通常更好的方法是为 Feature

feature.emplace_back(feature1, feature2, feature3, feature4, feature5);

因为这消除了创建和复制临时 Feature 的需要。

获取 Featuresfeature 的数量

feature.size();

很简单吧?

好的。所以有些人认为你不应该使用 vector 直到你年纪大了,更有经验了。他们希望你在学习编写一个体面的、结构良好的程序并弄清楚如何调试新程序员所犯的小错误时,经历内存管理的陷阱。我对此并不失望,但这似乎是统治这片土地的教育范式。

让我们从固定数组开始,因为它简单且不那么复杂。

 constexpr int MAX_FEATURES = 100;
Features feature[MAX_FEATURES];
int num_features = 0;

每次需要向阵列添加 Feature 时,首先要确保有空间。

 if(num_features < MAX_FEATURES)

然后添加 Feature

 feature[num_features] = new_feature;

然后递增,加一, num_features

 num_features++;

你有多少 Features

 cout << num_features << endl;

如果您绝对必须使用指针执行此操作

int capacity = 100;
Features * feature = new Feature[capacity];
int num_features = 0;

现在你必须维护 capacitynum_features 因为你会做这种愚蠢的事情的唯一原因是能够调整内存块的大小 feature 指向所需.

 if(num_features >= MAX_FEATURES)
{

做大 feature

     capacity = capacity * 1.5; // why 1.5? Because I felt like it.
    Features * bigger_feature = new Features[capacity];

将所有内容从 feature 复制到 bigger_feature

     for (int index = 0; index < num_features; index++
    {
        bigger_feature[index] = feature[index];
    }

释放 feature 使用的内存

    delete[] feature;

feature 替换为 bigger_feature

     feature = bigger_feature;
}

现在你可以

feature[num_features] = new_feature;
num_features++;

这又是一个漂亮的可剪切粘贴的 blob:

 if(num_features == MAX_FEATURES)
{
    capacity = capacity * 1.5; // why 1.5? Because I felt like it.
    Features * bigger_feature = new Features[capacity];
    for (int index = 0; index < num_features; index++
    {
        bigger_feature[index] = feature[index];
    }
    delete[] feature;
    feature = bigger_feature;
}
feature[num_features] = new_feature;
num_features++;

废话。而且这个指针杂乱无章绝对不符合三规则,因此您可能必须编写复制和移动构造函数、赋值和移动运算符以及析构函数。

最后,当你完成时,你必须

delete[] feature;

你有多少 Features

 cout << num_features << endl;

原文由 user4581301 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏