K.Maebashi's BBS

ご自由に書き込んでください。雑談も可。
テスト書き込みの類はテスト用掲示板にどうぞ

[日付順表示] [日付順インデックス] [スレッド順インデックス]

新規投稿 | 開設者ホームページへ戻る | ヘルプ

[766] ポインタ完全制覇
投稿者:負け組一号
2007/02/20 02:13:25

はじめまして、プログラミングを勉強するには遅すぎる年齢(28)で C言語を勉強している者です。それも再就職を目指し今は病気療養で傷病手当 で生活している、ま、いわゆる人生の負け組ですが、一応もがくだけもがこうと プログラミングを勉強しだし、前橋さんの著書ポインタ完全制覇を読みました。 そこで、本の内容で、ポインタのポインタについて一切触れられてない点が気になり ました。(そんなに、使う物では無いのかな?と勝手に思ってもいますが) それと、int (*func)();の様な形でプロトタイプ宣言したときに、引数の型を明示してないですが了解している警告として受け入れてはいますが 例えば int (*func)(); int func2(int*); とプロトタイプ宣言し、mainブロック内で func = func2; とした時僕としては、プロトタイプ宣言時に int (*func)(void*); としときたいのですが、別の著書では、void*を引数にすると厳しいコンパイラーでは エラーが出るとの事で(僕はVisual C++6.0で勉強していて、引数にvoid*を指定しても しなくても、警告もエラーも出ず実行できてしまいました) 引数は省略するほうが良いのだろうと思いつつ 警告でるなら、なんかやだな。とも思うんです。 かといって、引数として受け取る時にキャストする方法なんて知りませんし (ただの勉強不足なのでしょうが)そこら辺をもうちょっと本の中で知りたかったです。
[この投稿を含むスレッドを表示] [この投稿を削除]
[767] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

はじめまして。 >はじめまして、プログラミングを勉強するには遅すぎる年齢(28)で >C言語を勉強している者です。それも再就職を目指し今は病気療養で傷病手当 お大事に。無理せずがんばってください。 >そこで、本の内容で、ポインタのポインタについて一切触れられてない点が気になり >ました。(そんなに、使う物では無いのかな?と勝手に思ってもいますが) ご意見ありがとうございます。 うーん、ポインタのポインタ(型)、というのは、単にポインタから派生したポインタ型に 過ぎませんから、宣言の読み方からすれば3章の記述で足りそうですし、 実際の使い方としては、4-2-2の「可変長配列の可変長配列」および4-2-4の 「引数経由でポインタを返してもらう」で扱っているつもりです。 また、実際にプログラムを書くときの用途もそんなところです。 もちろん、ポインタのポインタを引数で返してもらうときにはポインタのポインタのポインタを 使いますし、ポインタのポインタの可変長配列を作りたければやっぱりポインタのポインタの ポインタを… いやこっちはさすがに構造体を導入すると思いますが。 まあ、「ポインタのポインタって何だ?」と疑問を持った人が、ポインタ完全制覇で その説明を探すときのことを考えれば、章タイトルに「ポインタのポインタ」が 入っていたほうがよかったかもしれません。 >例えば >int (*func)(); >int func2(int*); >とプロトタイプ宣言し、mainブロック内で >func = func2; >とした時僕としては、プロトタイプ宣言時に >int (*func)(void*); なぜ、 int (*func)(int*); ではだめなのでしょうか。 ひょっとして、funcに代入される実際の関数は、 int func2(int*); int func3(char*); int func4(double*); のうちのどれだかわからない、ということでしょうか。 もしそうであれば、これはちょっと邪悪な書き方だと思います。 # 厳密に言うと規格上もまずいです。int*とvoid*が同じ形式とは限らないので。 どうしてもこういうことをしたければ、私なら、 int (*func)(void*); としておいて、関数側で、受け取った後でキャストします。 int func2(void *a) { int *int_p = (int*)a; ... }
[この投稿を含むスレッドを表示] [この投稿を削除]
[768] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

