• 締切済み

テーブルというグローバル変数

学生時代にプログラミングを習ったときには、 グローバル変数は悪のものであると習いました。 しかし、プログラマーに就職してみると、 テーブルというなのグローバル変数がいたるところで 使われています。 グローバル変数を使用しないようなソースに することはできるのでしょうか? また、テーブルというのは一般的によく使われるもの なのでしょうか?検索してもそれらしいサイトが 見当たらないですし、Cの参考書を見ても、そのような ものは出てきません。

みんなの回答

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.4

組み込み系などでメモリサイズに制限がある場合に、 共用体と構造体を使ってグローバル変数にデータを入れる。 とかいうことをする場合があります。 # というか、今関わっているものがそういう使い方しています。 グローバルな上に共用体ですので、うっかり書き換えないように注意が必要です。

ohohohsun
質問者

お礼

そのような目的で使用される場合もあるんですね ご回答ありがとうございます。

回答No.3

グローバル変数がよくないと言われるのは、予想外の値が設定されたときに、誰がどこで(どの関数が)その値を設定したのか追いかけるのが大変だからというのが主な理由です。 ですから、まず、「誰も書き込みをしない(参照するだけ)」のグローバル変数は、#define で定義した定数と同じですから、危険性はありません。 普通に言う「テーブル」は、読み込みのみの用途であることが多いので、大丈夫なことが多いですが。 ただ、「誰も書き込みをしないはず」のところに、書き込みされてしまうのが、バグというものですから、const を指定して、「書き込みできないのを保証する」というのは、良い方法です。 グローバル変数の危険性を回避するためには、書き込み時のチェックを行うという方針になります。 テーブル自体を、どこかの関数のローカル変数として定義し、このポインタを「必要とする」関数に対して、引数として渡すことで、見かけ上グローバル変数をなくすことができます。 ただ、これも、このままでは、「引数として渡した関数のどこで(間違って)書き込んだのか」という点では、グローバル変数と危険性は変わりません。 ただし、この場合でも、(少なくとも)引数として渡した関数のどれかが悪さをしているとか、値を書き換える非通用のない関数では、const な引数として渡す(と、その関数では、少なくとも書き換えできない)とか、若干、安全性を増すことができます。 C++の範疇まで広げれば、 ・メンバー変数を private にして、 ・読み込み、書き込みが必要な場合には、public な関数経由 にすれば、書き込み時に、いろいろなチェックをかけることができますから、安全性を向上させることができます。

ohohohsun
質問者

お礼

グローバル変数の使い方は難しいですね。。 ご回答ありがとうございます。

  • notnot
  • ベストアンサー率47% (4848/10262)
回答No.2

あなたの会社で「テーブル」という語がどういう意味で使われているのか不明ですが、想像して答えると、 ケース1:定数テーブルのようなもの。例えば、{"January","Feburuary","March",...} のようなものであれば、グローバルにすると思います。 ケース2:DBの代用。本来ならばDBを使ってもおかしくないが、他のプロセスと共用しないとか高速化の必要がある等の場合に、配列で代用することがあると思います。この場合もグローバルでしょうね。データベースやファイルというのはグローバルなので。

ohohohsun
質問者

お礼

ケース2と思います。 特にほかのプロセスと共用するとかではなくて、 ひとつのプロセス内の複数の機能で、 そのテーブルを共有するイメージです。 具体的な構造は、構造体を使用した配列です。 構造体は、いくつもネストしていたりします。

回答No.1

グローバル変数が良くないのはスコープ(変数を参照更新できる範囲)が広いからです。スコープが広いと、その変数を修正したいとき、影響が広範囲にわたるため、保守性が低下します。変数のスコープはできる限り小さくした方が保守性が向上します。 >テーブルというなのグローバル変数 テーブルと言うのはおそらく配列のことではないでしょうか? 配列も引数で渡すことでローカル変数で管理することが可能です。配列の場合、一般的にアドレス渡しになると思いますが、const宣言することにより、更新コードを書くとコンパイルエラーにすることも可能です(関数内更新させたくない場合)。 ただ、学校と比べ仕事では、最初からプログラムを書くよりも誰かのプログラムを流用することが多いと思います。そのときに、既にグローバル変数で定義されたいるものをローカル変数に修正することは危険が大きすぎるので控えた方がよいのではないでしょうか?

