• 締切済み

フルポインタ仕様にしたい。

プロローグ ポインタはデータがメモリさせれいるアドレスを扱うので、引数では関数を呼び出すたびにデータ本体をコピーせずにすみます。 だから、限られた資源の中比較的高速のプログラムができる… でも、ポインタはスペースシャトルの機内からロボットアームで小さな作業を行う感覚で、結構厄介な存在でもあります。 でも、ポインタを気持ちよく操れないとゲームなど高速なプログラムはできません。 そこで、データのやり取りはアドレスのみというルールで、簡単なプログラム書いてみましたが、コンパイルしてくれるものの、エラーが発生して動いてくれません。どこがおかしいのでしょうかご教授おねがいします。もし、「ポインタのみで作るのは無理があるでしょう?」と思う場合は「そりゃむでっせ」とか書いてください。 #include <iostream> using namespace std; class Bass{ private: int* m_piData; // ポインタ変数(int) double* m_pdData; // ポインタ変数(double) public: void SetData(int* piData, double* pdData); void DataShow(int* piData, double* pdData); int iGatData(){return *m_piData;} double dGatData(){return *m_pdData;} }; void Bass::SetData(int* piData, double* pdData) { *m_piData = *piData; *m_pdData = *pdData; } void Bass::DataShow(int* piData, double* pdData) { cout << *piData << 'と' << *pdData << '\n'; } int main() { int iTestData=1234; // int型データ(表示用) double dTestData=20.5; // double型データ(表示用) int* piTestData; double* pdTestData; Bass* c_pBass; // private変数データ書込み・ポインタ c_pBass->SetData(&iTestData, &dTestData); // インライン関数(private変数関数)・ポインタ *piTestData = c_pBass->iGatData(); // int型 *pdTestData = c_pBass->dGatData(); // double型 // private変数参照 c_pBass->DataShow(piTestData, pdTestData); return 0; }

みんなの回答

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

既に書かれていますが… ポインタはなにか(どこか)を指し示すものです。 ポインタ変数を定義したからと言って指し示す先が虚空から生まれるわけではありません。 動的にメモリを確保するとか、変数を挿すようにする等の作業が必要です。

全文を見る
すると、全ての回答が全文表示されます。
  • ddnp009
  • ベストアンサー率25% (15/58)
回答No.3

パフォーマンスを上げるために引数をポインタ渡しにする・・・ 間違いではないけれども、下に示すキーワードでお勉強なさってください。 『const』『reference』『const reference』 > Bass* c_pBass; > > // private変数データ書込み・ポインタ > c_pBass->SetData(&iTestData, &dTestData); Baseクラスの実体が無いので使えません。 「そりゃむでっせ」

nVIDIA
質問者

お礼

はい!お勉強します! お勉強のポイントを教えてくださってありがとうございます。

