如何获取大小 c++ 动态数组

How to get size c++ dynamic array

本文关键字:c++ 动态 数组 何获取 获取      更新时间:2023-10-16

我正在学习C++,我需要创建结构Airplane并使用它。

我的结构飞机.h

#include "stdafx.h"
using namespace std;
struct Airplane {
    string destination;
    int number;
    string type;
};

这是我的代码

#include "stdafx.h"
#include "Airplane.h"
string SetDestination(int n);
string SetType(int n);
void PrintAirplaneList(Airplane * &airplaneList, int n, string title);
void SortByDestination (Airplane *&airplaneList, int n);
void FindAirplanesAndPrint(Airplane *&airplaneList, int n, string type);
int _tmain(int argc, _TCHAR* argv[])
{
using namespace std;
srand((unsigned)time(NULL));
int n;
cout << "Input n = ";
cin >> n;
Airplane * airplaneList = new Airplane[n];
for (int i = 0; i < n; ++i)
{
    airplaneList[i].destination = SetDestination(rand()%5);
    airplaneList[i].number = rand()%9001 + 1000;
    airplaneList[i].type = SetType(rand()%3);
}
PrintAirplaneList(airplaneList, n, "List:");
SortByDestination (airplaneList, n);
PrintAirplaneList(airplaneList, n, "Sorted list (by destination):");
string type;
cout << "Input type: ";
getline(cin, type);
FindAirplanesAndPrint(airplaneList, n, type);
delete [] airplaneList;
system("PAUSE");
return 0;
}
string SetDestination (int n)
{
    string destination;
    switch(n){
    case 0: destination = "Tokio"; break;
    case 1: destination = "Amsterdam"; break;
    case 2: destination = "Moscow"; break;
    case 3: destination = "Philadelphia"; break;
    case 4: destination = "San Diego"; break;
    default: destination = "Unknown city"; break;
    }
    return destination;
}
string SetType (int n)
{
    string type;
    switch(n){
    case 0: type = "passenger"; break;
    case 1: type = "cargo"; break;
    case 2: type = "post"; break;
    default: type = "unknown type"; break;
    }
    return type;
}
void PrintAirplaneList(Airplane *&airplaneList, int n, string title)
{
    cout << "n";
    cout << title << "nn";
    for (int i = 0; i < n; ++i)
    {
        cout << "Destination: " << airplaneList[i].destination << "n";
        cout << "Number: " << airplaneList[i].number << "n";
        cout << "Type: " << airplaneList[i].type << "nn";
    }
}
void SortByDestination (Airplane *&airplaneList, int n)
{
    for (int i = 0; i < n - 1; ++i)
    {
        for (int j = 0; j < n -1; ++j)
        {
            if(airplaneList[j + 1].destination > airplaneList[j].destination) continue;
            Airplane tempAirplane = airplaneList[j];
            airplaneList[j] = airplaneList[j + 1];
            airplaneList[j + 1] = tempAirplane;
        }
    }
}
void FindAirplanesAndPrint(Airplane *&airplaneList, int n, string type) {
    cout << "Type - " << type << "n";
    int count = 0;
    for (int i = 0; i < n; ++i)
    {
        if (airplaneList[i].type == type)
        {
            cout << "Destination: " << airplaneList[i].destination << "n";
            cout << "Number: " << airplaneList[i].number << "n";
            ++count;
        }
    }
    if (count == 0)
    {
        cout << "Not foundn";
    }
}

我有两个问题。
1. 我无法输入输入

string type;
cout << "Input type: ";
getline(cin, type);
FindAirplanesAndPrint(airplaneList, n, type);

我的函数FindAirplanesAndPrint开始工作,没有任何类型值。 如何让我的程序获得价值?
2. 如何获取函数中动态数组的大小?因为似乎每个函数中数组n的传递大小都是错误的方式。

"如何获取函数中动态数组的大小?因为似乎每个函数中数组n的传递大小都是错误的方式。

然而,这是使用动态分配的 C 样式数组时的唯一方法。

如果要避免显式发送大小,请传递一些包装此原始内存缓冲区并提供其他检索大小的方法的对象。这里最合理的解决方案是使用 std::vector<Airplane> .

1)省略不相关的内容,这基本上就是你得到的:

cin >> n;
getline(cin, type);

operator>>在输入缓冲区中留下一个换行符,这是getline看到的第一个字符。由于'n'是默认的行分隔符,因此您将获得一个空行。要修复它,请在调用getline之前调用cin.ignore()以丢弃'n'

2)如果您希望坚持使用原始指针,将大小作为参数传递是您唯一的选择。切换到std::vector,您将获得size()可以随时查询的方法。

输入类型的问题是输入缓冲区在输入 n 后包含换行符。在使用函数 getline 之前,应使用成员函数忽略来清除缓冲区。

至于您的第二个问题,那么一般来说,您应该自己跟踪动态分配的数组的大小。或者,您可以将数组的最后一个元素设置为 NULL 并将其用作哨兵。

您可能可以创建一个包含 0 个项目的动态数组,创建一个 int 计数器,使用 getline 作为语句进行 while 循环,而 (getline(cin, string_var) != SomeText)/* SomeText = 某种文本,以便用户向您展示不会再有任何输入*/,您将在 for 中做什么 在 while 和 while 结束时将计数器增加一个, i++。关于对数组的访问,如果你的动态数组有 0 个项目,那么 SomeDynamicArray[1].something = SomeValue 将只向数组添加第二个项目,并且该项目的"某些东西"将等于 SomeValue。

type *ArrayPointer = new type[0];
string StringVar;
int i = 0;
while (getline(cin, StringVar) != "Text that show there are not going to be any more inputs") {
     /*code*/
     i++;
} 

idk 如果它可以处理您的情况,但如果您愿意,请尝试一下。此外,关于每个人都在谈论向量,至少据我所知,向量更慢并且花费更多内存,bcs 它们的大小加倍,而不仅仅是每次需要时增加它。我希望我能有所帮助。

我在

处理动态数组时使用的一种方法是将数组作为对函数的引用传递。这将帮助您保留数组的大小信息。

例如:

string list1[3] = {
    "item1",
    "item2",
    "item3"
};
string list2[2] = {
    "item1",
    "item2"
};
template<typename T, size_t N>
void PrintItems(T(&items)[N]) {
    for (int i = 0; i < N; i++) {
        cout << items[i] << endl;
    }
}
int main() {
    PrintItems(list1);
    PrintItems(list2);
}

在前面的示例中,N 存储数组的正确大小信息。更多信息在这里

您无法通过 C++ 找出动态分配的数组的大小。

这实际上并不完全正确。广泛支持一种特定类型的大小检索 - 具有析构函数的对象数组的大小。

然而,对于任何考虑使用它的人 - 我必须警告你,据我所知,任何标准或编译器供应商都不以任何方式保证这一点。它可能在任何时间点发生变化,除了爱好项目之外,不应依赖任何其他内容。

可破坏对象数组的大小存储在对象本身之前,并且可以使用基本指针强制转换进行访问:((size_t*)mem)[-1]

当你考虑它时 - 当你调用delete []时,你没有传递数组的大小,所以C++必须以某种方式存储确切的大小,以了解调用析构函数的对象数量,以一种可以从指针本身简单有效地访问的方式。但是 - 不能保证它必须是元素的数量 - 它也可以是字节数或结束指针,可能混合了一些标志位。也就是说,一旦他们决定了一个约定,它可能会破坏某种向后兼容性,以便以后更改它。

对于那些有兴趣测试它的人,这是代码:https://ideone.com/Z0Sta1

#include <stdio.h>
struct bytes10
{
    ~bytes10() { printf("dtor %p", this); }
    char _[10]; // to test whether the size or the count is returned
};
int main()
{
    size_t size1 = ((size_t*)new int[10])[-1]; // doesn't work (pointer on some platforms, allocation size-based number on others)
    printf("%zu (0x%zx)n", size1, size1);
    printf("%zun", ((size_t*)new bytes10[5])[-1]);
    printf("%zun", ((size_t*)new bytes10[6])[-1]);
    printf("%zun", ((size_t*)new bytes10[7])[-1]);
    printf("%zun", ((size_t*)new bytes10[65536])[-1]);
    return 0;
}

可能的输出(第一个值可能不同):

49 (0x31)
5
6
7
65536
<小时 />

附言在我看来,C++委员会应该考虑标准化对所有new[]分配的数组大小的访问,或者提供一种能够保证大小前缀的新型类似new运算符。这有能力允许对较低级别的代码使用某些new[](例如,更简单的单指针不可变字符串)。