うーん。なぜ皆「ポインタのポインタ」というのだろうか。すごく不思議。 「ポインタへのポインタ」というほうがわかりやすくて正確だと思うのだが。 ポインタで躓いている人の半分くらいはポインタ左辺値と右辺値の違いがわかってない。 判ってるほうはわざわざ区別する気にならないのであえて明言しないし。 これは概念理解の問題なので、噛み砕いて説明しても無駄な場合が多くて泣きそう。 残り半分は宣言の読み方が判らないだけで、こっちは技術的問題なので慣れでなんとかなる。 int (*pf)(); と int func(int*); は C++ では明確に非互換なので無問題。 C では JIS X 3010:2003 6.7.5.3 関数宣言子にて「関数型が適合とは」の解説があり、 俺的解釈では pf=func; は適合であるため、「警告が出ないのがあたりまえ」 「もし警告が出るとしたら、それはコンパイラが親切なだけ」であると思われる。 int (*pf2)(void*); と int func(int*); は非互換でなきゃならない。 # 元発言者様の発言が質問になっていないので単なる感想。
[この投稿を含むスレッドを表示] [この投稿を削除]
[769] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

>うーん。なぜ皆「ポインタのポインタ」というのだろうか。すごく不思議。 >「ポインタへのポインタ」というほうがわかりやすくて正確だと思うのだが。 同意します。なので「ポインタ完全制覇」では、ある型Tを指すポインタは、 原則「Tへのポインタ」と言っているはずで…と思い、「ポインタのポインタ」で Googleしたらうちのページがトップに来た Σ(゚д゚lll)ガーン >ポインタで躓いている人の半分くらいはポインタ左辺値と右辺値の違いがわかってない。 一応そのつもりで、ポインタ完全制覇では、ポインタはまず型であり、ポインタ型が あるのだから、ポインタ型の変数もポインタ型の値もある、と書いているつもりです。 K&Rに「ポインタはアドレスを格納する変数である」と書いてあるのがやっぱり 諸悪の根源ではないかと。 今は(例によって)酔っ払っているので続きはまた考えます。
[この投稿を含むスレッドを表示] [この投稿を削除]
[770] Re:ポインタ完全制覇
投稿者:CES
2007/02/20 02:13:25

この前、読み方で思いっきり躓いた。 せっかくだからクイズにしてみよう。 問: char 型の配列へのポインタを返す関数の宣言を記述しなさい。 関数名、引数、戻り値の要素数は任意とする。
[この投稿を含むスレッドを表示] [この投稿を削除]
[771] Re:ポインタ完全制覇
投稿者:yuya
2007/02/20 02:13:25

こんにちは、CESさん。面白くてためになる問題ですね。 >関数名、引数、戻り値の要素数は任意とする。 戻り値はポインタなんですよね。 戻り値の要素数というのは? 戻り値であるポインタが指す先のchar型配列の要素数ということでしょうか? それとも、戻り値がポインタの配列になるかも知れないということでしょうか? いや、ポインタの配列を返したくても、その先頭要素へのポインタ(ポインタへのポインタ)を返すしかないわけですけれど(^^;)
[この投稿を含むスレッドを表示] [この投稿を削除]
[772] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

こたえ書いちゃうのは簡単なので、書かずに盛り上げるテスト # この辺、ポインタ中級レベルになるのでしょうか?それとも上級? ここはまず「配列へのポインタ」っつーものがあることを理解しなければならない。 char a[10]; という配列があるとき &a[0] = 配列先頭要素へのポインタ右辺値 (char*) &a = char [10] 配列へのポインタ右辺値 (Q1. この型の表記を行え) である。これも概念レベルの問題なので理解できない人は一生理解しないままだったりする。 # A1.char(*)[10] 型。 Q1'. char(*)[10] と char *[10] の違いを述べよ Q1". char(*)[10] 型の変数を作るにはどう記述するといい? 先の例は「配列へのポインタ」で示される先に実体が1つあるだけ。つまりよくある char c; char* p=&c; と同じレベルの些細でつまらない例に該当する。だからより実用的な例に変えよう。 Q2.char b[5][10]; とするとき &b[0] の型を述べよ (答えは char[10] へのポインタ右辺値) Q3.では b とだけ書いたら何型で何を指す? (暗黙の変換前と変換後の両者を答えよ) Q4.では &b と書いたら何型で何を指す? このへんがすらすら答えられるようになるなら CES さんの問題も簡単。
[この投稿を含むスレッドを表示] [この投稿を削除]
[773] Re:ポインタ完全制覇
投稿者:yuya
2007/02/20 02:13:25