全文を見る
すると、全ての回答が全文表示されます。
回答No.2

  > エラーが発生して動いてくれません。  どんなエラーでしょうか。 > class Bass{ > private: > int* m_piData; // ポインタ変数(int) > double* m_pdData; // ポインタ変数(double) > ・・・  ポインタが参照すべき値を入れる領域がないのでは。  

nVIDIA
質問者

補足

「Just-In-Time デバッグ」というウインドがあらわれ「いいえ」を選択すると、 おなじみの真っ黒画面に ハンドルされていない例外:System.NullReferenceException:オブジェクト参照がオブジェクト インスタンスに設定されていません。 at Bass.SetData(Bass* , Int32* piData, Double* pdData) in d:\ディレクトリ名\ファイル名.cpp:line 21 at main() in d:\ディレクトリ名\ファイル名.cpp:line 39 Press any key continue 以上が表示されていました。

全文を見る
すると、全ての回答が全文表示されます。
  • namacya
  • ベストアンサー率8% (21/243)
回答No.1

// private変数データ書込み・ポインタ c_pBass->SetData(&iTestData, &dTestData); この時 c_pBassの値は不定であるため。。。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 【C言語】別関数でポインタの値を変えたのに変わらない。

    【C言語】別関数でポインタの値を変えたのに変わらない。 メイン関数のポインタの値を、別関数で書き換えるプログラムを作りました。 以下がそのプログラムになります。 そのままだと、ダブルポインタを操作する必要があるので分かり辛いです。なので、ダブルポインタをシングルポインタにしてからポインタの書き換えを行うようにしました。その結果、きちんとポインタの書き換えが出来なくなってしまいました。 なぜ出来なくなってしまったのでしょうか。 2つのプログラムの違いは、 >  *pp = &dummy; が >  p = *pp;      // ダブルポインタをシングルポインタにした >  p = &dummy; に変わっただけです。 【参考】http://www.kouno.jp/home/c_faq/c4.html#8 -----------------正しいプログラム---------------- // 以下プログラムは、正しく動作する // 実行結果は、 //   p = 5 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   *pp = &dummy; } ---------------------------------------------- -----------------間違いプログラム---------------- // 以下プログラムは、正しく動作しない // 実行結果は、 //   p = 0 // と表示される void func( int **pp ); int main (void){   int *p;   int a = 0;   p = &a;   func( &p );   printf("p = %d\n", *p);   return 0; } void func( int **pp ){   static int dummy = 5;   int *p;   p = *pp;      // ダブルポインタをシングルポインタにした   p = &dummy; } ----------------------------------------

  • プログラミングテクニックについて(C言語).

    こんにちは.私は,大学でアプリケーションソフトをつくる作業を研究の一環としてやっています.C言語でコードを書いているのですが,計算処理の高速化を 実現したいと切に願っております. 例えば,以下のように2つの関数main とTest,があるとします. そのとき,Testは計算結果を返さないとします. #define MAX 100 void Test(i,j data); int main(void) { double data[MAX][3] for (i = 0; i <= MAX; i++ ){ for (j = 0; j <= MAX; j++){ // Test(i,j data); } } return 0; } この場合,毎回Test関数を呼ぶたびにdata配列を指すポインタを 渡し,さらにTest()関数内に定義されているローカル変数用のメモリ領域も 確保されます. ということは,処理を高速化するためには なるべくTest関数内の変数を できるだけへらせばいいのでしょうか? みなさんがプログラムを組むときに留意されているテクニックを 教えて頂きたいです. できればVC++ver6.0でのデバックツールをどのように つかってバグフィクスしておられるのかうかがいたいです. 以上、よろしく御願い致します.

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

  • Javaでポインタ的なことはできるか?

    JavaでC言語のようにポインタを使おうとしたらJavaには ポインタが表面上はサポートされていないことを知りました。 関数を呼び出した際に、呼び出し元の変数に影響を与えるようなプログラムは Javaで作れるのでしょうか? 例えば、以下のプログラムはCで関数を呼び出した際に呼び出し元の 変数の中身を関数内で書き換えてしまうプログラムです。 こういうことをJavaでするにはどう書けばよいのでしょうか? もしこういうことができないのであれば、Javaにはポインタに代わるやりかたがあるのでしょうか? 実行結果: 1 10 #include <stdio.h> void func( int *n ){   *n = 10; } int main(){   int n = 1;   printf("%d ", n );   func( &n );   printf("%d ", n ); }

    • ベストアンサー
    • Java
  • C言語でポインタを使ってピタゴラスの定理の関数を作りたいです

    私は今あるプログラムを書いていて、その過程でどうしても関数を使ってピタゴラスの定理を作りたいのですが、ポインタの渡し方がうまくいきませんでした。ポインタを使わない場合は次の通りでした。 double pythagoras(double a, double b){ double c; c = a*a+b*b; c = sqrt(c); return c; } これはメイン関数で二つの値a,b(int型)をpythagoras関数に入れて、ピタゴラスの定理を適用させてメイン関数にc(double型)を戻り値として返すものです。 しかし2つの値a,bがint型ではなくポインタだとうまくいかないです。どのような関数を作ればいいか分かる人がいたらぜひ教えてください。ちなみに現在a,bは次のように宣言してあります。 struct node { int a; int b struct node *next; };

  • 関数の引数と実引数の取り扱いについて

    C言語初心者です. 関数の引数と実引数の取り扱いについて,教えていただきたいことがあります. 例えば,2変数の和を求める関数を考えると,以下のようになると思います. #include <stdio.h> double sum(double x, double y); int main(void) { double a, b, wa; a=2.0; b=3.0; wa=sum(a,b); return 0; } double sum(double x, double y) { double total; total=x+y; return total; } このとき,mainプログラムでは,a,bふたつの変数を定義しておいて,関数sumに入れて計算させているわけですが,mainプログラムで変数x,yを定義しておいて,以下のようなプログラムにするのはありでしょうか? 参考書などをみると,前者のように取り扱っているようなのですが,試しに後者で実行させてみても同じ結果となりました. #include <stdio.h> double sum(double x, double y); int main(void) { double a, b, wa; a=2.0; b=3.0; wa=sum(a,b); return 0; } double sum(double x, double y) { double total; total=x+y; return total; }

  • C++ オート変数にポインタを代入したら?

    処理の初めに、オブジェクトTestClassにデータm_intDataをセットします。その後、ループ内の関数Func内で、m_intDataを取得し、それを元にいろいろな処理をします。この時、Func内でのオート変数intDataTestにm_intDataのポインタを代入しているのですが、Funcを抜けた時にintDataTestがスコープから外れるために、intDataTest = m_intDataも開放されてしまうのでしょうか?もしそうなら、2度目にFuncを呼び出した時は、m_intDataは不定値になっていて、2度目のFuncを抜ける時、すでに開放した領域を開放しようとしてエラーになりますか? もっと複雑な本物コードを動かすと、1度目のFunc呼び出しでは有効値が入っていたintDataTestが、2度目では、すべて0になってしまっていました。 本当は、Funcが何回呼び出されても、最初に設定したintDataTestのデータを読み込みたいのですが、どのように直せばよいのかわからず、困っています。 また、私の理解が間違っていましたら、正しい解釈を教えて下さい。 //------------------------------------------------------------------------- class TestClass { private:   int* m_intData; public:   TestClass()   {     m_intData = NULL;   }   ~TestClass()   {     if( m_intData != NULL )     {       delete m_intData;       m_intData = NULL;     }   }   void SetData( int* intData )   {     m_intData = intData;   }   int* GetData()   {     return m_intData;   } }; //------------------------------------------------------------------------- void Func( TestClass* pClass ) {   int* intDataTest = pClass->GetData();   // この後、いろいろな処理 } //------------------------------------------------------------------------- int main() {   int* intData = NULL;   intData = new int[10];   for( int i = 0; i < 10; i++ )   {     intData[i] = i;   }   TestClass* pClass;   pClass->SetData( intData );   for( int i = 0; i < 5; i++ )   {     Func( pClass );     // この後、複雑ないろいろな処理   }   return  1; } //-------------------------------------------------------------------------

  • Javaの細かい仕様を教えていただけませんか?

    ずっと前にちょろっと触ってJavaは一端離れていましたが 仕様を細かく確認してみたくなったので、駆け足で先ほどまた触れてみました。 なお、それぞれ触れた時間はだいぶ違いますが、プログラミング言語に関してはC、C++、C++/CLI、C#、HLSL、PHPは経験があります。(アセンブリはほんの少しだけ読める程度) なのでそれら(とくにC++)との比較を教えていただけると早く理解が出来そうで また、かなり多くの質問があります(だいたいは基本的なことでしょう)が、全部でなくとも、一部でもいいので教えていただけると助かります。 ためしに以下のようなコードを書いてみました。 class MySamplePrint { private static interface PrintIF { void Print(); //(1) } private static final class MyClass1<T> implements PrintIF { private final class Nest1{ private int num = 0;} private final Nest1 n = new Nest1(); //(2)、(3) private final T data; MyClass1( T data_, int num_ ){ //(4) data = data_; n.num = num_; } MyClass1( final T data_ ){ data = data_; } //(5) //MyClass1(){ this((T)0); } //(6)、(7) //(8) public void Print(){ System.out.println(data); System.out.println(n.num); } } public static void main(String[] arg){ PrintIF a = new MyClass1<Integer>(123); //(9) a.Print(); final MyClass1 b = new MyClass1("abc"); //(10) a = b; a.Print(); a = new MyClass1<String>("def",234); a.Print(); int i = 0; { //int i; //(11) int x = 0; } int x = 1; //(12) final PrintIF c = new MyClass1<String>("def",234); c.Print(); } } 結果 123 0 abc 0 def 234 def 234 (1) C++ でいうconstメンバ関数はJavaにもないですか?(可能であればvoid Print() const;のようなものを書きたい) (2)コンストラクタと、このようにメンバの宣言場所でついでに 「型 変数 = 何々;」については、どっちが先かとか明確な順番は規格上定義されているのでしょうか? (3)メンバ変数にも、このようにfinalを付け、コンストラクタ(か 「型 変数 = 何々;」)で一度だけ値を代入する、といったことが、試したら出来ましたが、これは仕様上普通に可能って事になっていますか? (4)C++でいう、int num_ = 0など、書かなかった場合それになる、というデフォルト引数というものは、Javaにもないんでしょうか?(つまり、呼び出し側で同じような書き方をしたければこのようにオーバーロードを使う?) (5)ローカル変数同様、引数にも普通にfinalを指定可能…? (6)C#ではC++の初期化子リストっぽく MyClass1() : this(何々){ } とか言う書き方になるかと思いますが、Javaでは専ら{}内にのみ記述(this(何々)だったら一行目)でしょうか? (7)この行はコメントアウトすると 「int から T へキャストすることはできません」 とエラーになります。 んでも(T)""にすると一応通ります。 String型などと整数の0(nullを意図してほしい)は互換性がないのでしょうか (8)C++やC#のoverrideのようにオーバーライドを明示的に示す方法(や、C#のnewに匹敵するものとか)はありませんか? (9)<int>はできませんでした。ジェネリックスに指定できる型にはどういう制限があるのでしょうか? (10)警告は出ましたが、<String>を省略しても通ってしまいました。これは興味本位で、実際は警告も出るので指定はすると思いますが、これは仕様ですか? (11)この場合、xは可ですがiはダメでした。つまり、CやC++と違い、スコープがより狭い範囲に変わっても「それまでに、より広いスコープで宣言されていた名前」とかぶる変数名の変数は宣言できない、ということでしょうか? (12)C++的には、このcは参照(というよりポインタに近い)と考えて、この場合finalはc自体の変更を阻止していますが、参照先の内容は変更可能に思います。 CやC++的には const PrintIF* c = ~ ではなく PrintIF* const c = ~ と同じ意味 出来れば const PrintIF* c = ~ や const PrintIF* const c = ~ といったことも可能だといいのですが、Javaでは仕様上、それは無理、でしょうか? その他、コード以外で (13)アクセス修飾子の指定を書かないと、Javaでは同一パッケージ内で参照可能、ということですが、この「パッケージ内」というのは、これはC#でいうinternalのような意味あいになる、ということでしょうか? (14)Javaでは非staticなメソッドは全て、C++でいうvirtualに自動的になる、ということでしょうか?(逆に言うと明示的な、virtualに相当する修飾子がない?) (15)Eclipseで タブが> 改行が曲がった矢印 で、全部の行に表示されるのですが テキストの色や背景色(白)の変更や、これらを非表示にする といったことは可能ですか?

    • ベストアンサー
    • Java
  • オブジェクト指向で、インターフェースにないメソッドを呼ぶ

    こんにちは。質問させてください。 現在C++でプログラムを書いているのですが、以下のようなプログラムを書いたとします(これ例ですので、実際のプログラムとは異なります)。 // ポインターを抽象化 class PointerInterface { }; // 抽象化したクラスを継承して整数型のポインタを作る class IntPointer : public PointerInterface { private:   // int型のポインタ   int *p; public:   int* get()   {     return p;   } }; // 抽象化したクラスを継承して少数型のポインタを作る class FloatPointer : public PointerInterface { private:   float *p; public:   float* get()   {     return p;   } }; PointerInterface* CreateInterface( bool flag ) {   PointerInterface* result = 0;   if( flag )   {     result = new IntPointer;   }   else   {     result = new FloatPointer;   }   return result; } void setIntPointer( PointerInterface* ptr ) {   // ここでint型のポインターを取り出して操作したい } void main() {   PointerInterface* ptr = CreateInterface( true );   setPointer( ptr ); } インターフェースは同じなのに継承先に内含されている変数のタイプが違い、それを取得したい場合が出てくると思います。 こういう場合どのように実装すれば、より美しくコーディングすることができるでしょうか? /* 私は 1:PointerInterfaceにvoid*を戻すメソッドを宣言する 2:setIntPointerの中で無理やりキャストして子クラスのgetを無理やり呼び出す という2つの方法が思いついたのですが、なんだかどっちのコーディングもピンときません。 お知恵を貸してください! ※今回はtemplateを使うというのは、なしでお願いします。 */

  • 変数の有効範囲について

    C言語の課題について教えてください [課題] 以下の関数がある。各関数の引数、変数は自由に設定していい ・int main() ・void Wrapper() ・void setdate(int *pset) { *pset = 10; } ・int *getdate() 問題 (1)main関数から、Wrapper関数を経由して、setdate関数を経由し値を取得し、表示する 意図としては、main内で、実態を宣言し、setdate関数内で値を代入し、main関数内で表示 (2)main関数から、Wrapper関数を経由して、getdate関数を経由し値を取得し、表示する 意図としては、main内でポインタを宣言し、getdate内で実態を宣言しそのアドレスをかえし、main関数内で表示 以下が考えたソースになります #include <stdio.h> int *getdata(void) { static int num = 100; printf("num[%p]\n",&num); } void setdata(int *p) { *p = 1; } void Wrapper(int *pw, int type) { if (type == 0) { *pw = *getdata(); } else { setdata(pw); } } int main(void) { int *get, set; Wrapper(get, 0); printf("get[%d]\n", *get); Wrapper(&set, 1); printf("set[%d]\n", set); return 0; } setdateの関数に関してはわかるのですが、getdateの関数は、実施したい内容とは異なると思うので、修正していただきたいです。 このやり方だと、参照しているアドレスはmain内で宣言した場所でありget関数で宣言した場所ではないと思うのです。