我需要找到结构数组中的元素数
我有这个结构
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++
cout << (sizeof feature / sizeof *feature) << endl;
Run Code Online (Sandbox Code Playgroud)
应该
cout << (sizeof(feature) / sizeof(*feature)) << endl;
Run Code Online (Sandbox Code Playgroud)
注意括号。遗憾的是,由于几个原因,它无法告诉您您想要什么。
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)
不是其中之一。当您必须将二维数组传递给函数时,请记住这一点。
根据大小,我们可以像上面那样计算容量,但坦率地说,这是一个愚蠢的赌注。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为你做各种很酷的事情,比如调整自己的大小并计算实际使用了多少。此外,与典型的指针和动态数组方法不同,它符合三规则。三分法则是什么?嗯,这真的很重要。我建议阅读链接。
要定义vector的Features
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.
为了获得数量Features在feature
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)
现在你必须维护capacity,num_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)
替换feature为bigger_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)