頭の整理のために、ということで。 A1'. char(*)[10] はchar配列(要素数10)へのポインタ。 char*[10] はcharへのポインタの配列(要素数10)。 A1". char (*hoge)[10]; Q3. 暗黙の変換前は 「charの配列(要素数10)の配列(要素数5)」型であり、 b[0]~b[4]の5つ(配列が5つ)のこと。 暗黙の変換後はその先頭要素へのポインタになるので、 「charの配列(要素数10)へのポインタ」型の右辺値となり、 そのポイント先はb[0]です。 「b + 1」はb[1]を、つまり10バイト離れたところをポイントします。 Q4. &bの「b」は暗黙の変換が行なわれないので、 配列そのもの(この場合は「配列の配列」という配列そのもの)になり、 それに「&」を付けた「&b」は「charの配列の配列へのポインタ」型の右辺値です。 「&b」のポイント先は「50バイト分のヒトカタマリ」であって、 「&b + 1」はもはや配列外をポイントするので、 ここを書き換えると何が起こるか分かりません。それこそ >「配列へのポインタ」で示される先に実体が1つあるだけ という状態ですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[774] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

カンペキだ... もう何も言うことは無い。俺が書かなかった内容まで指摘済み。以下蛇足。 > ポイント先は「50バイト分のヒトカタマリ」であって、 これが理解できない人がいる、ってのが理解に苦しむというかなんというか。 int* だって 2byte なり 4byte なりの塊を指すワケだし、何一つ違わないと思うのだが。 もっと言うなら char* だって 8bit の塊 (もっと大きいこともあるが) を指すのだし。 「配列へのポインタ」の存在価値がわからんという人も居たな。 多次元配列(より正確には配列の配列)を考えれば存在価値がわかるだろう。 char a[10]; char (*p)[10]=a; なとき *p=0; と書けないから理解できんのだろうか。そりゃ無謀ってもんだが... っと、先の [772] は yuya さん宛てに書いたのではなくって ROM 者のための課題だったので そこの ROM なあなた、自分で一度考察してみると理解が深まって吉ですぜ。 # 774 げっと
[この投稿を含むスレッドを表示] [この投稿を削除]
[775] Re:ポインタ完全制覇
投稿者:本多
2007/02/20 02:13:25

>「配列へのポインタ」の存在価値がわからんという人も居たな。 >多次元配列(より正確には配列の配列)を考えれば存在価値がわかるだろう。 「配列へのポインタ」という型はもちろん存在価値があるのですが、 読んでてふと思ったことがあります。 「int a[10];」という配列に対して、 「&a」で取得できる「配列へのポインタ」って使い道ってあります? っていうか実務で使った経験ってありますか? int a[10][20]を受け取る関数の引数とかでなく、 配列自身に「&」をつけて、それを使うプログラムを使ったことが、です。 言語仕様を確認しようとしたチョイプロとかじゃなくて 何か明確な意図を持って、それを使わなくちゃいけない または使うほうが適切と判断するような場面ってありましたか?
[この投稿を含むスレッドを表示] [この投稿を削除]
[777] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

たとえばこんなのとか int a[10]; memset(&a, 0, sizeof a); 配列だから &a にせずとも a とだけ書けば事足りるのだが、配列の場合だけ & 不要ってのは (単なる表記の問題ではあるが)初心者を惑わすもととなりうるんで。 typedef int i10[10]; // これは .h ファイルにあって i10 a; memset(&a, 0, sizeof a); // こっちは .c ファイルにある の場合には & ありのほうが自然で、ないのは不自然。 個人的には char (*)[N] を単体で使うってのは他ではナイなぁ。 二次元(以上)配列を使うときに現れるだけだと思う。
[この投稿を含むスレッドを表示] [この投稿を削除]
[778] ポインタ完全制覇へはまだ遠し
投稿者:負け組一号
2007/02/20 02:13:25

レスありがとうございます 私は 技術評論社の入門本物志向が身に付く本(浅井 淳さん 著)とウェブの初心者ページ で初心者としての知識を身につけ 初心者用問題集(確か~望洋さん 著)の本を一通り解いて C言語ポインタ完全制覇(前橋 和弥さん 著)と C言語文字列操作+ファイル入出力完全制覇(山地 秀美さん 著)を買い C言語文字列操作+ファイル入出力完全制覇の構造体を使ったリストの所で 頭がこんがらがり、今は、C言語入門シニア編(林 晴比古さん 著)by ソフトバンク で勉強中で、かつ、プログラムはなぜ動くのか(矢沢 久雄さん 著)by 日系BPを読み アセンブラを勉強した方が良いのか?と思いつつ、とにかくC言語をという感じで 勉強中です。 以上駄文ですが、なにかお勧めの本はありますか?あれば教えて頂きたいです。 このBBSにふさわしくない内容でしたら削除します。駄文もうしわけない。 ちなみに、ポインタに関しては、さし棒と考える事にしてます そんで、array[index]=*((array)+(index))だし これなら、配列に書き込む時オーバーフローしてもしかたがないと思う反面 過去にどっかで、誰か偉い人が、配列というものをポインタとはまた別の物として 規定をなぜしてくれなかったのかと思います。 ついでに、初期化で char array[] = "abcd"; char *p = array; の意味が最初僕はわかりませんでした。「*pの内容にarray?どういうこと?」と思いました これもchar* p = array;とすれば意味がすんなりわかりました。 で、勉強すればするほど、シンタックスシュガーなるもの、プログラミング言語に 存在してはいけないのじゃないのか?と初心者ながらに思いつつ 「まぁ、偉い人がこう決めたんだから、必要性もあるんだろう」と思っています。 以上、失礼します。
[この投稿を含むスレッドを表示] [この投稿を削除]
[779] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

