![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?c9bd177)
C++についての質問です。プログラミング初心者ですが、よろしくお願いします。
最近、関数の外側でも変数を宣言できることを知りました。関数の外側で変数を宣言すると、全ての関数でその変数にアクセスすることができ大変便利なように思います。
「わざわざポインタ渡しなどする必要はないのでは?」と思ってしまいました。
これは何か問題があるのでしょうか?
初心者の言葉で説明しても理解しにくいかと思いますので、例として「足し算するプログラム」を以下に記載します。
ポインタ渡しで書くと、以下のような感じになるかと思います。
//●ポインタ渡し
#include "stdafx.h"
#include <iostream>
void func(int x,int y,int *pans){
*pans = x+y;
}
void main(){
int a=10, b=20, ans;
func(a,b,&ans);
std::cout << ans << std::endl;
}
しかし、mainの外に変数を宣言すれば
//●mainの外に変数
#include "stdafx.h"
#include <iostream>
int a,b,ans;
void func(int x,int y){
ans = x+y;
}
void main(){
a=10;
b=20;
func(a,b);
std::cout << ans << std::endl;
}
ansをポインタ渡しする必要なく、funcの計算結果をansに代入できました。
「●mainの外に変数」のプログラムはどのような問題や危険性を孕んでいるのでしょうか?
以上になります。長文お読みいただきありがとうございました。
よろしくお願いいたします。
No.2ベストアンサー
- 回答日時:
例えば、
機能を追加して
int func0(int x,int y,int z){
ans = x - y ;
return ans -z;
}
を作ります。
void main(){
a=10;
b=20;
func(a,b);
std::cout << ans << std::endl;
int c=func0(30,40,50) ;
std::cout << c << std::endl;
std::cout << ans+c << std::endl;
}
とすると、
std::cout << ans << std::endl;
→ 30
std::cout << c << std::endl;
→ -60
と出力されます。
ということは
std::cout << ans+c << std::endl;
で期待するのは、
ans 30 + c -60 = -30
となりますが、実際には「-70」が出力されます。
これは、func0で途中計算に ans = x - y ; としてしまったため、ansが変わってしまったからです。
この程度の規模なら、管理もできるでしょう。
ですが、例えば、 「std::cout は実はグローバル変数ansを書き換える」なんてことになっていたらどうでしょうか?
標準ライブラリでは、そのようなことが無いように作られていますが、自作プログラムだと、ついうっかりやってしまう可能性があります。
実用的なプログラムとなると、数千~数十万といった行数になってきます。その中から、グローバル変数がどこで使われているか調べるのは並大抵のことではありません。
変数の有効範囲はなるべく狭く。必要なところだけで有効なようにする。
というのが、現在の主流の考えです。
詳細かつ例題まで載せてくださり、ありがとうございます。
これは「グローバル変数」と言うのですね。確かに期待される結果と違うものが出力されました。そして、この程度の行数でも変数がどこでどう変化したか追うのに苦労してしまいました。
『変数の有効範囲はなるべく狭く。必要なところだけで有効なようにする。』
これは肝に銘ずることにします。
ご回答ありがとうございました。ベストアンサーとさせていただきます。
No.1
- 回答日時:
「全ての関数でその変数にアクセスすることができ」るのが, まさに利点であると同時に問題点です. 「いつの間にか値を変えることができる」ってことだから.
ところで, 外部変数とした後者のプログラムで, なぜ func に a や b を引数として渡しているのですか?
簡潔かつお早いご回答下さりありがとうございます。
大きな規模のプログラムになると問題が起こってくるのでしょうね。今後このような書き方をしないよう注意しようと思います。ありがとうございました。
ちなみに、質問に記載したプログラムは、この質問のために書いたもので特に意味のあるものではありません。初心者の思いつきゆえ、理解しがたいところがあったかと思いますがご容赦ください…
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# 至急教えてください! プログラミングの問題です! お願いします! 出力2と全く同じ出力をするように、 2 2022/06/22 23:10
- C言語・C++・C# C言語初心者 ポインタについて、お助けください、、 2 2023/03/15 23:50
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# C++初心者です stirng 2 2022/09/20 20:43
- C言語・C++・C# C++のcinの動作 5 2023/02/26 00:13
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# このプログラミング誰か教えてくれませんか 1 2022/06/02 15:27
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# C pointer? or... 2 2022/03/29 00:47
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
構文エラーが出ているのですが...
-
空ENTERの判別
-
findnext();について
-
switch文のエラーについて
-
VC++で文字列から任意の文字を...
-
C言語のポインターで詰まっている
-
C++でバイナリデータの扱い方
-
_CRT_SECURE_NO_DEPRECATE が効...
-
2次元vectorのerase?
-
C++でのファイル入出力について
-
構造体に決められた文字列を入...
-
C言語のエラーを修正したい
-
#define中の#のエスケープ
-
C++でのmath.hやstdio.hの使用...
-
vc++の使い方について
-
Linux Ubuntu19.10でQt5.14.1の...
-
指定した文字を削除したい
-
【C++】ヘッダ内でstringを格納...
-
gccでコンパイル時のエラー
-
途中からMFCを使用したい
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラーが出ているのですが...
-
switch文のエラーについて
-
enumの値から定義名を文字列化...
-
VC++で文字列から任意の文字を...
-
なぜ、C++の標準ヘッダをインク...
-
空ENTERの判別
-
std::wstringのメモリリークに...
-
C言語からgnuplot呼び出し
-
リモートデスクトップの接続元I...
-
JPEGやPNGが読めるLoadImage関数
-
このプログラミング誰か教えて...
-
プログラミング
-
#include "fstream.h"
-
C++での <iostream.h>と<iostre...
-
std::map の const 修飾について
-
構造体配列のvectorへの変換と...
-
#defineの使い方について
-
VS2019でofstreamが未定義になる
-
指定した文字を削除したい
-
構造体に決められた文字列を入...
おすすめ情報