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

jLy*_*ynx 1 c++ arrays struct

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

我有这个结构

struct Features {
    int feature1;
    string feature2;
    string feature3;
    string feature4;
    bool feature5;
};
Run Code Online (Sandbox Code Playgroud)

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

Features *feature = new Features[100];
Run Code Online (Sandbox Code Playgroud)

然后我输入了一些值

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;
}
Run Code Online (Sandbox Code Playgroud)

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

我该怎么做呢?

cout << (sizeof feature / sizeof *feature) << endl;
Run Code Online (Sandbox Code Playgroud)

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

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

use*_*301 5

cout << (sizeof feature / sizeof *feature) << endl;
Run Code Online (Sandbox Code Playgroud)

应该

cout << (sizeof(feature) / sizeof(*feature)) << endl;
Run Code Online (Sandbox Code Playgroud)

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

  1. feature 是一个指针。

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

cout << (4 / sizeof(*feature)) << endl;
Run Code Online (Sandbox Code Playgroud)

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

如果feature被定义

Features feature[100];
Run Code Online (Sandbox Code Playgroud)

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

例如:

cout << (sizeof(feature) / sizeof(feature[0])) << endl;
Run Code Online (Sandbox Code Playgroud)

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

Feature feature2d[100][100];
Feature ** feature2dptr = feature2d;
Run Code Online (Sandbox Code Playgroud)

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

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

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

constexpr int MAX_FEATURES = 100;
Features feature[MAX_FEATURES];
Run Code Online (Sandbox Code Playgroud)

然后而不是这个:

cout << (sizeof(feature) / sizeof(feature[0])) << endl;
Run Code Online (Sandbox Code Playgroud)

我们打印少得多的复杂

cout << MAX_FEATURES << endl;
Run Code Online (Sandbox Code Playgroud)

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

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

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

要定义vectorFeatures

std::vector<Features> feature;
Run Code Online (Sandbox Code Playgroud)

存储一个 Feature

Feature temp;
feature.push_back(temp);
Run Code Online (Sandbox Code Playgroud)

通常更好的方法是为Feature和定义一个构造函数

feature.emplace_back(feature1, feature2, feature3, feature4, feature5);
Run Code Online (Sandbox Code Playgroud)

因为这消除了创建和复制临时Feature.

为了获得数量Featuresfeature

feature.size();
Run Code Online (Sandbox Code Playgroud)

很简单吧?

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

让我们从固定数组开始,因为它很简单,也没有那么复杂。

constexpr int MAX_FEATURES = 100;
Features feature[MAX_FEATURES];
int num_features = 0;
Run Code Online (Sandbox Code Playgroud)

每次需要向Feature数组中添加 a 时,首先要确保有空间。

if(num_features < MAX_FEATURES)
Run Code Online (Sandbox Code Playgroud)

然后添加 Feature

feature[num_features] = new_feature;
Run Code Online (Sandbox Code Playgroud)

然后递增,加一,num_features

num_features++;
Run Code Online (Sandbox Code Playgroud)

Features你有几个?

cout << num_features << endl;
Run Code Online (Sandbox Code Playgroud)

如果你绝对必须用指针来做这件事

int capacity = 100;
Features * feature = new Feature[capacity];
int num_features = 0;
Run Code Online (Sandbox Code Playgroud)

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

if(num_features >= MAX_FEATURES)
{
Run Code Online (Sandbox Code Playgroud)

做一个更大的 feature

    capacity = capacity * 1.5; // why 1.5? Because I felt like it.
    Features * bigger_feature = new Features[capacity];
Run Code Online (Sandbox Code Playgroud)

复制从feature到的所有内容bigger_feature

    for (int index = 0; index < num_features; index++
    {
        bigger_feature[index] = feature[index];
    }
Run Code Online (Sandbox Code Playgroud)

释放所使用的内存 feature

    delete[] feature;
Run Code Online (Sandbox Code Playgroud)

替换featurebigger_feature

    feature = bigger_feature;
}
Run Code Online (Sandbox Code Playgroud)

现在你可以

feature[num_features] = new_feature;
num_features++;
Run Code Online (Sandbox Code Playgroud)

这是一个漂亮的可剪切和粘贴的斑点:

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++;
Run Code Online (Sandbox Code Playgroud)

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

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

delete[] feature;
Run Code Online (Sandbox Code Playgroud)

Features你有几个?

cout << num_features << endl;
Run Code Online (Sandbox Code Playgroud)