🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

Q&A

解決済

2回答

7566閲覧

配列の要素数が1つだけのメンバ変数?

dokutoku

総合スコア11

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

配列

配列は、各データの要素(値または変数)が連続的に並べられたデータ構造です。各配列は添え字(INDEX)で識別されています。

0グッド

1クリップ

投稿2019/11/17 08:45

編集2019/11/17 08:48

C言語のソースコードを見ていると、配列の要素数が1つだけのメンバ変数を格納している構造体を見かけますが、これの意味がよくわかりません。
要素数がひとつだけなら配列にする意味はあるのでしょうか?

c

1struct test { 2 int x[1]; 3 char y; 4 char z; 5};

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2019/11/17 08:49

このような使い方でしたか? 配列が構造体の末尾にあったり、または構造体の後ろにある要素がもっと大きくありませんでしたか?
jimbe

2019/11/17 09:17

(公開)可能であれば, その見かけたモノをご提示願えますか.
Zuishin

2019/11/17 11:17

ああ、追記・修正依頼読まない人か。
dokutoku

2019/11/17 11:35

読んでますよ。読んでるだけで・・・
Zuishin

2019/11/17 11:37

これには反応するんだ。
Zuishin

2019/11/17 11:37

これは読むだけでいいんですよ。
Zuishin

2019/11/17 11:38

単なる独り言なのでお構いなく。
guest

回答2

0

ベストアンサー

質問中に書いてある例の通りだとしたら、配列として書く以上は配列として扱いたいという意図の表れであると考えられます。 たとえば struct test 型のオブジェクト foo があるときに foo.x[1] としたら yz をひとまとめにしたものが見えるかもしれません。

ただし、構造体の要素間には詰め物 (padding) が入る可能性があるなど、バイナリレベルでのレイアウトは言語仕様では定義されていません。

ハードウェアに近いプログラム (ファームウェアやデバイスドライバなど) で、なおかつコンパイラが構造体をどのようなレイアウトに配置するのか把握可能なときにはそういうことをしたいこともなくはないのでしょうが、普通のアプリケーションプログラムでそのようなことをするのはとても駄目なので真似しないでください。


構造体の最後のメンバを配列にしている場合は episteme さんが述べているように可変長の配列にするテクニックのひとつとしてよく知られていますが、現在の C では最後の要素に限って不完全型を許すことになっています。 すなわち、配列の大きさを書かないということが出来ます。

c

1struct test { 2 int size; 3 int data[]; 4};

このとき、 sizeof(struct test)data の大きさを 0 として大きさを計算するので、配列の大きさを 1 として定義した構造体よりは大きさの計算がやりやすく、また可変長を意図しているということがわかりやすいのでなるべくならこちらの方式を使った方が良いです。

ただし、 C++ では構造体の最後を不完全にするのは許されていません。 (一部の処理系は許容したりもするのですが……。) 古い C コンパイラしかないような場面や、 C と C++ でコンパイルできる必要がある場合などに苦肉の策として配列の大きさを 1 にするということはあるかもしれません。

投稿2019/11/17 09:24

SaitoAtsushi

総合スコア5684

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dokutoku

2019/11/17 11:12

私の不完全な質問にとても親切に回答してくれてありがとうございます。 構造体の最後のメンバが配列だったので、可変長の配列のようです。 ためになる知識も多かったのでこれをベストアンサーにしようとおもいます。
guest

0

可変長配列実現のため「最後のメンバを要素数1の配列にする」っていう小賢しいテクニックはありますけども。

C

1#include <stdio.h> 2#include <stdlib.h> 3 4struct test { 5 int size; 6 int data[1]; 7}; 8 9struct test* make_test(int size) { 10 int i; 11 struct test* p = malloc(sizeof(struct test) + (size-1)*sizeof(int)); 12 if ( p != NULL ) { 13 p->size = size; 14 for ( i = 0; i < size; ++i ) p->data[i] = i; 15 } 16 return p; 17} 18 19int main() { 20 int i; 21 struct test* p = make_test(10); 22 for ( i = 0; i < p->size; ++i ) { 23 printf("%d ", p->data[i]); 24 } 25 free(p); 26 return 0; 27}

投稿2019/11/17 08:56

episteme

総合スコア16612

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dokutoku

2019/11/17 11:02

回答ありがとうございます。確かに私が見たケースは最後のメンバが要素数1の配列でした。
episteme

2019/11/17 11:07

ならばおそらく可変長配列が目的なんじゃないかしら。 SaitoAtsushiさんご指摘のとおり、きょうびの処理系なら int data[]; を許すみたい。 int data[1]; はむかしむかしからある(そこそこ有名で)小賢しいワザです^^;
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問