• 締切済み

char *(*)[];について

#include <iostream> using namespace std; main(){ char *(*pp)[2]; printf("%lu", sizeof(char*)); printf(" pp%lu", pp); printf(", ++pp%lu", ++pp); } これを実行して 4 pp6660000, ++pp??????? のように表示されたときに、???????の部分が何になるか考えました。 ppはchar[2]を指すポインタのポインタだから、ppをインクリメントすれば、「char[2]を指すポインタ」の大きさだけ大きくなるはずだから、「char[2]を指すポインタ」の大きさである4バイト大きくなるはずだから 4 pp6660000, ++pp6660004 になると思いました。 どこを勘違いしていてどう考え直せばよいか教えて下さい。

みんなの回答

  • ency
  • ベストアンサー率39% (93/238)
回答No.4

No3 encyです。 え~と。。。ひょっとして試されちゃったのかな?私ったら…(?) ま、それはさておき、一点だけ確認させてください。 sizeof( char* ) はいくつですか? 基本的には、このサイズの2倍分増えるはずなんですけど。。。 ちなみに、私の手元にある環境では、+8 になりましたよ。 # [私の環境] # OS: WindowsXP SP2 # コンパイラ: Borland C++ 5.5.1 for Win32

mithsc
質問者

お礼

理由を知りたかったです。 ぼくにはなぜそうなのか分かりませんでした。 ありがとうございました。

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

結果は +8 されるということで良いですか。 mithsc さんのご質問の中にある以下の箇所がちょっと違っていることになります。 > 「char[2]を指すポインタ」の大きさである4バイト大きくなるはずだから 誤)「char[2] を指すポインタ」 正)「char (*)[2]を指すポインタ」 ですよね。 つまり、pp は「『ポインタの配列』を指すポインタ」です。 配列を指すポインタは、インクリメントすると配列サイズ分アドレスが進みます。 No1 osamuyさんの例をそのまま使わせてもらって、具体的に説明してみます。 # 勝手に使わせてもらってすみません。。。>osamuyさん。 > typedef char *Tcharptr; > typedef Tcharptr Tcharptrarr[2]; > Tcharptrarr *pp; ここで、サイズを確認していきましょう。 sizeof(Tcharptr) ⇒ 4 # 「char型を指すポインタ」のサイズだから 4 ですね。 sizeof(Tcharptrarr) ⇒ 8 # 「ポインタの配列(要素数2)」のサイズだから # 「ポインタのサイズ」×「配列要素数」= 4×2 = 8 ですね。 ということは、pp は「Tcharptrarr を指すポインタ」ですから、++pp は 8バイト分アドレスが進むことになるんです。 こんな感じでいかがでしょうか。

mithsc
質問者

お礼

僕が予想した 4 pp6660000, ++pp6660004 は間違っていましたが、結果は 4 pp6660000, ++pp6660008 でもありませんでした。 まだこの回答が全部理解できていませんがこれだけ投稿しておきます。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.2

こういうのだと理解しやすいかも。 typedef char *TCharPtrArr[2]; TCharPtrArr a[2]; TCharPtrArr *pp = a; ――で、以下が成り立ちます: *pp == a[0] *(pp + 1) == a[1] p++は、p=p+1ですから、メモリアドレス空間的には、aの要素1個分(i.e. sizeof TCharPtrArr)だけ移動する事になります。

参考URL:
http://www.st.rim.or.jp/~phinloda/cqa/cqa3.html
全文を見る
すると、全ての回答が全文表示されます。
  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

> char *(*pp)[2]; 分けて書くと、以下のようになります: typedef char *Tcharptr; typedef Tcharptr Tcharptrarr[2]; Tcharptrarr *pp; なので、「char[2]を指すポインタ」のポインタでなく、「char型ポインタ二つ分の配列」のポインタではないかと。 char[2]を指すポインタのポインタなら、こうでは: char ( **p )[2];

mithsc
質問者

補足

日本語が変でしたね。でも、「char型ポインタ二つ分の配列」のポインタということは分かっていました。 やっぱりそのサイズは4で、 4 pp6660000, ++pp6660004 になると思いました。 osamuyさんも6660004になるはずだと思いませんか?

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

