• ベストアンサー

識別子の外部結合について

識別子について調べていてわからないことがあり 質問させて頂きます。 以下のコードの場合変数aは外部結合ですか それとも外部結合以外となるのでしょうか。 識別子の宣言に対し同一ソースファイル内の関数内で その識別子の定義がある場合、その識別子は外部結合か どうかが知りたいのです。 ご存じの方すいませんがよろしくお願いします。 --test.c-- static int a; main() { ・・・ } function1() { a = 1; ・・・ } function2() { a = 1; ・・・ }

質問者が選んだベストアンサー

  • ベストアンサー
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

> 以下のコードの場合変数aは外部結合ですか > それとも外部結合以外となるのでしょうか。 内部結合です。 ファイル有効範囲で宣言した関数・オブジェクトの結合は、大雑把にいうと次のような基準で決まります。 ・externが付けば外部結合 ・staticが付けば内部結合 ・externもstaticも付かなければ外部結合 ただし、externもstaticも付かない場合、同一翻訳単位に同名の関数・オブジェクトの宣言があり、そちらにexternまたはstaticが付いているならそれに従います。 具体的には、 int a; static a; とあれば、aは内部結合になります。 > 識別子の宣言に対し同一ソースファイル内の関数内で > その識別子の定義がある場合、その識別子は外部結合か > どうかが知りたいのです。 void f(void) {  static int a;  extern int b;  int c; } とある場合、bは外部結合ですが、他は「結合なし」です。

orp39ds
質問者

お礼

回答ありがとうございました。 返事が遅れてしまいすいませんでした。 とても参考になりました。 また、よろしくお願いします。

その他の回答 (3)

  • chie65535
  • ベストアンサー率43% (8519/19367)
回答No.4

関数の外で定義した変数は、全て静的変数になります。 本来、全て静的変数なので、あえてstaticを付ける必要はありません。 しかし、関数の外で定義した変数は「外部参照可能か、外部参照不可で翻訳単位内(1つのソース内)のみで参照可能か」の2通りがあります。 そこで、この2つを区別する為「静的変数を意味するキーワードstaticを流用」して、 static付き→外部参照不可 static無し→外部参照可 と言う事にしてしまいました。 本当であれば「private」とかって修飾子でも追加して、 private int a; とでも書いたら「外部参照不可」にすれば良かったのですが、staticが流用されてしまった為、外部参照不可にする場合は static int a; と書く事になっています。

orp39ds
質問者

お礼

回答ありがとうございました。 返事が遅れてしまいすいませんでした。 また、よろしくお願いします。

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

関数の外で static 属性を付けて定義した変数は、 当該変数の定義を含んでいるソースファイルに 存在するすべての関数からアクセス可能です(ファイルスコープ)。 当該プログラムが当該ソースファイルを含む 複数のソースファイルで構成していて、 当該ソースファイルと同様に他のソースファイルにおいても 関数の外で static int a; と定義した場合、 当該ソースファイルにおける変数 a と 他のソースファイルにおける変数 a とは 別々の領域に確保します。互いのアクセスは不可です。

orp39ds
質問者

お礼

回答ありがとうございました。 返事が遅れてしまいすいませんでした。 また、よろしくお願いします。

  • eroermine
  • ベストアンサー率18% (83/444)
回答No.1

関数外 static はファイルローカルです。 そのファイル外から参照されないグローバル変数は必ず static にしましょう。

orp39ds
質問者

お礼

回答ありがとうございました。 返事が遅れてしまいすいませんでした。 また、よろしくお願いします。