>問: >char 型の配列へのポインタを返す関数の宣言を記述しなさい。 >関数名、引数、戻り値の要素数は任意とする。 用途としては、「\0込みで30文字以内の文字列を可変の個数返す関数」とかですかね。 CADやってたころは、たとえば3次元ポリラインなどで、「double3つの可変長配列」を よく受け渡ししたものです。また、4×4の行列もしょっちゅう引数で受け渡ししました。 配列を引数で渡すとき、 void func(double a[]) のように書けるシンタックスシュガーは、私は混乱を招くだけだと思うのですが、 やっぱりこれを使ったほうが読みやすい、という主張もわからなくはないです。 特に多次元配列では。 でも、仮引数の宣言でしか使えない(戻り値とか、一時変数に代入する時には使えない) んじゃやっぱ中途半端だよなあ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[780] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

本多さん: >「&a」で取得できる「配列へのポインタ」って使い道ってあります? 私の認識は、こっちに書いた通り。 http://kmaebashi.com/programmer/pointer.html | 配列から読み換えられたポインタは左辺値を持たないため、 & 演算子の | オペランドにはならないはずであるが、この例外規則のため、 & でアドレス | (配列の先頭要素のアドレスではなく、配列全体のアドレス)が 取得できる。 | この規則は初心者を混乱させることがある (例えば scanf("%s", buf) でなく、 | scanf("%s", &buf)と書いても 正常に動いてしまう(正常に動いたように見えて | しまう)が、 メリットは今ひとつわからない。 774RRさん: >int a[10]; >memset(&a, 0, sizeof a); >配列だから &a にせずとも a とだけ書けば事足りるのだが、配列の場合だけ & 不要ってのは >(単なる表記の問題ではあるが)初心者を惑わすもととなりうるんで。 strcpy(dest, src)とかでもdestに&は付きませんから、これは付けないほうが むしろ統一が取れるのではないでしょうか。 >typedef int i10[10]; // これは .h ファイルにあって >i10 a; memset(&a, 0, sizeof a); // こっちは .c ファイルにある >の場合には & ありのほうが自然で、ないのは不自然。 MinGWのsetjmp.hより: typedef _JBTYPE jmp_buf[_JBLEN]; でも、setjmp()を使うときは、 jmp_buf buf; if (setjmp(buf) == 0) { ... なのであって、&は付けません。 まあ、前から書いているように、私もこれって不自然だと思うんですが。
[この投稿を含むスレッドを表示] [この投稿を削除]
[782] Re:ポインタ完全制覇へはまだ遠し
投稿者:(ぱ)
2007/02/20 02:13:25

>これなら、配列に書き込む時オーバーフローしてもしかたがないと思う反面 >過去にどっかで、誰か偉い人が、配列というものをポインタとはまた別の物として >規定をなぜしてくれなかったのかと思います。 配列とポインタがこんなふうにこんがらがった変な言語はC/C++くらいなものであり、 たいがいの言語では、明確に別なものとして定義されています(ポインタではなく 参照と呼んでいるかも知れないけれど)。 ポインタ完全制覇にも書いたように、Cはもともと現場の要求を満たすために でっちあげられた言語なので、「ベストな言語」どころか「ベストを目指した言語」 でもないように思います。でも、そこそこよくできていたため広く使われてしまった、 というのが世の常であるわけで。 デザインの「悪い方がよい」原則 http://chasen.org/~daiti-m/text/worse-is-better-ja.html >ついでに、初期化で >char array[] = "abcd"; >char *p = array; >の意味が最初僕はわかりませんでした。「*pの内容にarray?どういうこと?」と思いました >これもchar* p = array;とすれば意味がすんなりわかりました。 これは、 char *p; よりも char* p; と書くほうがわかりやすい、という意味でしょうか? それはそれで否定しませんが、それで問題は解決しない、ということもポインタ完全制覇には 書きました。
[この投稿を含むスレッドを表示] [この投稿を削除]
[783] Re:ポインタ完全制覇
投稿者:CES
2007/02/20 02:13:25

