【问题标题】:Get the number of elements in a struct array c++获取结构数组c ++中的元素数
【发布时间】:2016-03-17 00:56:50
【问题描述】:

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

我有这个结构

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++

【问题讨论】:

  • 数组的大小将始终为 100 个元素。请改用std::vector。
  • 数组的大小将始终为 100,指针的大小将始终为 4 ,或者在 64 位寻址的机器上为 8。
  • C 不是 C++ 不是 C!而*feature 是一个指针,而不是一个数组。
  • 重要提示:因为feature 是一个指针,所以无论它指向多少东西,它的大小始终是指针的大小。

标签: c++ arrays struct


【解决方案1】:
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 / &lt;anything greater than 4&gt; 将被截断为 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;

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

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

The preferred C++ solution is to use std::vector。 vector 为您做了各种很酷的事情,比如调整自身大小并计算实际使用了多少。此外,与典型的指针和动态数组方法不同,它符合三规则。 What is The Rule of Three? 这真的很重要。我建议阅读链接。

定义vector 的Features

std::vector<Features> feature;

存储Feature

Feature temp;
feature.push_back(temp);

通常更好的方法是为Feature 和

定义一个构造函数
feature.emplace_back(feature1, feature2, feature3, feature4, feature5);

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

获取Features中feature的数量

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;

现在您必须维护capacity 和num_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;

【讨论】:

  • 这是一个了不起的答案,感谢您花时间写出来
  • 很高兴看到一个答案,而不是谴责 OP 做错了,实际上回答了这个问题。
【解决方案2】:

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

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

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

【讨论】:

    【解决方案3】:

    您需要跟踪它。当您为 100 个功能分配了足够的空间时,您得到的正是……足够的空间用于 100 个功能。跟踪您随后初始化了多少等是您需要做的事情。

    【讨论】:

      【解决方案4】:

      我确定它正在按程序打印正确的值。但是sizeof 只告诉你分配了多少空间,而不告诉你有多少成员包含有意义的值。

      如果您想要一个可变大小的数组,请使用 std::vector。否则,请保留您的设置,但将成员(例如 feature1)初始化为可识别的值(例如 -999 或您不会期望有意义地使用的其他值),然后查看在找到之前可以循环多远那个值;

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-01-07
        • 1970-01-01
        • 2019-03-08
        • 1970-01-01
        • 2021-09-20
        相关资源
        最近更新 更多