関連するQ&A

  • Java main関数内でStatic変数使えない

    JavaのStatic変数について質問です。 Main関数の中でStaticな変数を定義しようとしたところ、 final修飾子しか使えませんというエラー文言が出ます。 Main関数内でわざわざStatic変数を使用する必要はないのですが、 出来ないと言われると何故だろうと思ってしまいます。 どなたかご説明いただけないでしょうか? -------------------------------------------------------------------- class Test { public static void main(String[] args) { // 宣言時Staticは使えなく、finalでしか定義できないとエラーが出る Static int test_val = 10; // 表示 System.out.println(test_val); } }

    • ベストアンサー
    • Java
  • 外部変数について

    今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]というのを別の関数で使用したいのですがこれも無理でしょうか? 馬鹿な質問だとは思いますが,どなたかお答え頂けますでしょうか? よろしくお願いします.

  • 文字列のメンバ変数を外部変数のように扱いたい

    済みません。質問なのですが、 メンバ変数を外部変数のように扱うにはどうしたらよいのでしょうか? int型などの場合、 class test{ static const int a; }; const int test::a = 10; とすればよいですよね? これをcharの配列にして class test{ static char a[7][32]; }; char test::a[0] = "test"; とすると サイズが0の配列を割り当てまたは宣言しようとしました というコンパイルエラーがでてしまいます…。 多次元配列の場合はstatic変数としてもてないのでしょうか? char** として宣言してもどこでnewを行えばよいか解りません。 コンストラクタの中で行えば そこでstaticではなくなってしまいますし…。 後、できればstringクラスの配列で持ちたいのですが #include <string> class test{ static string test[7]; }; string test::test[0] = "aaa"; なんてことができますでしょうか? 質問内容が解りにくいかも知れませんが どうか教えてください。 宜しくお願いいたします。

  • C言語でヘッダファイルにグローバル変数を宣言する

    main.hに static int a; と記述し、main.cで #include "main.h" [省略] a=10; のように使用して、-Wallをつけてコンパイルすると、main.cで使用しているにも関わらず、 'a' defined but not used という警告が表示されます。 同様に、関数においても、ヘッダファイルでstaticをつけると ‘~’ declared ‘static’ but never defined と警告されます。 静的グローバル変数などは、ソースファイル内で宣言しなければいけないのでしょうか?ヘッダファイル内で宣言しても警告が出ないような方法はありますか?

  • vectorを引数として使いたいのですがエラーが出てしまいます

    vectorを引数として使いたいのですがエラーが出てしまいます 以下のようなコードでコンパイルでエラーが出てしまうのですがどうしたら良いでしょうか。 class car{ public: int tire; int engine; } というクラスを作ります。 main関数内で function(car a[]);//関数の宣言 int main(){ std::vector<car> car1(0);//car型のcar1を作成 std::vector<car>::reference car1rf=car1.front(); function(car1rf);//関数に代入 } function(car a[]){ car test; test.tire=1; a.push_back(test); } としてpush_backを外部関数で行いたいのですが、エラーが出てしまいます。 どうしたら良いでしょうか。

  • 非staticフィールドを参照できない理由とは

     java勉強中です、宜しくお願いします。  下のようなプログラムを書き「Test1」をコメントアウトしたら、 「非staticフィールドをstatic参照できません。」というエラーが 出ました。  「Test1 t」をグローバル変数で定義したのですが、やはりを 「static」からは見れないということでしょうか。  「main」は特別な関数というのは分るのですが、staticフィールドとか クラスオブジェクトしか、main()からは覗けないという設計思想(?) とかはどのようなものなのでしょうか。  逆に覗けるのが可能ならばどのような不都合が生じるのでしょうか。  何かしら非常に不便を感じて使い勝手が悪いという気がして仕方ない のですが、特別にこうしなけらばならないとか、今までの他の言語であ った不具合(ex 隠蔽機能)を更に強化したためとかと言う理由があるの でしょうか。  ========================================================== public class Test1 { Test1 t; void calc() { int a = 2; int b = 3; System.out.println(a+b); } public static void main(String args[]) { /*Test1*/ t = new Test1(); t.calc(); } }

    • ベストアンサー
    • Java
  • 外部結合?

    SQLについてです。 テーブルA ID 価格 タイプ 01 1,000 A01 02 2,000 B02 テーブルB ID 名前 種別 01 test a 03 aiue b 上記のようなテーブルがあったとして テーブルAとテーブルBを外部結合し 紐づくレコードがあった場合、さらに 種別=a で検索を行いたいのですが 書き方がよくわかりません。 外部結合で検索し、紐づくレコードがあった場合に さらに検索条件を絞る場合には どう書いたらいいのですか? よろしくお願いします。

  • 配列の操作時にLNK2001外部シンボルが未解決がでてしまいます。

    test.hにて class test{ public: static int test[8][8]; static int test1[8]; public: static int set_test(); } を定義して test.cppで void test(){ test[0][0] = 0; test1[0] = 0; } とすると LNK1120: 外部参照 1 が未解決です。 LNK2001外部シンボルが未解決です。 となってしまいます。 環境は Visual Studio 2005 C++です。

  • static付き宣言の初期化

    static付きの宣言をした場合の変数の初期化について教えてください。(ANSI-C) int func(void) { static int si; static char sca[10]; static char *scp; /* 何らかの処理 */ return 0; } このように関数内でstatic付きで宣言したとき、変数はどのように初期化されますか? siは0、sca[0]からsca[9]までは'\0'、scpはNULLで初期化されますか? また、このようなstatic付きの宣言が関数の外にあった場合は、どのように初期化されますか?

  • ・関数内で宣言された変数の扱い(C入門本の説明で)

     以下C言語入門書の説明ですが!  いまいちわかりません?   ・関数内で宣言された変数の扱い 関数内で宣言した関数は、その関数内でのみ有効な変数になります。関数が異なれば、同じ変 数名で宣言することができます。例えば、main関数と(?)kansuu関数で、同じ(?)hennsuuという名 前の変数を宣言することができます。  int main() { int (A)hensuu = 0; (B)kansuuu(1); } int (C)kansuu(int hikusuu) { int (D)hensuu = 10; }  列のmain関数で宣言されている(?)hensuuと、さ(?)kansuu関数で宣言されている(?)hensuuは 同じ名前ですが、独立した異なるものです。(?)kansuu関数が実行されているときに、(?)hensuuの値 を変更しても、main関数で宣言されている(?)hensuuの値は変更されません。 また、(?)kansuu関数を実行している間だけ、(?)kansuu関数で宣言されている(?)hensuuが有効です。 (?)kansuu関数から呼び出し元でるmain関数に戻った際は、(?) kansuu関数で宣言した (?)hensuuはもう有効ではなくな、値を参照することもなくなります。     以上の説目で、   (A)hensuu、 (B)kansuuu、(C)kansuu、(D)hensuu  (アルファベット)を分かりやすいよう追加しました。   説明の   (?)にプログラムの(A)~(D)をつけたらどうなるか知りたいです。 (何となくわかるですが?)   よろしくお願いします。

専門家に質問してみよう