>>問: >>char 型の配列へのポインタを返す関数の宣言を記述しなさい。 >>関数名、引数、戻り値の要素数は任意とする。 > >用途としては、「\0込みで30文字以内の文字列を可変の個数返す関数」とかですかね。 ポインタの読み方から頑張って導こうとしなくても、こんなのを書いちゃうと一発だと、散々悩んでから気がついた。 template< typename ReturnType > ReturnType Test(); std::cout << typeid( Test< char(*)[10] > ) << std::endl; ちなみに、皆さんご存知だと思うけれど、正解はこう(N は要素数)。 char ( * f() )[ N ]; なんでこんなもので悩んでいたかというと、VC++ に奇怪なソースを発見したから。 配列の要素数を数えるコード。 template< typename _TypeOfArray, size_t _SizeOfArray > char ( * __countof_helper( _TypeOfArray ( & )[ _SizeOfArray ] ) )[ _SizeOfArray ]; #define _countof( _Array ) sizeof( * __countof_helper( _Array ) ) __countof_helper は、日本語で言うと「_TypeOfArray 型の配列(要素数は _SizeOfArray 個)の参照を引数に取り、char 型の配列(要素数は _SizeOfArray 個)のポインタを返す関数」の宣言。 返ってきたポインタを間接参照して sizeof すれば、引数に渡した配列と同じ要素数の char 型の配列のサイズ、すなわち引数の要素数が手に入るというカラクリ。 テンプレートに引数配列の要素数まで推測させているのにビックリ。
[この投稿を含むスレッドを表示] [この投稿を削除]
[784] Re:ポインタ完全制覇
投稿者:CES
2007/02/20 02:13:25

>ポインタの読み方から頑張って導こうとしなくても、こんなのを書いちゃうと一発だと、散々悩んでから気がついた。 > >template< typename ReturnType > >ReturnType Test(); > >std::cout << typeid( Test< char(*)[10] > ) << std::endl; マチガヘタ。 std::cout << typeid( Test< char(*)[10] > ).name() << std::endl; が正しい。
[この投稿を含むスレッドを表示] [この投稿を削除]
[786] 難解不落のポインタ すべてはプログラマにゆだねられ プログラマはポインタに揺らされる
投稿者:負け組一号
2007/02/20 02:13:25

Thank you for res. >char *p; > >よりも > >char* p; > >と書くほうがわかりやすい、という意味でしょうか? >それはそれで否定しませんが、それで問題は解決しない、ということもポインタ完全制覇は これについては、著書で理解しております。 char* p,p2; とするとp2は char p2;となってしまうと理解させていただいています。 あと、char *p;としてprintf("%p",p);としたとき参照されてない というエラーがでましたが、まぁ、ただ、もう理解してますので、蛇足です。 あと、他の言語では、配列とポインタは、”ほぼ別格”というのは、新たな知識として ありがとうございます。 とりあえず、今は構造体のリストを理解するために、脳をこねくりまわしている状態です。 しっかし、まぁ、I study hard and more hard to purogramming-Cってなことですな~ ついでの蛇足で int dt = (a = 20,b=10);とすると dt=10となるなんていう、たぶん一生必要ない知識ですが、まぁ、なんというか・・・ 色々あるな~・・・と思う、日々。 年々歳々花相似たり、年々歳々人同じからず
[この投稿を含むスレッドを表示] [この投稿を削除]
[787] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

# あれこれ言ってみるテスト jmp_buf の場合は「set/longjmp で使うハンドル」と考えれば & なしにも違和感なし なまじ buf という文字列が見えてしまっているのが名前付けに失敗した例と思う memset の場合は要求されるのが void* だから &array のほうが適切な場合多し strcpy の場合は要求されるのが char* だから array と書かなきゃいけない scanf+%s の場合も同様 GCC はフォーマット文字列がリテラルな場合に警告してくれます。 scanf("%s", &buf); に対して gcc -Wformat hoge.c で piyo.c:4: warning: char format, different type arg (arg 2) みたいに。 C/C++ はエラーメッセージの読み方が難しいのが減点ポイント (馬から落馬) たいていの原因はエラー表示のある行の直前にあったりするし。 template 多用時は俺でもエラー判別がめんどくさかったりするですね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[789] Re:難解不落のポインタ すべてはプログラマにゆだねられ プログラマはポインタに揺らされる
投稿者:(ぱ)
2007/02/20 02:13:25

