- ベストアンサー
ポインタについての良いテキストを探しています
sankaku197の回答
- sankaku197
- ベストアンサー率47% (29/61)
ダブルポインタ、トリプルポインタについて。 p1 → p → オブジェクト このイメージで分かりますでしょうか? 「p1はpの実体を指したい場合」があります。 この時、pが頻繁にnewとdeleteを行う場合、以下のようにしてしまうと問題があります。 int *p = new int; int *p1 = p; delete p; p = new int; //この時点でp1はdeleteされたアドレスを指している これをイメージ化するとこうです。 p > オブジェクトA p1 ↓ p - オブジェクトB p1 - オブジェクトA つまり最初のイメージ「ポインタpを指すポインタ」が必要になってきます。 int *p = new int; int **p1 = &p; delete p; p = new int; トリプルポインタも同様に考えていけば良いと思います。 p2 → p1 → p → オブジェクト
関連するQ&A
- トリプルポインタが必須!となる状況ってありますか?
不具合が生じ、業務ソースのエラー処理の部分まで掘り進んで見ていたら、 トリプルポインタ(ポインタのポインタのポインタ)を使用している部分がありました。 外注で中国産のソースのようで、当人に聞くことはできず、 周りの知識人に聞いてみたのですが「それでうまく動いているんならいいんじゃないの?」と 素っ気ない対応でした。 トリプルポインタが必須となる状況はあるのでしょうか? 構造体がネストしていてそのメンバに文字列があって… となっている場合などでもダブルポインタ(ポインタのポインタ)で処理できるように思います。 そんなときにトリプルポインタを使うよっていう状況やサンプルがありましたら教えてください。 よろしくお願いいたします。 ちなみに、不具合は単純なものですぐに解決しました。
- 締切済み
- C・C++・C#
- ポインタのポインタの必要性
書物によるとポインタのポインタの使用例として「ポインタの配列」はポインタを使ってアクセスすることができます。」[*]とありますが、どうしてポインタのポインタが必要なのかがいまいちピンと来ません。 どういう場合なのかを知りたく思っています。 [*]サンプルスクリプト ===================================================== char *mnthp[3] = {/* ポインタの配列の宣言 */ "January", "February", "March" }; char **p1;/* 「ポインタのポインタ」の宣言 */ int i, j; p1=mnthp;/* 「ポインタのポインタ」にポインタの配列 */ /* の先頭番地を設定 */ /***** 例1 *****/ for (i = 0; i < 3; i++) {/* 「ポインタのポインタ」の値を変えずに */ printf("%s\n", *(p1 + i));/* 相対的に文字列を出力 */ } ==> このようなことをしなくとも printf("%s", mnthp[i]); で値を参照出来ると思われる。 ===================================================== [*] http://www9.plala.or.jp/sgwr-t/c/sec10-4.html 宜しくお願い致します。
- 締切済み
- C・C++・C#
- ポインタのポインタの初期化法
文字列をポインタを使って扱うとき、例えば、初期化は次のように行えますよね。 #include <stdlib.h> char *s; s = (char *)malloc(1000); (これに続いてscanf("%s", s);など) これと同様にして、二次元の配列を、ポインタのポインタを使って表したいとき、 char **s; と宣言したものを、malloc()関数を使って初期化することはできるのでしょうか。よろしくお願いします。
- ベストアンサー
- C・C++・C#
- ポインタ変数とポインタのポインタ
ポインタ変数の宣言 char *a[]; をしたとき僕の中では a[0],a[1]...という、ある文字列A,B,C...の最初のアドレスを指すポインタが、配列になっているものを宣言していると理解していました。 しかしこの次に、ポインタのポインタが出てきました。僕はこれを、 ある変数を指し示すアドレスのアドレスである、と理解しました。 この2つは1つめはいくつかのアドレスを指し示すもの、2つ目は1つのアドレスを指し示すものであるとして、僕の中で異なったものであると理解していましたが、参考書「C標準コースウェア」によると プログラムにおいて、関数でポインタ配列を受け取るときchar *p[]はchar **pとしてもよい と書かれており、またその実例として、 (9-5) #include <stdio.h> void disp (char *p[],int n){ int i; for (i= 1;i<n;i++){ printf("%s\n",p[i]); } } int main(void){ char *girl[] = {"Arica","Candy","Lisa"}; disp (girl,sizeof(girl)/sizeof(girl[0])); return 0; } というプログラムが書かれていました。 ここで一気に訳が分からなくなりました。 char *girl[] = {"Arica","Candy","Lisa"}; と宣言されているため、 girl[0]はAricaという文字列の最初のアドレスを指すポインタ、 *girl[0]はAricaという文字列を直接指し示していると解釈しています。 girlは{"Arica","Candy","Lisa"}という文字列の配列の最初のアドレスを指し示していると考えました。 sizeof(girl)を使った時に不思議なのですが、 girlはどのように配列の終わりを理解しているのでしょうか? (配列の要素数を渡していない点が不思議です。) また、 disp側が受け取ったのは*girl[]であり、いくつかのポインタの配列ですが、渡したものはgirlという要素数がないポインタ1つだけです。 そして最初の疑問が出てくるわけですが、*p[]を**pと書きかえてみると、 文字列のアドレスを示すgirlという名の1つのポインタを渡すと、pという名のポインタのポインタで受け取るというのも、よくわからなくなっています。 おそらくポインタ配列に対する理解がどこかでずれているようですが、自分でどこがわからないのかわからなくなっています。 どうかご教授ください。
- ベストアンサー
- C・C++・C#
- ポインタ
文字列"apple", "orange", "strawberry"へのポインタをポインタ配列の各要素に代入した後,その文字列の文字を逆順に表示するようにプログラムを考えているのですが、 while文の中のjはそれぞれについて考える必要がありますか? ポインタを使って文字数を数得られそうですが出来ませんでした。 [実行例] ポインタ配列[0]の文字列の逆はelppaです. ポインタ配列[1]の文字列の逆はegnaroです. ポインタ配列[2]の文字列の逆はyrrebwartsです. #include<stdio.h> #define COUNT 3 int main(void) { char * words[COUNT] = {"apple", "orange", "strawberry"}; int i, j; for(i = 0; i < COUNT; i++) { j = ? ; printf("ポインタ配列[%d]の文字列の逆は", i); while( ? ) { printf("%c", *(words[i] + j)); j--; } printf("です.\n"); } return 0; }
- ベストアンサー
- 情報工学
- C言語 ポインタと配列の違いが理解できません。
ポインタと配列の違いとは何でしょうか? 自分は学校で習ったのですがあまり深くはやってくれず良く理解していないままです。 ・ポインタと配列はしまう場所は同じなのでしょうか? ・単にしまい方、呼び出し方が違うだけなのでしょうか? ・ポインタと使えるところでは配列も使えるのでしょうか? ・そもそもしまわれる場所って何処なのでしょうか? 基礎中の基礎のことなので申し訳ないですが教えてください。 後、「」←このサイト見ろ だけのような解答は無しでお願いします。
- ベストアンサー
- C・C++・C#
- ポインタと多次元配列についての質問です
私の使っている本に、 『ポインタを使って多次元配列にアクセスするには、コンパイラが自動で行っていることを手作業で 行わなければなりません。たとえば、次の配列には各列に5つの要素があります。 float balance[10][5]; したがって、ポインタを使ってbalance[3][1]にアクセスするには、次のようなコードを使用 しなければなりません。 float *p; p = (float *) balance; *(p + (3*5) +1) 目的の要素に到達するには、行番号に行の要素数を掛けてから、その要素の行内での番号を 加えなければなりません。上記の例では、balanceをfloat* にキャストする必要がありました。 配列要素を手作業で指定する都合上、ポインタ演算をfloatポインタに基づいて行わなければなりません。 しかし、balanceによって生成されるポインタの型はfloatの2次元配列です。そこでキャストが 必要になるわけです。』 とあります。 【質問1】なぜ、p = (float *) balance; なのか。p = (float) *balance; ではないのか? 【質問2】本文「上記の例では………必要になるわけです。」の意味がわかりません。 未熟者の私ですがどうか教えてください。
- ベストアンサー
- C・C++・C#
- ポインタでつまっています。
いま、ポインタを扱ったクラスの学習をしています。 ポインタの活用が不可欠な,アルゴリズムやデータ構造の勉強を並行して進めることを勧められました。 実際の利用法を知ることが理解の助けになるからとのことです。 そこでポインタとクラスを扱ったサンプルソースを書いていただけないでしょうか? コメントアウトによる解説があると助かります。
- ベストアンサー
- C・C++・C#
- 二次元配列のポインタについて教えて下さい
今日はCの配列のポインタについて質問いたします、宜しくお願いします。 1次元の配列からは、 =================================== int *p , a={1,2,3}; p = &a; printf("%d\n" , p[1] ) ; printf("%d\n" , *p[1] ) ; ===================================== でaの値がとれますが、 二次元の配列では下のような書き方ではエラーになります。 何故でしょうか、どう書いてやればいいのでしょう。 =============================================== printf("%d\n" , pbb[1][1] ) ; printf("%d\n" , *pbb[1][1] ) ; =============================================== 宜しくお願いします。
- ベストアンサー
- C・C++・C#
お礼
ご回答ありがとうございます。 int **p1 = &p; でポインタpのアドレスをp1に保持しておくと、 その後、pをdeleteしてからnewしても、変わらず同じオブジェクトを指すのでしょうか。 delete p; p = new int; は、オブジェクトは別物になるけれど、アドレスは変わらないの…かな? C++は経験がないのでうまくイメージ出来ていないかもしれませんが、 そういう「ポインタのポインタが必要になる」事例が知れてよかったです。 私の場合、ポインタのポインタが必要になるのは、関数への、ポインタ変数のアドレス渡し、くらいしか経験がないので…。 試行錯誤しつついろいろテストプログラムを書いて勉強したいと思います。 ありがとうございました。