ohohohsun
質問者

お礼

複数の機能が、テーブルを介して処理をする。 というのはどこのシステムでも一般的な手法なので しょうか? >既にグローバル変数で定義されたいるものをローカル変数に修正するこ >とは危険が大きすぎるので控えた方がよいのではないでしょうか? プログラムを書き換えることはないです。 もし設計する機会があれば、どのような設計にするのが、 よいだろうと思ったしだいです。

関連するQ&A

  • 変数名のこだわりについて

    私はC言語始めて10ヶ月ぐらいのものなのですが、 現在ゲームプログラミングを学んでいます。 C言語で用いている変数名や関数名、クラスのオブジェクト名 など、本当に適当につけていたのですが、 最近とてつもなくソースコードが読みにくくて 変数名のつけ方に規則みたいなものを作ろうと思うのですが、 どなたかゲームプログラミングなどのプログラミング をやっている方々、参考までに、どんな風に名前をつけているか を教えてください。 そういうことを記述しているサイトでもかまいません。 よろしくお願いします。

  • 変数などの名前のつけ方の「_」という記号について。

    本などで、プログラミングのソースを読んで勉強していると、変数などの名前に「**_**」という名前の付け方を、よく目にします。 使い勝手がありそうなので、私も使いたいのですが、この「_」は一般的にどういう意味合いで使うのでしょうか? よろしくお願いします。

  • 変数のスコープはどうするのがベター?

    C言語で組み込みプログラミングしています。 頻繁に呼び出される関数があり、その中でのみ使用する大きめの構造体があり、 この構造体の実体をグローバル変数として生成しておくか、関数が呼び出される度に 生成するかで、どちらが良いのかが知りたいです。 条件として、 変数は1つ実体があればOKです。(なのでグローバルでもローカルでもどちらでも使用上問題なし) 高級言語(Java、C#など)では関数内で生成するようにしてカプセル化を図るのが良いと思いますが、 組み込みでは 1)生成コストがあるのでグローバルで一度生成しておくのが一般的 2)カプセル化できるように関数内で、関数が呼ばれる度に生成するのが一般的 3)関数内でstaticで生成しておくのが、生成コストかからず、一般的 など、こうするのがスタンダード、という方法があればお教え下さい。 ケースバイケースの場合は、どういう場合はどうするのがよいかをお教え下さい。 よろしくお願いします。

  • 動的な変数名のつけ方について

    ■環境 OS:XP 言語:C++ コンパイラ:Visual C++ 2008 char*やstd::string等で格納された文字列を使用して 変数を宣言することは可能でしょうか。 用途として、テキストファイル等から文字列を取得し その文字列を変数名としてプログラミング内で使用するという方法を考えています。 よろしくお願い致します。

  • 外部変数について

    今Vine Linuxを使ってC++でプログラムを書いているのですが教えて頂きたいことがあります. C++の初心者の為,変なことをお聞きしますがお許しください. extern宣言で他のソースのローカル変数を参照する方法はないのでしょうか? 例えば,a.cとb.cというソースがあったとします. a.cの関数内でint i;と宣言されている変数をb.cからextern int i;という風にしたいのですが, こうするにはa.cでグローバル変数としてint i;を定義する以外方法はないのでしょうか? できればグローバル変数を使いたくないのですがこれ以外では無理でしょうか? あともう一つお聞かせ下さい. メイン関数の引数を別の関数,またはソースで使うということはできないのでしょうか? int main( int argc, char *argv[] )のargv[1]というのを別の関数で使用したいのですがこれも無理でしょうか? 馬鹿な質問だとは思いますが,どなたかお答え頂けますでしょうか? よろしくお願いします.

  • 学生プログラマー (アルバイト)

    私は高専情報科に通う学生です (高専は学生です) 学校で学ぶのとは別に趣味でプログラミングをしています。 四六時中Linuxいじりやプログラミングをしているとプログラマーとして働くというのはどんなものなのか気になります。 また、「学生プログラマー」として働いている人がいると知り合いから聞きましたので、この夏休みを利用してプログラマーとして働いてみたいです。 いくつかの求人サイトで検索しましたが、そもそも数が少ないのと関東での仕事が多いようですが、 僕は関西在住なので、関西圏でないと働けません。 使える言語: C, C++, nasm(Netwide Assembly), Shell Script 一応読める言語: Java, Verilog 自分が使う環境がUbuntuかArch LinuxなのでLinuxとLinuxプログラミングもOKです。 そこで、そもそも僕が使える人材であるかどうかもわかりませんが、 この文脈に合う、求人があるのであればぜひ紹介していただきたいです。

  • 変数名や関数名の命名方法

    どうも初めて質問させていただきます。 私はプログラマの2年生で、現在C++で作業しています。 最近になってようやくプログラミングに自信を持てるようになり、 だいぶコーディングも早くなった気がしています。 ですが、いつも変数名や関数名またはクラス名といった名前を付ける際に 非常に時間がかかってしまいます。 和英辞典を使って調べたりするのですが、 そのまま名付けても、他の人が見て意味が理解できなさそうなことが多いです。 みなさんは変数名など考えるときに、どのようにしていますか? 何かプログラミング専門の和英辞典みたいな書籍など出ているのでしょうか? お役立ち情報ありましたら、どうぞよろしくお願いします。

  • フィールド(メンバ変数)のプリフィックスについて

    C#でプログラムを作っていて、ふと思ったのですが、 皆様は「メンバ変数」であることをあらわすために どんなプリフィックスをつけられていますか? また、その理由も教えていただけると幸いです。 一般的にどんなプリフィックスを使うのかわからなくて、 ネットで検索してみたら、『m_変数名』というものがあったのですが、 別のサイトでは「『m_変数名』は古い」みたいな記述もあり…。 どれが正解でどれが間違いというのは一概に言えないと思うので、 いろんな方の意見を伺いたく存じます。よろしくお願い致します。

  • コンポジット型の変数?

    PL/SQL参考本を読み始めているのですが 「コンポジット型の変数」というとろこで質問があります。 コレクションを使った変数定義というのを見ているのですが その定義内容について教えてください。 参考本では下記のような定義を行っていました。 DECLARE TYPE hosttable_type IS TABLE OF VARCHAR2(15)      INDEX BY VARCHAR2(32); ・・・(1) host_table hosttable_type; ・・・(2) 「コレクションとは一般的なプログラミング用語の配列にあたる」 との解説がありましたが 上記の変数定義でどの部分が配列変数の宣言にあたるのですか? (1)が配列変数の宣言部分で (1)の「INDEX BY VARCHAR2(32)」では添字の長さを指定し 「TYPE hosttable_type IS TABLE OF VARCHAR2(15)」では 実際配列に格納する値の長さを指定してる という意味なのでしょうか??? サイトなどを調べてみてはいるのですが 自分ひとりではどうも解決できなくて。。。 どなたかお力をお貸しください!

  • PRO*Cでテーブル名にバインド変数は使えますか?

    PRO*Cのプログラムで、テーブル名とカラム名をパラメータで 受け取って、ホスト変数(バインド変数?)に代入して、 それぞれ、SELECT文等で使用できますか? PL/SQLなら出来るでしょうか? EXEC SQL BEGIN DECLARE SECTION; varchar t_name[64]; /* テーブル名 */ varchar col_name[64]; /* カラム名 */ EXEC SQL END DECLARE SECTION; /* 中略 パラメータの値をホスト変数に代入する処理を行う */ ↓以下のように出来ますか? SELECT :col_name FROM :t_name ;