ファイルマネージャをプログラムしようとしていて、サブフォルダの配列を含むフォルダを使用したいとします。私はstructの型を含む構造体を宣言しています
struct folder {
char* name;
struct folder subfolders [10];
}
のようなものを考えていた
は、どのような方法でそのpossbileですか?
ファイルマネージャをプログラムしようとしていて、サブフォルダの配列を含むフォルダを使用したいとします。私はstructの型を含む構造体を宣言しています
struct folder {
char* name;
struct folder subfolders [10];
}
のようなものを考えていた
は、どのような方法でそのpossbileですか?
はありません、あなたがこれを行うことはできません、あなたはこれを実行する必要があります。
struct folder {
char* name;
struct folder *subfolders [10];
}
は今タイプ
struct folder
の変数の型
struct folder
の変数に10の
ポインタが含まれています。
先に進む前に、ポインタと動的メモリ割り当てに精通する必要があります。
類似の概念を使用するリンクリストとバイナリツリーを最初に調べます。ウェブ上にたくさんの例とチュートリアルがあります(Googleの "リンクリストの例")。
あなたのソリューション:各struct folder
は再び10 struct folder
が含まれますので、
struct folder {
char* name;
struct folder subfolders [10];
}
は10 struct folder
が含まれているというように無限大まで考え、それぞれが、意味がありません。
しかし、あなたのコンセプトでは、各フォルダには10個のサブフォルダしか含めることができません。
短い答えははいです。その効果が働くものがあります。 struct folder parentfolder
を追加して、上から下に移動できるようにすることもできます。
いいえ、struct
型には同じ型の配列を含めることはできません(型は一般的に不完全と診断されるため)。さらに、その型のすべての変数に同じ型のメンバーが1つ以上含まれていると、型定義は無限に再帰的になります(AにはAを含むA .....)。
しかし、struct
タイプポインタ
struct folder1
{
char* name;
struct folder1 *a_subfolder;
};
またはポインタのアレイの両方の場合において
struct folder2
{
char* name;
struct folder2 *subfolders [10];
};
、論文タイプがポインタであることを確認するために世話をする必要が使用するコードを含むことができ正しく初期化されていること、(例えば、初期化されていないポインタの値にアクセスしようとしていない、NULLを参照解除していないなど)賢明に処理されていることを示します。この種の構造を使う前にポインタを読んでください。ポインタで間違ってしまうのは、しばしば厄介な方法でクラッシュするプログラムを意味します。
"不完全な型"と診断されることに同意しますが、*理由*はそのような型が無限回帰それ自体のインスタンス以外のものがあれば、無限のストレージも必要になります。 – JeremyP
struct folder {
char* name;
struct folder subfolders [10]; // bad
}
ですが、その完全な定義が必要とされる前にstruct folder
として片道@Peter罰金答えは完全に定義されていないことはできません。 `
これはどのような方法でも可能ですか?
はい、動的に割り当て考える:
は、作成するための関数を作成し、サブフォルダを追加、および削除を。可能な多くの細分化。
typedef struct folder_s {
char* name;
size_t n;
struct folder_s **subfolder;
} folder;
folder *folder_alloc(const char *name) {
folder *root = malloc(sizeof *root);
if (root) {
root->n = 0;
root->subfolder = NULL;
root->name = strdup(name);
if (root->name) {
return root;
}
free(root);
}
return NULL;
}
folder *folder_add_subfolder(folder *f, folder *sf) {
size_t new_n = f->n + 1;
void *tmp = realloc(f->subfolder, sizeof *(f->subfolder) * new_n);
if (tmp == NULL) {
return NULL;
}
f->subfolder = tmp;
f->subfolder[f->n] = sf;
f->n = new_n;
return f;
}
// Only need to free the root folder, recursion will handle the sub-folders.
void folder_free_tree(folder *f) {
if (f) {
while (f->n > 0) {
f->n--;
folder_free_tree(f->subfolder[f->n]);
}
free(f->subfolder);
f->subfolder = NULL; // Useful for debug
free(f->name);
f->name = NULL; // Useful for debug
free(f);
}
}
私はこの回答を控えています。ここまでは移動できません。 –
@MichaelWalzと同意します。あなたは構造体と構造体へのポインタを混同しています(後者は許可されています) – JeremyP