3

私は C++ を勉強していて、構造を作成して操作する必要がありますAirplane

私の構造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 << "\n\n";
    for (int i = 0; i < n; ++i)
    {
        cout << "Destination: " << airplaneList[i].destination << "\n";
        cout << "Number: " << airplaneList[i].number << "\n";
        cout << "Type: " << airplaneList[i].type << "\n\n";
    }
}

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 found\n";
    }
}

2 つの質問があります。
1. 入力できない

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

私の関数FindAirplanesAndPrintは、型の値なしで機能し始めます。プログラムを作成して価値を得る方法は?
2. 関数内の動的配列のサイズを取得する方法は? すべての関数で配列のサイズを渡すn方法が間違っているようです。

4

6 に答える 6

3

1) 関係のないものを省略して、これは基本的にあなたが得たものです:

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

operator>>入力バッファに改行文字を残し、それが最初に表示される文字ですgetline'\n'がデフォルトの行区切り文字であるため、空行になります。cin.ignore()を呼び出す前にそれを修正するにgetlineは、'\n'.

2) 生のポインターに固執したい場合は、サイズをパラメーターとして渡すことが唯一の選択肢です。に切り替えると、いつでもクエリできるメソッドがstd::vector得られます。size()

于 2013-10-14T13:49:24.220 に答える
0

C++ で動的に割り当てられた配列のサイズを調べることはできません。

これは実際には完全に正しいわけではありません。特定の種類のサイズ取得 (デストラクタを持つオブジェクトの配列のサイズ) が広くサポートされています。

ただし、これを使用することを検討している人には、私の知る限り、これは標準またはコンパイラのベンダーによって保証されていないことを警告する必要があります。いつでも変更される可能性があり、趣味のプロジェクト以外には依存しないでください。

破壊可能なオブジェクトの配列のサイズは、オブジェクト自体の直前に格納され、基本的なポインター キャストでアクセスできます((size_t*)mem)[-1]

あなたがそれについて考えるとき - あなたが呼び出すときdelete []、あなたは配列のサイズを渡していませ.ポインター自体。ただし、要素の数でなければならないという保証はありません。バイト数またはエンドポインターの場合もあり、フラグビットが混在している可能性があります。後で変更するために、ある種の後方互換性を壊す可能性があります。

これをテストすることに興味がある人のために、コードは次のとおりです: 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("%zu\n", ((size_t*)new bytes10[5])[-1]);
    printf("%zu\n", ((size_t*)new bytes10[6])[-1]);
    printf("%zu\n", ((size_t*)new bytes10[7])[-1]);
    printf("%zu\n", ((size_t*)new bytes10[65536])[-1]);
    return 0;
}

可能な出力 (最初の値は異なる場合があります):

49 (0x31)
5
6
7
65536

PS私の見解では、C++委員会は、すべてのnew[]割り当ての配列サイズへのアクセスを標準化するか、サイズプレフィックスを保証できる新しいタイプのnew-like演算子を提供することを検討する必要があります。new[]これには、より低いレベルのコード (たとえば、はるかに簡単な単一ポインターの不変文字列)の特定の使用を可能にする力があります。

于 2021-07-18T06:10:28.283 に答える