簡體   English   中英

聲明沒有大小的 c++ 數組

[英]Declaring c++ array without size

如果我在 visual studio 代碼或其他在線編譯器上聲明一個數組而沒有提及它的大小,那么它可以正常工作,但是如果我在 visual studio 中使用相同的代碼,那么它就不起作用。 我知道聲明未知大小的數組是不正確的,但由於不使用指針或任何其他東西的情況,我不得不使用它。 在 visual studio 上,當我只制作鏈接和網頁 class 時,我就開始工作了。

誰能告訴我該怎么做。

#include <iostream>
using namespace std;
class link
{
    const char* name;
public:
    link() :name("null")
    {
        cout<<"Default link constructor called"<<endl;
    };
    link(const char n[]) :name(n)
    {
        cout<< "Parameterized link constructor called"<<endl;
    };
};
class webpage
{
private:
    double height;
    double width;
    int linkno;
    link links[];
public:
    webpage() :height(10), width(10), linkno(2)
    {
        links[0]=NULL;
        links[1]=NULL;
    };
    webpage(double hw,int lno, link hyperlinks[]) :height(hw), width(hw),linkno(lno)
    {
        for (int i = 0; i < linkno; i++)
        {
            links[i]=hyperlinks[i];
        }
    };
    webpage(double h, double w,int lno, link hyperlinks[]) :height(h), width(w),linkno(lno)
    {
         for (int i = 0; i < linkno; i++)
        {
            links[i]=hyperlinks[i];
        }
    };
    void showdata(int linkno)
    {
        cout << "height: " << height << endl;
        cout << "width: " << width << endl;
        cout << "links " << endl;
        for (int i = 0; i < linkno; i++)
        {
            cout << "link #" << i + 1 << " = " << links[i].getname() << endl;
        }
    }
};
class website
{
private:
    const char* name;
    int webpageno;
    webpage wpgs[];
public:
    website() :name("null"),webpageno(4)
    {
        wpgs[0];
        wpgs[1];
        wpgs[2];
        wpgs[3];
    };
    website(const char n[],int wpn, webpage page[]) :name(n),webpageno(wpn)
    {
        for (int i = 0; i < webpageno; i++)
        {
            wpgs[i]=page[i];
        }
        
        cout<<"Parameterized website constructor called"<<endl;
    };
    void showdata(int linkno, int pageno)
    {
        cout << endl<< "Website name: " << name << endl;
        for (int j = 0; j < pageno; j++)
        {
            cout << "Webpage #" << j + 1 << " : " << endl;
            wpgs[j].showdata(linkno);
            cout<<endl<<endl;
        }
    }
};
int main(int argc, char* argv[])
{
  link link1[2]={"maha","saira"};
  webpage page[1]={{32,21,2,link1}};
    website site("my website",1,page);
    site.showdata(2,1);
}

在 visual studio 上,當我只制作鏈接和網頁 class 時,我就開始工作了。

使用 C++ 容器或指針。

  1. 我推薦使用std::vector , std::list , ...
  2. 指針: link* links ,然后在需要的地方使用new link[100]delete[] links
  3. 智能指針: shared_ptr<link[]> sp(new link[10]);

作為評論說明,這是https://en.wikipedia.org/wiki/Flexible_array_member

Windows API 在幾個地方使用了這個技術。 因此,Visual Studio 支持 C++,如https://learn.microsoft.com/en-us/cpp/cpp/arrays-cpp?view=vs-2019中所述

只有當數組是結構或聯合中的最后一個字段並且啟用了 Microsoft 擴展 (/Ze) 時,零大小數組才合法。

然而,使用這種技術的訣竅在於,無論誰創建 object,都必須在其后分配 memory,以便非大小數組擴展到其中。 否則使用該數組會導致損壞 memory 用於其他目的。

所以按照你的方式使用它是不正確的。 您的程序沒有表現出奇怪的行為或崩潰只是偶然。

作為評論說明,您應該使用std::vector或其他適合您需要的此類容器。

非靜態成員數組不能有未指定的大小。 只有 static arrays 可以聲明為未指定大小。 然后必須在定義中指定大小,它仍然是編譯時常量。

如果你需要的是一個運行時大小的數組,那么這個數組就需要動態分配。 最簡單的解決方案是使用std::vector

它工作正常但是

無論如何,該程序格式錯誤。 當一個格式錯誤的程序編譯時,通常是因為您使用了語言擴展。 當您使用語言擴展時,該程序將無法與未實現相同擴展的編譯器一起工作。

為了保持程序的可移植性,應該避免使用語言擴展。

我對該問題進行了一些調查,發現它是 c++ 設計的一團糟,或者可能是擴展設計(無論您說什么)。

看看下面的代碼(它工作正常):

#include <iostream>

using namespace std;

class Test {
private:
    int n;
    int buf[];
public:
    Test() : n(0) {}
    Test(int _n, int* _buf) : n(_n) {
        for(int i=0; i<n; i++) {
            buf[i] = _buf[i];
        }
    }
    void print() {
        printf("array:");
        for(int i=0; i<n; i++) {
            printf(" %d", buf[i]);
        }
        printf("\n");
    }
};

int main() {
    int n = 100;
    int b[128];
    for(int i=0; i<n; i++) {
        b[i] = i;
    }
    Test t = {n, b};
    t.print();
    return 0;
}

現在,看看下面的另一個代碼段,做了一些改動(它根本沒有運行):

#include <iostream>

using namespace std;

class Test {
private:
    int n;
    int buf[];
public:
    Test() : n(0) {}
    Test(int _n, int* _buf) : n(_n) {
        for(int i=0; i<n; i++) {
            buf[i] = _buf[i];
        }
    }
    void print() {
        printf("array:");
        for(int i=0; i<n; i++) {
            printf(" %d", buf[i]);
        }
        printf("\n");
    }
};

int main() {
    int n = 100;
    
    // int b[128];
    
    // rather than declaring array
    // using dynamic memory allocation technique
    int *b = (int *)malloc(sizeof(int) * 128); // everything same, just this line is changed
    for(int i=0; i<n; i++) {
        b[i] = i;
    }
    
    Test t = {n, b};
    t.print();
    
    free(b);

    return 0;
}

當使用new運算符代替malloc()時,它是一樣的。

我想暗示的是,這是編譯器(或 cpp 語言的編譯器擴展)的一個非常糟糕的設計決策。 你不應該在這種結構中編寫你的代碼。

您可以根據需要使用向量、列表或您自己的數據結構,這仍然是比您現在正在做的任何事情更好的選擇。 Vector將是最有效的解決方案。

[PS]: 如上所述,看到這里就明白了,為什么有的編譯器可以編譯你的代碼,有的不能。

我已經使用 mingw 進行了測試。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM