• ベストアンサー

外部変数について

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

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

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

> extern宣言で他のソースのローカル変数を参照する方法はないのでしょうか? 直接参照する方法はありません。 > できればグローバル変数を使いたくないのですが 「グローバル変数」をどういう意味で使われているのか分かりませんが、大域的名前空間有効範囲に属している外部結合を持つオブジェクトの意味であれば、大域的でない名前空間有効範囲にするとか、クラス有効範囲にすればよいのではないでしょうか? > int main( int argc, char *argv[] )のargv[1]というのを別の関数で使用したいのですがこれも無理でしょうか? 引数で渡せばよいのでは?

the_koba
質問者

お礼

回答ありがとうございます. 私の言うグローバル変数とは >大域的名前空間有効範囲に属している外部結合を持つオブジェクトの意味 だと思います. C++についてまだまだ勉強中なのであいまいな判断しかできませんが. >大域的でない名前空間有効範囲にするとか、クラス有効範囲にすればよいのではないでしょうか? というのは例えば, namespace Ex { int abc; } として,使うときはEx::abc;のようにするということでしょうか? 若しくは,クラスのpublicセクションにおいて参照するということですか? 2つ目.引数で渡すというのは void func(char *argv)のようにすればOKですか? この場合2つ目,3つ目のメイン関数の引数を読み込もうと思えばforループでfuncを数回呼び出すようにすればいいのでしょうか?

the_koba
質問者

補足

できれば何故できないのか理由も教えて頂けたらうれいしです. ローカル変数を参照できないのは関数同士で変数が干渉するから,という理解でいいのでしょうか?

その他の回答 (3)

  • iyomante
  • ベストアンサー率60% (14/23)
回答No.4

一応、望んでいるものに該当するかわかりませんが、C++ならfriend というのがあります。 friend class hoge; をクラス内で宣言すれば、例外的にpublic以外の変数もhogeクラスからのみ参照できます。 多分なさりたいとする内容が、入門書に禁止されてる内容よりもさらに許されない内容なので いずれにしても代替案になると思います

the_koba
質問者

お礼

回答ありがとうございます. friendなんてものがあるんですね. これでもできそうですがあまり使わない方がいいみたいですね. もう一度プログラムを考え直してみます.

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

まず、開発を行っているのはCですか?C++ですか? はっきりしてください。 >extern宣言で他のソースのローカル変数を >参照する方法はないのでしょうか? >グローバル変数を使いたくないのですがこれ 参照する必要があるならローカル変数にしていること自体が 設計ミスだといわざるを得ませんが、グローバルにしたくなければ、 引数で渡せば良いと思います。もしくは、関連する変数を使っている 関数を別ファイルにしない。 やりたいことが具体的でないので、この方法が実用的かどうかは これ以上わかりませんが:-p >Ex::abc;のようにするということでしょうか? >クラスのpublicセクションにおいて参照するということですか? C++ならこれでいいと思います >void func(char *argv)のようにすればOKですか? >この場合2つ目,3つ目のメイン関数の引数を読み込もうと思えば >forループでfuncを数回呼び出すようにすればいいのでしょうか? そのまま渡せばfunc内で複数取れると思いますが? void func( int argc, char* argv[] );

the_koba
質問者

お礼

回答ありがとうございます. 開発をしているのはC++です. 質問文の「例えば~」のくだりでa.cやらb.cなどと混乱を招くようなことを書いてすいません.a.cpp,b.cppの間違いです. グローバル変数を多くすると訳がわからなくなってくるので,できるだけグローバル変数は使いたくないなと思ったもので. ローカル変数だけどある一部の関数では使える,みたいなことは出来ないですね. >void func( int argc, char* argv[] ); 確かにその通りですね. ありがとうございました.

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

Cだと無理ですね iみたいにありふれた変数だと多くの関数内で宣言されてわけわからなくなっちゃいますよ。 C++のクラスならアクセス範囲を指定できるのでpublic変数にすればそれっぽい使い方が出来るのでは。 メイン関数の引数の方ですが引数として渡すかグローバル変数にコピーするかですね。

the_koba
質問者

お礼

回答ありがとうございます. iとしたのは例えばです.例が悪くてすいません. 入門書などではpublicセクションに変数を置くのはあまり良くないと書かれていました. publicセクションには関数を置き,その関数からprivateセクションにある変数を参照する方がいいと. >メイン関数の引数の方ですが引数として渡すかグローバル変数にコピーするかですね。 このグローバル変数にコピーするとはどういうことでしょう? 具体的に書いて頂けるとありがたいのですが,お願いできますでしょうか?

関連するQ&A

  • 変数宣言・変数定義のちがいって??

    変数宣言・変数定義のちがいって?? 同じ意味なんでしょうか? 私の解釈では、 ・宣言っていうのは、今からこの変数を使いますよってことで。 ・定義っていうのは、実際に変数の領域をわりあてるってイメージなんですけど・・ なので、 int a; ←これは変数定義 extern int a; ←これは変数(extern)宣言 あってるでしょうか?

  • SolarisとLinuxのグローバル変数の扱いについて

    Solaris用のソースをLinuxで使えるように変更したいのですが、 グローバル変数について以下のようなことが発生していて困っています。 なにか、コンパイルオプションなどで対応はできないものでしょうか? Solaris (CC)では 特にextern宣言しなくても同じシンボルの外部変数はコモンセグメントに1つだけ作成しコンパイル自体は正常である。 しかし、Linux (g++)では externを宣言しないと同じシンボルを再定義したことになりエラーとなる。 これにより、グローバル変数を多用しているプログラムはLinuxでうまくコンパイルができない。 しかし、単純にextern宣言での対応は難しい。 extern宣言は外部で定義してあるグローバル変数を参照する というものだがLinux では 1つの定義を意外は全てexternしなければ、2重定義エラーになってしまう。 つまり、実体が1つであとはそれを参照しているという形でなければいけない。 ところが、その実体をどこにするか特定することができない。 例えば、gというグローバル変数を仮定する。 A.c,B.c,C.cはその3つのソースよりAA.aという静的ライブラリを構成する。 gはA.cで定義してありB.c,C.cはそれを参照する。 ところが C.cは個別にC.oというオブジェクトで他からの呼び出しがあり 別LMにリンクされる。 その時C.c内のgは実体を失うことになり未定義となる。 つまり、どれが実体になるかは何にリンクするかで決まるため 実態を特定できない。 また、共通のヘッダにグローバル変数が定義されている場合も、重複するというエラーを起こすため、 共通ヘッダからグローバル変数を分離し、何れかのソースにグローバル変数の実態を定義させる必要がある。 共通ヘッダを使っている他のソースはそのグローバル変数の実態を参照するようにexternの宣言をする。

  • 関数の引数の書き方。

    AとBのどちらの書き方でもよいのですか? 私が読んだ本(やさしいC)には、 Aパターンのみだったような? Aパターン ------------------ void main(int argc,char *argv[]) { int i; ・・・・ } Bパターン ------------------ void main(argc, argv) int argc; char *argv[]; { int i; ・・・・ } http://ash.jp/db/ora_c.htm

  • 複数ファイルで使うグローバル変数の位置

    メイン関数の処理で、関数A→関数B→関数Cという順序で関数が呼び出される場合(1関数1ファイルとします)、関数A,B,Cすべてで使用するグローバル変数の宣言を関数Bのファイルでおこなって、他のファイルではそれをexternするというのでも問題ないでしょうか?

  • 関数の最初の変数有効期限について

    最近C言語を勉強しているのですが変数の有効範囲について教えてください。 ローカルやグローバル変数があるのが分かって関数内の変数も関数内でのみ有効というのも理解したのですが int a( int b ); という関数の最初に書く括弧の中のbと宣言している変数も関数内に含まれているという事で良いのでしょうか?。

  • C言語の変数について

    C言語の変数について教えていただきたいです。 C言語で下記のような設定をした場合、変数A、Bに設定する値にはバイト数制限 はないのでしょうか? バイト数制限がなくなる場合、なぜそうなるのかを教えていただきたいです。 よろしくお願いします。 #include <stdio.h> void test( char **B); int main( int argc, char *argv[] ) { char *A = NULL; char *B = NULL; A = argv[1]; test( B ); return 0; } void test( char **B ) { strcpy(B, "ABCD"); return 0; }

  • サブルーチン、グローバル変数がわかりません。

    2つの行列の計算をサブルーチン関数とグローバル変数を使って行いたいのですが、サブルーチン関数を宣言する為の、プロトタイプ宣言やプロトタイプ定義や、グローバル変数など、 調べてもよく理解できません。 とりあえず、二次元配列を用いたソースコードを書いてみました。 (1)14行目と23行目からのfor文、(2)40行目と51行目と62行目からのfor文を1つにまとめて、最初のプロトタイプ宣言は void 関数(double a[LINE][COLUMN] , double b{LINE][COLUMN] , double c[LINE][COLUMN]) ; にすればいいと思うのですが、 その後は、どのようにすればいいのでしょうか? あと、scanfも使って、aとbも入力できるようにしたいです。 1 #include <stdio.h> 2 3 #define LINE 3 4 #define COLUMN 3 5 6 int main(int argc, char *argv[]) 7 { 8 double a[LINE][COLUMN] ; 9 double b[LINE][COLUMN] ; 10 double c[LINE][COLUMN] ; 11 int i ; 12 int j ; 13 14 for(i= 0;i < LINE ; i++) 15 { 16 for(j = 0 ; j<COLUMN ; j++) 17 { 18 printf("A[%d][%d]=", i+1 , j+1 ); 19 scanf("%f", &a[i][j]); 20 } 21 } 22 23 for(i =0;i < LINE ; i++) 24 { 25 for(j = 0 ; j<COLUMN ; j++) 26 { 27 printf("B[%d][%d]=", i+1 , j+1 ); 28 scanf(" %f", &b[i][j]); 29 } 30 } 31 32 for(i =0;i < LINE ; i++) 33 { 34 for(j = 0 ; j<COLUMN ; j++) 35 { 36 c[i][j] = a[i][j] + b[i][j] ; 37 } 38 } 39 40 printf("\n行列A:\n"); 41 for(i =0;i < LINE ; i++) 42 { 43 for(j = 0 ; j<COLUMN ; j++) 44 { 45 printf("%10.5f" , a[i][j]) ; 46 } 47 48 printf("\n"); 49 } 50 51 printf("\n行列B:\n"); 52 for(i= 0;i < LINE ; i++) 53 { 54 for(j = 0 ; j<COLUMN ; j++) 55 { 56 printf("%10.5f" , b[i][j]) ; 57 } 58 59 printf("\n"); 60 } 61 62 printf("\nC(和):\n"); 63 for(i= 0;i < LINE ; i++) 64 { 65 for(j = 0 ; j<COLUMN ; j++) 66 { 67 printf("%10.5f" , c[i][j]) ; 68 } 69 70 printf("\n"); 71 } 72 return 0 ; 73 }

  • C言語のローカル変数の使い方について質問です。

    C言語の変数に関しての質問です。 グローバル変数を使わずに、関数内で宣言したローカルの変数を別のソースファイルで使用することって可能ですか? 例えば、a.cというソースファイルと、b.cというソースファイルがあります。 a.cの関数内で"FILE *fp;"と宣言したローカル変数を、b.cの関数内で共有して使うことはできるのでしょうか。 また、"fp"に直接アクセスはできなくても、間接的にアクセスできる方法があれば教えてください。 下に記述しているのは例え用に適当に書いたプログラムです。 --------------------- a.cのソースファイル --------------------- void Temp(void) { char file_name[128] = {}; errno_t error; FILE *fp; // ←この変数を別のソースで使いたいです scnaf_s("%s", file_name, 128); if(error = fopen_s(&fp, fname, "rb") != 0) { printf("ファイルがオープンできません"); return 0; } fclose(fp); } --------------------- b.cのソースファイル --------------------- void Temp2(void) { int size; // ここでa.cのTemp関数で宣言されている"fp"を使いたい fseek( fp, 0, SEEK_END ); fsize = ftell( fp ); fseek( fp, 0, SEEK_SET ); }

  • グローバル変数

    分割コンパイルで、持ちいる変数をヘッダーファイルに宣言しました。 ヘッダーファイル内で次のように宣言し、メインの関数でない場合にはexternになるようにしました。 メインなら FILEは1 それ以外なら0 #if FILE   unsinged int inputNo; #else  extern unsigned int inputNo; #endif しかし、リンクをさせると error LNK2001: 外部シンボル "_inputNo" は未解決です と出てしまいます。解決策はあるでしょうか? プロジェクトの設定の関係でしょうか?よろしくお願い致します。

  • C言語のヘッダファイルの使い方

    ヘッダファイルの使い方について質問です。 ソースファイルA、ソースファイルBで共有して使用したい変数がある場合、 Aでは「int a」と宣言し、Bでは「extern int a」と宣言すれば 同じ変数を共有出来ると認識しています。 それをヘッダファイルへ記述しておきたい場合にはどのように 宣言しておけば良いのでしょうか? ヘッダファイルに「int a」と宣言した場合は両方のソースファイルで includeした時に多重定義でエラーとなります。 では「extern int a」と宣言しておいて、両方のソースファイルで includeするのが正しいのでしょうか? 初歩的な質問で申し訳ないですが、有識者の方、教えてください。

専門家に質問してみよう