>char* p,p2; >とするとp2は >char p2;となってしまうと理解させていただいています。 この問題だけであれば、一度に複数の変数を宣言するなゴルアで回避できるのですが、 Cではたとえば配列なども型の一部ですから、どっちみち 型 変数名; の形では変数宣言を解読できないんですね。CESさんが出した問題がそうであるように。
[この投稿を含むスレッドを表示] [この投稿を削除]
[790] Re:ポインタ完全制覇
投稿者:(ぱ)
2007/02/20 02:13:25

# テストに反応してみるテスト >jmp_buf の場合は「set/longjmp で使うハンドル」と考えれば & なしにも違和感なし ハンドルといえば、 handle = CreateWindow(...); みたいなのだと思うので、戻り値ではなく引数で返すならやっぱり&が付くのではないかと。 >memset の場合は要求されるのが void* だから &array のほうが適切な場合多し >strcpy の場合は要求されるのが char* だから array と書かなきゃいけない >scanf+%s の場合も同様 memset()の場合でも、&を付けない人のほうが多いんじゃないかなあ。 適当にぐぐって見たけど付いてない例が多いようです。 http://www.microsoft.com/japan/msdn/library/default.asp?url=/japan/msdn/library/ja/vclib/html/_CRT_memset.asp http://www.cppreference.com/stdstring/memset.html >C/C++ はエラーメッセージの読み方が難しいのが減点ポイント (馬から落馬) まあ、エラーメッセージの良し悪しはコンパイラによるところもあるとは思いますが、 C言語自体が多様な書き方を許すためにエラーメッセージがわかりにくくなるところは ありますね。
[この投稿を含むスレッドを表示] [この投稿を削除]
[791] Re:ポインタ完全制覇
投稿者:本多
2007/02/20 02:13:25

#テストの(略) >>jmp_buf の場合は「set/longjmp で使うハンドル」と考えれば & なしにも違和感なし >handle = CreateWindow(...); >みたいなのだと思うので、戻り値ではなく引数で返すならやっぱり&が付くのではないかと。 もしsetjmp/longjmpがcreate_jmp()してから使うような形であったら、&なしがきれいですよね。 jmp_buf myjmp = create_jmp(); if ( (ret = setjmp(myjmp)) == 0 ) { ... } else { ... } ~略~ longjmp(myjmp, ret); >memset()の場合でも、&を付けない人のほうが多いんじゃないかなあ。 今まで考えなしに付けてなかったですけど、概念的には付けるべきだったのかしら。 例えば「配列へのポインタ」と「配列の先頭要素へのポインタ」の 表現方法が異なるような処理系において ...では、やっぱりmemset()の使用は推奨されないのかなぁ?
[この投稿を含むスレッドを表示] [この投稿を削除]
[792] Re:ポインタ完全制覇
投稿者:774RR
2007/02/20 02:13:25

>もしsetjmp/longjmpがcreate_jmp()してから使うような形であったら、&なしがきれいですよね。 御意。 > 今まで考えなしに付けてなかったですけど、概念的には付けるべきだったのかしら。 俺なんかはその昔の &array が規定されてなかった頃からCをやってる人ですから 「配列名が先頭要素へのポインタに変換される」仕様が本能レベルで染み付いているので memset 等のポインタが必要な関数が使われてて引数に & が無い場合にはむしろ 「& がないから、これって配列なんだ」と解釈しがちな傾向がありますな。 # よく読んだら、ポインタ変数だったりすると後からびっくり。 概念的には & があるべきなのだと思う。ただ歴史的事情により 配列であることが明確な場合には & を書かないソースのほうが圧倒的多数だと思います。 > 例えば「配列へのポインタ」と「配列の先頭要素へのポインタ」の > 表現方法が異なるような処理系において > ...では、やっぱりmemset()の使用は推奨されないのかなぁ? void* は、内部表現が最大サイズとなるポインタを保持できなければならず、なおかつ、 必要な時には内部表現を失わずに元の型に戻せることが必須とされていますから、 問題ないです(問題あったら大変だ) # テスト略
[この投稿を含むスレッドを表示] [この投稿を削除]