関連するQ&A

  • char *(*)[3];について

    #include <iostream.h> main(){ char *(*pp)[3]; printf("%lu", sizeof(char*)); printf(" pp%lu", pp); printf(", ++pp%lu", ++pp); } これを実行して 4 pp6660000, ++pp??????? のように表示されたときに、???????の部分が何になるか考えました。 ppはchar[3]を指すポインタのポインタだから、ppをインクリメントすれば、「char[3]を指すポインタ」の大きさだけ大きくなるはずだから、「char[3]を指すポインタ」の大きさである4バイト大きくなるはずだから 4 pp6660000, ++pp6660004 になると思いました。 どこを勘違いしていてどう考え直せばよいか教えて下さい。

  • アドレスをintに代入する方法

    適当なアドレスをprintfで表示し、その値をintに代入するのが目的です。 #include <iostream> using namespace std; main(){ char buf[20]; char **pp; char *p = "\0"; int i; pp = &p; printf("%lu\n", pp); sprintf(buf, "%lu\n", pp); i = atoi(buf); printf("%lu\n", i); } とりあえずできていますが、 pp = &p;以降の処理で、bufを使ったり非推奨?のatoi()を使っています。 pp = &p;以降の処理でもっとよい方法はないでしょうか?

  • アドレスをint変数に代入する方法

    printfで表示したアドレス値を、int変数に代入するのが目的です。 #include <iostream> using namespace std; main(){ char buf[20]; char *(*pp)[2]; char *p[2]; int i; pp = &p; printf("%lu\n", pp); // i = (int)(&pp); sprintf(buf, "%lu\n", pp);//// i = atoi(buf);//// printf("%lu\n", i); } とりあえずできていますが、 pp = &p;以降の処理で、bufを使ったり非推奨?のatoi()を使っています。 pp = &p;以降の処理でもっとよい方法はないでしょうか? また、このソースは不正なことをやっていないでしょうか? 必要な初期化をやってない、などということはありませんか?

  • C++のnamespace stdについて

    C++のnamespace stdについて教えて下さい。 coutを使用する場合"iostream"をインクルードし、using namespaceでstd名前空間を使用します。 printfを使用する場合"cstdio"をインクルードし、using namespaceでstd名前空間を使用します。 どちらのインクルードファイルにもnamespace stdという風に同じ名前の名前空間を 使用しているのでしょうか? もしもそうだとしたらcstdio,iostreamの両方をインクルードしている場合 名前空間が競合してしまうのではないでしょうか? namespaceはjavaでいうパッケージにあたる物だと思っていたので、 これでは意味がないのではないかと思いました。 それとも意図的に同じ名前空間を定義している意味があるのでしょうか? C++を使い始めたばかりで戸惑っています。どなたかお答え頂ければありがたいです。

  • この文章正確ですか?

    #include <string> #include <iostream> using namespace std; int main(){ string s1; s1 = "こんにちわ"; count << s1 << endl; } これをコンパイルしようとしてもできません。 どこが間違っているのでしょうか?

  • char[]とchar*

    #include<iostream.h> main() { char str1[] = "AB"; char *str2 = "ab"; *(str1+1) = 'C'; *(str2+1) = 'c'; printf("%s\n", str1); printf("%s\n", str2); } このソースの *(str2+1) = 'c'; の所はC++では間違った処理ですか? []かnewなどの変数なら書き換えてよいのは分かりますが、str2はこれでよいのか教えて下さい。

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • C++言語で文字列を出力するにはどうしたら良いですか。

    C++言語で文字列を出力するにはどうしたら良いですか。 今、ポインタの勉強中ですが、ポインタの使い方がよく分からないです。 次のコードで ---------- one two three ---------- を出力したいのですが、nしか出力できません。 どうやらoneのnしか出力できません。 どのようなコードを書いたら解決できますでしょうか。 ------------------------------------------- #include<iostream> using namespace std; char name[3][10]={{"one"},{"two"},{"three"}}; char f(const char *name,int i){ return name[i]; } int main(){ cout << f(name[0],1) << endl; } -------------------------------------------

  • プログラミング言語Cとプログラミング言語C++

    プログラミング言語Cとプログラミング言語C++の違いって何ですか? あと、プログラミング言語C++についていくつか質問があります。 #include <iostream> using namespace std; void main(){ cout << "Hello world!" << endl; } このプログラムについて質問なんですが、iostreamってプログラミング言語Cで言うstdio.hのことですか? using namespace stdって何ですか? あと、 cout <<"Hello world!"って何ですか?

  • 改行文字について

    #include<iostream> using namespace std; int main(void) { char c; while (cin.get(c)) if (c == '\n') cout << "[RET]\n"; else cout << c; return(0); } これのif (c == '\n')の改行文字と等しいとは何のことを指すのでしょうか? よろしくお願いします。