何が間違っているかを説明する4つの回答を読むのはかなり面倒ですが、それを修正する正しい方法を説明するものはありません. OPがスコープについて知らない場合、変数を関数に渡すことについてもおそらく知らないというのは、おそらく安全な推測です。
問題
変数の値を取得しようとしていますが、変数は別の関数にあります。どうすればそれを手に入れることができますか?まあ、簡単な答えは、あなたはそれを手に入れたくないということです. あなたは私を正しく聞いた。関数を使用するすべての理由は再利用性です。新しく作成した関数を別の関数に関連付けると、どこでも使用できなくなります。関数は怠惰になるのに役立つことを忘れないでください。そして、優れたプログラマーは怠惰なプログラマーです。関数を 1 回記述して、100 万の場所で使用できれば、それは正しいことです。;)
しかし、私はまだその変数の値を取得したい
次に、関数パラメーターを使用して変数を関数に渡します。
関数は、数学の観点から考えることができるため、名前が付けられています。変数を入れて、関数の実行後に有用なデータを取得し、それらの変数で興味深いことを行います。したがって、数学関数があるとしましょy = f(x)
う。これと同等のものは、変数または数値の場所int f(int x) { /*stuff here*/ }
を使用してメイン関数で呼び出すことです。int y = f(a)
a
グローバル変数は常に期待どおりに機能するとは限らないため、避けたいと考えています (特にコードが多い場合は、誤って同じ名前を使用してしまう可能性が非常に高くなります)。
あなたの場合、関数で特定の変数の内容を出力したいので、おそらく特定の変数でその関数を使用する方法を探していると思います。だからここにあなたがそれを行う方法があります。
void f(); //hi, I'm a function prototype
void f(int a); //hi, I'm a function prototype that takes a parameter
void f(int a, int b); //hi, I'm a function prototype that takes two parameters (both ints)
void f(int a, ...); //hi, I'm a function prototype that takes an int then any number of extra parameters (this is how printf works.)
したがって、実際にやりたいことは、コードを次のように変更することです。
header.h:
#ifndef HEADER_H
#define HEADER_H
#include <iostream>
// extern int* a; // We don't need this
void f(int* a)
{
if (a != NULL) //always, always check to make sure a pointer isn't null (segfaults aren't fun)
std::cout<<*a <<std::endl;
//return; //Don't really need this for a function declared void.
}
#endif
main.cpp:
#include "header.h"
int main()
{
int* a = new int(10);
f(a);
return 0; //main is declared as returning an int, so you should.
}
値、ポインター、および参照による関数
したがって、私が与えたあなたの例では、あなたの例ではint
なく使用int*
しました。2 つの違いは、最初のパラメーターが値によって渡されることです。もう一方はポインタで。変数を関数に渡すと、常にそのコピーが作成されます。int を渡すと int のコピーが作成され、4 MB 構造体を渡すと 4MB 構造体のコピーが作成され、4MB 構造体へのポインターを渡すとそのコピーが作成されます。ポインター (構造全体ではありません。) これは、次の 2 つの理由から重要です。
- パフォーマンス: 4MB 構造のコピーを作成するには時間がかかります。
- コンテンツを変更する機能: ポインターのコピーを作成しても、元のデータは同じ場所にあり、ポインターからアクセスできます。
2 ではなく 1 が必要な場合はどうしますか? それでは、ポインタを宣言できますconst
。プロトタイプは次のようになります。int f(int const* a);
1 ではなく 2 が必要な場合はどうしますか? タフなクッキー (とにかく正当な理由はありません。)
最後に、ポインターではなく参照を取る関数を宣言することもできます。参照とポインターの大きな違いは、参照が NULL にならないことです (また、参照に対してポインター演算を使用することはできません)。通常、参照渡しまたは値渡しのいずれかを使用します。ポインターで渡す必要があることは、私がほとんどする必要がないことです。私の経験では、それはより特殊なケースのようなものです。
参照int f(int& a);
渡し: const 参照渡し:int f(int const& a);
要約すると:
if you have function that needs parameters:
then:
if you do not need to modify the contents:
then:
if the size of the variable is small:
pass by value: int f(int a);
else if the size of the variable is large:
then:
if the value of the address can be NULL:
pass by const pointer: int f(int const* a);
else:
pass by const reference: int f(int const& a);
else if you do need to modify the contents:
then:
if the value of the address can be NULL:
pass by pointer: int f(int* a);
else:
pass by reference: int f(int& a);
他にもいくつかのケースがありますが、これらは主なものです。詳細については、この Web サイトを参照してください。