• ベストアンサー

**って何でしょう?

はじめまして。C++の勉強をしている初心者です。 あるプログラムを読んでいて分からないところがあったので教えて下さい。(変数名と値は適当です。) #define num 20 int *a; int **b; a = new int [num]; こちらの方は読んでいる参考書(これならわかるC++)に載っていたので、大体分かります。 b = new int * [num]; for (i = 0; i < num; i++) b[i] = new int [5]; これが分かりません。**bとは何でしょうか?検索しようとしても**というのが検索対象にならず検索できませんでした。詳しく解説しているサイトでも良いので教えて下さい。宜しくお願い致します。

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

  • ベストアンサー
  • egeg007
  • ベストアンサー率33% (3/9)
回答No.3

厳密な意味では、ちょっと違うかもしれませんが、 理解しやすくするために以下のように言い換えて みました。 本当は、絵をかければわかりやすいのですが、、、 int *a; 「int型」リスト(配列)の        先頭アドレスをaとする。        ですから、int a[] と同義です。        ※ただし、ここでは配列の実体はなし int **b;  「int型」リスト(配列)の        先頭アドレスを格納するリスト        (配列)の先頭アドレスをb とする。        ですから、int b[][] と同義です。        ※ただし、ここでも配列の実体はなし そこで、各実行文を眺めて見ます。 a = new int [num];      「int型」変数をnum個獲得して、      その先頭アドレスを a に代入。      ここで、aは配列の実体を持ちます。 b = new int * [num];      これは、b = new (int *)[num] と考え      れば、「int型」リストの先頭アドレスが      入る領域をnum個獲得して、その先頭      アドレスを b に代入。      ここで、bにnum個の「リストのアドレス」      を格納できる配列が定義されたことに      なります。      ですけど、このままではリストのアドレス      用領域が用意されただけですので、      b[i] は実体を持っていません。 b[i] = new int [5];      そこで、ここで各配列に実体をつけて      あげます。 ふ~、しんどいですね!? ポインタは、C, C++の'きも'ですので、がんばって みてください。

revolution_2005
質問者

お礼

プログラムの分かりやすい説明有難う御座いました。Cについては学校で基本を習い、配列を使ったプログラムは良く書くのですが、ポインタは殆ど使用していませんでした。 卒業論文でアプリケーションプログラムを実践しているのでC++が必要になり勉強し始めたのですが、複雑なプログラムを書くにつれコンストラクタやらnewやらdeleteなどの必要性が高くなり、四苦八苦です。ポインタは難しいですがこれから理解を深めていこうと思います。有難う御座いました。

その他の回答 (2)

noname#15691
noname#15691
回答No.2

「int*」は「intのポインタ」型 「int**」は「「int*」*」であり、「「intのポインタ」のポインタ」型 さらに、「int***」は「「「intのポインタ」のポインタ」のポインタ」型になります。 つまり、際限はありません。 C言語では「任意の型」に「*」を付けると「任意のポインタ」型になるので、「任意の型」がたまたまポインタだったということです。 int a; int *p; int **q; p = &a; // 「int」変数のアドレスを「intのポインタ」変数に代入 q = &p; // 「intのポインタ」変数のアドレスを「intのポインタのポインタ」変数に代入

revolution_2005
質問者

お礼

ポインタのポインタのポインタのポインタなんて言葉も検索したらありました。実際に使うとなると凄い大変そうです。奥が深いですね。有難う御座いました。

  • 6dou_rinne
  • ベストアンサー率25% (1361/5264)
回答No.1

**はポインタのポインタです。 ポインタについての理解がすすんでくればわかってきますが。

revolution_2005
質問者

お礼

ポインタのポインタというのですね。検索したら結構出て来ました。ポインタについては多少習いましたが、ポインタのポインタは初めて聞きました。有難う御座いました。

関連するQ&A

  • 派生クラスの自動生成

    はじめまして。 表題の件に関して質問させていただきます。 Aを親とした派生クラスをn個作るとします。 B1,B2,B3…Bn これらのインスタンスをクラスCのコンストラクタで生成したいとします。 その再Aのポインタを使いたいです。 このような時num_Aという定数をnum_of_A.hh中でnとdefineして #include "num_of_A.hh" class C::C(){ for(int i=0;i<num_A;i++){ A *a[i]=new A(); } } とする以外の方法がないでしょうか? Aを派生させたBを作ると、自動的にその数をカウントしてくれて、Bの数を書いたヘッダファイルなどを用意せずともC中でその数だけ生成してくれる機構を作ることは可能なのでしょうか? 説明がわかりにくくてすみません。 ご存じのかたご教授よろしくお願いいたします。

  • プログラムの処理について

    主クラスから別のクラスに送るときに 値一個ずつ6回送って処理した値を返すのと 値二個ずつ3回送って処理した値を返すのと どちらが早いのですか? 例1) main(){ int i,ans = 0; int num1[] = new int[6]; for(i=0;i<6;i++){ num1[i] = i+1; ans += ***.keisan(num[i]); } } class ***{ static int keisan(int num){ int x; x = num * 2; return x; } } 例2) main(){ int i,j,ans = 0; ***[] dt = new ***[3]; for(i=0,j=1;i<3;i++){ *** dt[i] = new ***(); dt[i].num1 = dt[i].num2 = 0; dt[i].num1 = j++; dt[i].num2 = j++; ans += ***.keisan(dt[i].num1,dt[i].num2); } } class ***{ public int num1; public int num2; static int keisan(int num1,int num2){ int x; x = (num1 + num2) * 2; return x; } } 上記の構文みたいな感じの状況です 構文が間違ってても気にしないでいただけるとありがたいです

    • ベストアンサー
    • Java
  • インスタンス変数の特殊な参照

    次のようなクラスを考えたときに(特に意味があるものではないですが) class A{ int a; A(){ a = 10; B b = new B(); } } class B{ int b; B(){ b = 20; C c = new C(); } } class C{ int c; C(){ c = 20; } } Cのコンストラクタの中から、Aのインスタンス変数aやBでのbの値を 参照することって出来ないのでしょうか? 変数をクラス変数にする、引数として渡す以外の方法を探しています。

  • Objective-Cについて

    今、Objective-Cを独学で勉強しているのですが、 プログラムで int a1; int a2; int b1 = 1; int b2 = 1; a1 = ++b1; a2 = b2++; NSLog(@"変数a1の値は%dです\n", a1); NSLog(@"変数a2の値は%dです\n", a2); NSLog(@"変数b1の値は%dです\n", b1); NSLog(@"変数b2の値は%dです\n", b2); これで「Run」を押すとそれぞれ、 「変数a1の値は2です」 「変数a2の値は1です」 「変数b1の値は2です」 「変数b2の値は2です」 とOutputされるのですが、この時なぜ「a2」が1と出てくるのか分かりません。 どなたか解説お願いします。

  • 分割コンパイルの初歩

    C言語ですが、.hに実装を書くのは避けたほうが良いといわれます。 私は main.c define.h aaa.h bbb.h みたいなスタイルでコードを書いていました。 まずdefine.hでグローバル変数や、マクロなどの宣言を まとめて行い、ほかの.hやmain.cでも使えるようにして いました。 しかし、以下のような状況のとき、どのように分割すれば 良いのかが分かりません・・・。 たとえば、以下のように、マクロNUM、変数a,bをすべてのファイルで共有して使えるように分割コンパイルするにはどのようにコードを書き直せば良いのでしょうか? //--------------main.c------------------ #include "define.h" #include "aaa.h" #include "bbb.h" int main( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM);   aaa();   bbb();   return 0; } //------------define.h------------------ #define NUM 100 int a = 10; int b = 20; void aaa( void ); void bbb( void ); //------------aaa.h------------------ void aaa( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); } //------------bbb.h------------------ void bbb( void ){   printf("%d", a);   printf("%d", b);   printf("%d", NUM); }

  • C#で、引数にクラスの配列の参照パラメータを渡したい

    C#始めて3日目ですが、そろそろ挫折しそうです。 以下のクラス class Test{ int num; public Test(){ num = 0 }; ~Test(){}; public void set(int n){ num = n; } public int get(){ return num; } } があり、 void kakikae(Te [] t){ for(int i =0; i < 10; i++){ t[i].set(i); } } Test [] test = new Test[10] = { new Test, new Test, new Test, new Test, new Test, new Test, new Test, new Test, new Test, new Test }; kakikae(test); とした時に、test[0]からtest[9]まで 1,2,3,4,5,6,7,8,9 の値が入っている事がしたいのです。 要は、クラスの配列のポインタを渡して、相手側の関数で書き方内容が、関数から戻った時も値渡しでなく 参照渡しのように値が変わって戻ってきて欲しいです。 配列の仕組み、クラスの仕組み、パラメータの仕組みが 分からず、ここから進みません。 1から勉強できるC#の参考書も探しています。

  • C++ なのですがエラーが消えません

    課題のC++プログラムのエラーが消えません,教えてください. 10個の数値を入力し並び替えるプログラムなのですが並び替え部分以外は先生作成のプログラムです. どうかお願いいたします. #include <stdio.h> #define MAX 10 #define OK 0 void inputnum(int num[]); void sortnum(int num[]); void outputnum(int num[]); main(){ int num[MAX]; printf("番号 氏名\n"); inputnum(num); sortnum(num); outputnum(num); return(OK); } void inputnum(int num[]){ int i; for(i=0;i<MAX;i++,num[i]){ printf("数値%d = ", i+1); scanf("%d",&num[i]); } printf("数値入力完了\n"); } void sortnum(int num[]){ int tmp,p,q; for(p = 0; p < 9; p++){ for(q = p + 1; q < 10; q++){ if(num[p] > num[q]){ tmp = num[p]; num[p] = num[q]; num[q] = tmp; } } } printf("並び替え完了\n"); void outputnum(int num[]){ int i; for(i=0;i<MAX;i++){ printf("数値%d = %d\n",i+1,num[i]); } printf("数値出力完了\n"); }; [エラー  Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland 1142122.c: エラー E2140 1142122.c 46: ここでは宣言はできない(関数 sortnum ) エラー E2141 1142122.c 46: 宣言の構文エラー(関数 sortnum ) エラー E2134 1142122.c 54: 複合文に } がない(関数 sortnum ) *** 3 errors in Compile ***]

  • 行列に関して。

    以下の行列を対角成分が最も大きくなるような プログラムをつくりたいのですが 0   1   4  3 7   0   1  -5 1    3   0   7 -2   4   4  -8 #include<stdio.h> #include<math.h> #include<stdlib.h> #define NUM 4 int main(){ /* 初期化 */ int i; /* ループ変数 (行)*/ int j; /* ループ変数 (列)*/ int k; /* ループ変数 */ int imax; /* 最大値のi成分 */ int jmax; /* 最大値のj成分 */ double nmax; /* 最大値を入れるための変数 */ double tmp; /* ソートのための一時的な変数 */ double eps = 1.0e-6; /* 判定値 */ double a[NUM][NUM] = { { 0.0, 1.0, 4.0, 3.0}, { 7.0, 0.0, 1.0, -5.0}, { 1.0, 3.0, 0.0, 7.0}, {-2.0, 4.0, 4.0, -8.0}}; /* 対象とする要素位置 = k */ for( k = 0 ; k < NUM ; k++ ){ /*対象とする要素位置 = k*/ nmax = 0.0;/* 初期化 */ imax = k;/* 初期化 0とは限らない */ jmax = k;/* 初期化 0とは限らない */ /* 1.絶対値の最大値を求める */ for( i = k ; i < NUM ; i++ ){ for( j = k ; j < NUM ; j++ ){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; jmax = j; /* 対象としている行列要素の中で,最大となる行列要素のi,j成分を探す */ /*ここに絶対値の最大値を求め、nmax、imax、jmaxに代入するプログラムを書く*/ /*絶対値の求め方、数学関数fabs(x)を用いる*/ } } } /* 2.行入れ換え */ if( k != imax ){/* 対象としている行と最大値を持つ行が同じなら,入れ替える必要が無い */ for( j = 0 ; j < NUM ; j++ ){ tmp=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=tmp;/* 対象としている行と最大値を持つ行との入れ替え */ /*ここに行の入れ替え行うプログラムを書く*/ } } /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら,入れ替える必要が無い */ for( i = 0 ; i < NUM ; i++ ){ tmp=a[i][k]; a[i][k]=a[i][imax]; a[i][imax]=tmp;/*対象としている列と最大値を持つ列との入れ替え*/ /*ここに列の入れ替え行うプログラムを書く*/ } } } /* 結果の出力 */ for(i=0; i<NUM; i++){ for(j=0; j<NUM; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } /*ここに行列の表示プログラムを書く*/ return(0); } 上のぷろぐらむを実行しても、1個目のfor文の1ループ目で終了してしまい 1行目と、4行目を交換、4列目と1列目を交換した行列だけが表示されます。 結果が以下のような行列にするにはどう改善すればよいでしょうか? -8.0   -2.0  4.0  4.0 -5.0   7.0  1.0  0.0   3.0   0.0  4.0  1.0  7.0   1.0  0.0  3.0 です。

  • ところどころ理屈の解らない記述

    #include<iostream> using namespace std; int main() { const int num = 5; //変数numを5の値で初期化、constを使うから値の変更はない int test[num]; //int型の配列testを初期化 cout << num << "人の点数を入力してください。\n"; //変数numを出力して点数入力を促す for (int i = 0; i < num; i++) { //int型のiを0で初期化 numよりiが小さい場合 iを1増やす cin >> test[i]; //上のfor文によって配列の点数を5回入力 } for (int s = 0; s < num - 1; s++) {  for (int t = s + 1; t < num; t++) { if (test[t] > test[s]) { int tmp = test[t]; test[t] = test[s]; test[s] = tmp; } } } for (int j = 0; j < num; j++) { cout << j + 1 << "番目の人の点数は" << test[j] << "です。\n"; } return 0; } 解るところは、コメントしてあります。 それ以外で解らないところがあるので、(特にnumの後ろにつく-1の意味が解らない) どうかご回答お願いします。

  • 分割コンパイルについて

    現在分割コンパイルが分からずに苦戦しています。 下記のリストは構造体を使わなければコンパイラを通すことができましたが、 使うとなぜか通りません。 あれこれ試しましたがどうしても分かりません。 何がおかしいのでしょうか? *define.hで全てのファイルへの定義や宣言を行わせています。 ////////////// //Main.cpp ////////////// #include <stdio.h> #include <conio.h> #include "define.h" int main( void ){ Tmp[0].c = 15; printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); aaa(); bbb(); getch(); return 0; } ////////////////// // A.cpp ///////////////// #include <stdio.h> #include "define.h" void aaa( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // B.cpp ///////////////// #include <stdio.h> #include "define.h" void bbb( void ){ printf("a: %d\n", a); printf("b: %d\n", b); printf("c: %d\n", Tmp[0].c); printf("NUM:%d\n", NUM); } ////////////////// // define.cpp ///////////////// #include "define.h" int a = 10; int b = 20; struct Parameter { int c; }; struct Parameter Tmp[NUM]; ////////////////// // define.h ///////////////// #define NUM 100 extern int a; extern int b; extern struct Parameter Tmp[NUM]; void aaa( void ); void bbb( void );