1 :
名無しさん@お腹いっぱい。 :
2000/10/09(月) 01:16 ポインタでつまずいている私はダメダメでしょうか?
2 :
名無しさんダーバード :2000/10/09(月) 01:35
ポインターとは、つまり、ポイントするものです。
3 :
1 :2000/10/09(月) 01:36
2> つまり「示す」という意味でしょうか?
つまり、こんなことでそもそもスレッドたてずに ギコ猫のプログラミング相談室に聞けと言うことです
4age
大抵の人は一度はつまづく所。
7 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 02:16
メモリは1バイトごとにアドレスがついています。 そのアドレス情報をもつ変数がポインタです。
変数ってのはいろんな目的の箱で、ポインタってのは住所が置かれた箱なんだよな。 住所は他の箱の場所を指していたり、1つの箱の場所を覚えておいて、 そこから何番目までを記録に使ったりする。 言うのは簡単だけど概念的に理解できないと面倒なだよなあー。
9 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 02:55
コマンドライン引数で遊んでみたらすぐ解かると思うけど。 初心者の内は理解しようと必死になるより馴れることに重点置いた方が良いんじゃない?
10 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 03:20
つまずかなかった僕が質問に答えたげるよさあ書け
は? 一体、ポインタのどこが難しいんだ?(汗
12 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 03:28
多次元配列へのポインタは最初脳がパンクしそうになったが
13 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 04:52
俺も理屈はべつに難しくないと思う。 ただあのCの宣言の文法は腐ってると思う。 ちょっと半年くらい別の言語やってたりするとすぐわかんなくなる。
Javaだけやってると、もうなにがなんだか・・・
VC++のクイックウォッチで遊べばすぐに理解できるんじゃないの。
16 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 07:49
ポインタ変数が、別のポインタ変数を示していて、 そのポインタ変数がまた別のポインタ変数を… とかなってると、頭パンクしそうになるかもですねぇ。 自分、高校の授業で、8085のワンボードマイコンで ハンドアセンブルとかやってて良かったですわ。 アレがあったから、コンピュータってどうやって動いてるのか わかったような気がする。 そういう低レベルなところを理解できてれば、 ポインタうんぬんがわかんない、なんて事にはならないですな。
パンクしそうになったら図をかけ 終了
そもそもポインタがわからないと言うやつって ポインタの何がわかってないんだかもわかってないようだ‥ 人にきくなら、できるだけ具体的に せめて簡単な事例を用意してきくように。
19 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 13:56
おれもポインタの概念自体よりも表記法がわかりにくいんだと思う。 しかしどんな書き方だったらわかりやすいのかな?
20 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 14:03
[ポインタ] これだ!
21 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 14:08
Cを高級言語だと思う人は手をageて~ うちは思わない。
22 :
優しい名無しさん :2000/10/09(月) 14:10
int *a; じゃなくて int* a; ならわかりやすくないかい?
23 :
厨房@C/C++暦○年 :2000/10/09(月) 14:34
excel で例えるなら、「123」 等の数字が直接入ってるセルは変数で、 「A2」の様に、他のセルを参照しているセルはポインタ変数。 …では駄目ですか? あくまで「例え」なんで間違ってる部分もあるとおもいますが。
24 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 14:39
そうやって覚えると、 int* a,b; と書いちゃう人が増えるんだな。期待しているのは int *a, *b; なのに。
25 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 14:52
それ Stroustrup 先生に言ってみ
26 :
優しい名無しさん :2000/10/09(月) 14:54
今はポインターわかるが、以前わかってなかったこと。 頭の中で変数の実体とポインターがごっちゃになってる。 で気分次第で意味解釈が変わってきてた。 あと、ポインター宣言したら実体も同時にできていると思ってたり…。 だけど、がんぱってWinのアプリ一本作ってみたら、 なぜこれがわからなかったのかがわからなくなってた。 結局、文法書で終わってるとこがダメなんだよ。 文法はコンパイラと対話しながら学びなさい。
27 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 15:00
アセンブラの入門書とか見るのもいいかも。
28 :
優しい名無しさん :2000/10/09(月) 15:05
>27さん そうですね。 いっぺん、Z80でもCASLでもいいから 文字列テーブルでも作ってプログラムの中で参照してみるといいかも。
29 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 18:06
何故ポインタなんかがあるか・・・(悩
30 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 18:17
"call by name" が破綻したからだろ?
32 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 18:37
高水準アセンブラだからだろ。 値呼び出しが破綻しただけなら参照呼出しをちゃんとサポートすればよかったんだよ。
33 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 18:49
>24 char* const p; はやはり char *const p; とかくのか?
34 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 20:20
char * const p; がふつーだと思う。
35 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 20:48
101匹わんちゃんもポインター地獄
>33 意味的には char (* (const p)); なんだから、char と * をくっつける強い必然性はない。 まぁ、const と p をくっつけるわけにはいかないから char *const p; または 34 さんのように char * const p; だろうな。 この場合も、 char a; char*const p = &a, q; とした場合など q の型が直感的には認識しづらい。
38 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 21:57
char const*p;
char const * const p; は?
40 :
名無しさん@お腹いっぱい。 :2000/10/09(月) 22:43
Stroustrup先生なら const char* const p; とおっしゃりたいところでしょう(笑)。 つーか、やっぱこの*の位置キライなんだが。 C++がデフォになると(もうほとんどなってるが) こっちが標準になっちゃうからなあ。 うー、どうしよう。うにゃにゃにゃにゃ。
41 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 01:32
>29,30,31 メモリを動的に確保・廃棄したいから、であってますか?
42 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 01:37
メモリマップドIOを直接操作したいから、であってますか?
43 :
>38 :2000/10/10(火) 02:49
とちゅうchar const* p;とchar* const p;の違いが分かってないものが約一名。
44 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 02:54
>40 char *p, *q;みたいに一行に何個も書くこと自体廃れてきた ような気がする。それでいいと思う。
45 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 09:40
debugコマンドでもVCでもいいけど機械語デバッガで1ステップづつ追いかけてみれば?。 まーCの演算子解決順ってなんでもう少しわかり安くしてくれなかったんだろ。 いまだに*p++とか書くとき一瞬迷いが走るのは修行が足りない?
46 :
>Stroustrup先生 :2000/10/10(火) 10:31
こーゆーのはどうするんですか? char const * const * const * const p;
47 :
>46 :2000/10/10(火) 11:02
ポインタポインタ以上を使うなら、typedefせよ
48 :
46 :2000/10/10(火) 11:15
const 込みの typedef も作っとくの? やなこった。
49 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 12:20
>46 char const* const* const* const p; だろな。 >48 これは同感。ポインタをtypedefすると何か使いにくい。
50 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 12:43
const char *const *const *const p; がいいな。
51 :
どーでもいーことだが :2000/10/10(火) 15:34
const char* const* const* const p; でないの?
52 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 17:32
char ********************************************************p;
53 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 17:37
void* p; あとはキャストして使ってくれ。
54 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 17:51
わかった。 char ********************************************************pp = (char ********************************************************) p;
55 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 17:52
printf("%c\n", ********************************************************pp);
56 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 18:03
int ***(*func(int a, char (*func2)(void *)))(int x); 世界人類がこんな関数を作りませんように。
57 :
名無しさん@LV2 :2000/10/10(火) 20:29
ans = *p/*q; を始めて書いたときはめっさうけた^^
58 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 20:32
ちょっとは地獄らしくなってきたけどまだ足りないな。 ホンモノの地獄をみせてくれっ!!
59 :
名無しさん@お腹いっぱい。 :2000/10/10(火) 22:16
* * * * * * * *** * * * * * * * よく見ると雪印っぽくて地獄。
60 :
名無しさん@お腹いっぱい。 :2000/10/11(水) 08:54
ども、教えて君です。 多次元配列のポインタ教えて。
61 :
名無しさん@お腹いっぱい。 :2000/10/11(水) 08:58
>60 54にすでに40次元ぐらいのがあるだろ。
62 :
>60 :2000/10/11(水) 09:08
ややこしければ とりあえず配列をtypedef してからポインタにすれば?
63 :
62 :2000/10/11(水) 09:09
ごめん。変な事言った。修正 配列を構造体に入れてからtypedefしてポインタにすれば判りやすいよ
char (*p)[2][2][2][2][2][2][2][2][2][2][2][2][2][2] ;
56ほどじゃないけど、signal()のプロトタイプも初心者殺しだよね。 void (*signal(int, void (*)(int)))(int); そんでもって、Cプログラマのまあ多分6割以上はこれを読めないというのが、 日本の悲しい現状。
うはあ…なつかしい。図書室で見た時はなんかの暗号化と思ったわい。
67 :
>65 :2000/10/11(水) 17:50
やっぱそれはCの文法が悪いと思うんだけど、、、 PASCALとかではどうかくの?
68 :
>67 :2000/10/11(水) 19:22
pascalではポインタは ^ です char *p;は var p:^Byte; です。 じゃ同じじゃないかと思われるでしょうが、参照渡しが使えるのと absoluteで別名参照が出来るのと、そもそもクラスが参照なので C程ポインタにお世話になるチャンスは少ないですね
69 :
>67 :2000/10/11(水) 20:00
あと、配列とポインタが明確に区別されてるのと
70 :
ぴか虫 :2000/10/12(木) 00:42
71 :
名無しさん@お腹いっぱい。 :2000/10/12(木) 15:51
昔,読みづらいCのソースコンテストって野があったのを思い出した.
Pascalではtype使わないと複雑なのは書けないと思ったが‥
>71 確か、 main() { goto togo; gototo: goto gogo; togo: goto gototo; gogo: } こんな感じのがあったような。
>73 用件を聞こうか。
こういうのって四則計算覚えたてのガキにただ長いだけの暗算やらしてるのと同じだね。 傍観してるのは面白いけど。
>74 2chがコンタクトポイントだったのか
77 :
名無しさん@お腹いっぱい。 :2000/10/22(日) 04:56
int(*(*(*(*(*func(int(*)(int(*)(int(*)(int(*)(int(*)(int)))))))(int))(int))(int))(int))(int);
78 :
名無しさん@お腹いっぱい。 :2000/10/22(日) 06:20
>>68 それは Pascal というか Delphi の話だね。
79 :
名無しさん@お腹いっぱい。 :2000/10/22(日) 06:23
#include <stdio.h> main() { int = 1; loop: printf("%d\n", i); i = i + 1; if (i <= 10) goto loop; return 0; } うあああ。昔のBASICみたいだ。
80 :
名無しさん@お腹いっぱい。 :2000/10/22(日) 06:27
void func(int ******************************************x) { printf("%d\n", ******************************************x); }
81 :
名無しさん@お腹いっぱい。 :2000/10/22(日) 12:01
>80 const が付いてないので減点。
82 :
名無しさん@お腹いっぱい。 :2000/10/23(月) 16:08
(***********************************&printf)("hello\n");
83 :
名無しさん@お腹いっぱい。 :2000/10/23(月) 18:13
varargと可変引数な関数でスタックを壊してるに100000ペリカ
84 :
名無しさん@お腹いっぱい。 :2000/10/24(火) 02:57
ポインタ地獄は構造体で解決。
*じゃなくて@とかにしたほうがなんかわかりやすいとおもう。
やっぱり、
>>65 の
void (*signal(int, void (*)(int)))(int);
とかは、
typedef void TVIFunc(int);
typedef TVIFunc *TVIFuncPtr;
TVIFuncPrt signal(int, TVIFuncPtr);
とかみたいにtypedefしてくれるとわかりやすいと思う。
88 :
学生 :2000/10/26(木) 01:38
>>65 わからんです・・・。
一番最後の(int)
これが付くとどうなるんです?
ごめんちゃい、ごめんちゃい。
>75 んで、おまえもできないんだろ(藁
>>88 一番最後の(int)っていうのは、
void (* ~ )(int)
こうみるのね。
つまり、signalという関数の戻り値が
「「引数int 戻り値void の関数」へのポインタ」というわけです。
91 :
学生 :2000/10/30(月) 09:53
サンクスコ>90 でもせっかく気付いてもらったのに・・・ 分からんです。 今はもう一度みっちり勉強してまふ。
92 :
名無しさん@お腹いっぱい。 :2000/10/31(火) 06:03
これは解るんです void ( *signal )( int ) でこれが void ( *signal(int, void(*)(int)) )( int ) こうなると解りません signalのあとから始まるかっこはどういう意味なんですか? すみませんだれか教えて下さい _(._.)_ _(._.)_ _(._.)_ _(._.)_ _(._.)_ _(._.)_
signalは、関数へのポインタ変数。 その関数は(int, void(*)(int))型の引数をとる。 引数内のvoid(*)(int)は、関数へのポインタ型。 この引数内の関数はintの引数をひとつとり、voidを返す。 その関数の返り値は関数へのポインタ型。 この関数はintの引数をひとつとり、voidを返す。
>>92 signalは、引数にintとvoid(*)(int)を持ち、void ( * )( int ) の関数ポインタを返す関数だよ。
わかんなかったら素直にtypedefしろよ。
typedef void ( *tproc)( int );
tproc signal(int, tproc);
これで済むだろが。だぁほ!
>>92 そのsignalのあとから始まるかっこは関数を意味します。
名前の前につく*はポインタ、名前の後につく()は関数を意味するんだ。
このかっこの中にあるのは関数の引数なんで、さいしょは分けて考える。
*より()の方が結合が強いことに気をつけて。
*hoge()
は、*と()の両方がくっついてるけども
()の方が結合が強いので、hogeは関数。
{{hogeは関数}ポインタを返す}
てな感じで考える。一方
(*fuga)()
は、*と名前をかっこでくくってるから*の方を先に評価して
{{fugaはポインタ}関数への}
てな感じで考える。
で、問題の
void(*signal(int,void(*)(int)))(int)
なのだけども、
(*signal())()
として考えて、名前に近いほう(内側)から考えよう。
{signalは関数}ポインタを返す}そのポインタは関数への}
こんなんでわかってもらえたかな?
もちろん、自分で書くときはtypedefを使ったほうがいいね。
ちなみに、93は間違い。おしいけど‥
96 :
93 :2000/10/31(火) 16:41
仰せの通りでございまする・・
97 :
92 :2000/10/31(火) 17:15
理解できました 皆様解りやすい説明ありがとうございました
その関数signalへのポインタpsignalを書いてみろ
そのポインタの配列もな(藁
演算子の結合順序と方向の表をちゃんと見ましょう。
101 :
92 :2000/11/01(水) 01:59
typedef void ( *tproc)( int ); typedef tproc signal(int, tproc); signal *psignal; signal *psignal[5];
拍手!
103 :
名無しさん@お腹いっぱい。 :2000/11/13(月) 00:15
ageとこう
ようするにポインタってアドレスだろ? 膨大なデータとか、引き渡すの面倒だから住所だけ教えて。 そのアドレスデータを格納するのがポインタで、その参照先の データを書き換えたり、その値を代入したりできる。 つまり馬鹿でかいデータAがあるとすると、 A = B = Cとか3つ作るんじゃなくて、 A、Aのアドレスを入れたポインタB、Aのアドレスを入れたポインタC、って 形にできて、メモリを節約できる。それだけだろ。基本は。 ポインタのポインタとかが初心者を混乱させてるけど、ただの住所録って思ってれば 問題ないよ。 データを入れた書類と、その書類の保管場所を書いたメモみたいなもの。 そのメモもどこかに保管した場合、その場所を記入してるのがポインタのポインタ。 こんな風に実生活でイメージすると混乱しないはず。 仮に何十個ポインタが重なっても、参照を繰り返してるだから。
単にCの構造欠陥とも言う。 関数と混同しやすい書式指定、ってのも混乱を生んだ一因だし。 けど、それ以前に。 ムダにわかりにくくしてるのは、教科書の説明なんだよな。 何やってんだか。 本来は、どっちかっつーと簡単な概念なのにな。ポインタなんて。
アレだ、アセンブラのインデックスアドレッシングをやれば 一発で理解できると思うんだが、どうか。 オートインクリメントがある今のCPUなら、 *p = 1; p ++; なんてのがどうなるかも判るしな。
107 :
ポインタ :2001/01/19(金) 07:42
要するにメモリの指定ですか?
108 :
デフォルトの名無しさん :2001/01/19(金) 10:23
アセンブラをやりなさい。 簡単に理解できます。 例題として時々ポインタのポインタとかわけ分からないこと 教えるからこういうことが起きるんだよ。
109 :
デフォルトの名無しさん :2001/01/19(金) 15:37
すんごく情けない事がわからないんです。助けて下さい。 int i の中に入っている数値を文字列として扱うにはどうすればいいんですか?
110 :
名無しでGO! :2001/01/19(金) 15:41
sprintf(hoge,"%d",i);
> int i > の中に入っている数値を文字列として扱うにはどうすればいいんですか? すんごく情けない事がわからないんです。助けて下さい。 これってポインタと何か関係あるんですか?
(char*)i;
× (char*)i; ○ ((char*)&i); int*iと勘違いしておったぞな‥
114 :
109 :2001/01/19(金) 16:53
>>110 例えば、
int a = 1;
char* b;
sprintf(b,"%.2d",a);
でばっちり、「01」という文字列を扱えるようになりました!!
ありがとうございます。
115 :
デフォルトの名無しさん :2001/01/19(金) 16:58
>>114 あ゛ーーーーーっ、それはちがーーーーう
せめて
int a = 1;
char b[10];
sprintf(b,"%.2d",a);
か
int a = 1;
char c[10];
char* b = c;
sprintf(b,"%.2d",a);
としてくれ
いまは*たまたま*動いているにすぎない
116 :
109 :2001/01/19(金) 17:14
せっかく使えたと思ったのにたまたまなんですか… これだから、ポインタってやつは… でもなんとなくわかりましたよ。領域を確保してないから、ですね?
ちゃんとポインタの話になるようにオチがついてる。。 このスレでやるってことは狙ってんだよな。。<109
>>117 マジで、Cは初心者なので、文字列に四苦八苦してるんです。
文字列はポインタだから…ということでここに書き込んでみたりしたわけです。
勉強になります。
119 :
777 :2001/01/19(金) 18:17
プログラミング初心者ですが、基本的な質問をさせていただきます。 間違ってわり算の時に「0で割る」ということがありますが、そのとき にエラー処理が行われると思うのですが、いったいCPUでは何が 起こっているのでしょうか?ポインタとかも関係あるのでしょうか? おおまかなことでもいいので、わかる方いましたらお願いします。
120 :
マジレスさん :2001/01/19(金) 18:45
>>119 初心者がそんな疑問いきなり思いつくとは思えない。
また例によって宿題レポートマル投げ君かよ。
>>119 それじゃあんまりなので
「ポインタは関係ない」
とだけ答えといてやろうΨ(`∀´)Ψ
CPU君は DIV 0 なんてアホな命令が読み込まれたら例外を発生します。 (初期ペンタでは発生しない事もあり。)
俺は趣味とはいえ長く C をいじってきたけど最近になってやっとポインタの ポインタではてなー?ということがなくなった。俺ってバカ?
>>124 馬鹿だけど、わりと普通なので気にしなくて良い。
126 :
名無しさん@お腹いっぱい。 :2001/01/20(土) 02:28
別スレで void* の使い方を教えてもらった者ですが、これは Cの malloc()とかで 使用例があるので大体わかった(つもり)です。 で、void** っていうのがどーにもイメージがつかめません。どういう利用法が あるのか、実例とか教えて欲しいのですが。
127 :
デフォルトの名無しさん :2001/01/20(土) 02:44
>>126 (void **)などは主に関数の引数に与えるポインタの参照位置を変更したい時などに使う。
実は、キャストすれば型はなんだっていい。(サイズさえ同じなら)
void intinc(void **p) {
((int *)*p)++;
もしくは
((int *)*p) = ((int *)*p) + 1;
}
void test() {
int *p;
intinc(&p); // p += sizeof(int)と同じ
}
128 :
デフォルトの名無しさん :2001/01/20(土) 02:47
test() { char *p; でした
>>127 ありがとうございます。よく読んでこれから (^^; 理解してみます・・
130 :
777 :2001/01/20(土) 15:56
>>123 ありがとうございました。
CPUは自分が処理出来ないときには、
「例外」を出すと考えていいんですね。
123も微妙にずれた答えを教えるなんてニクイね ま、揚げ足とりだけど
ボインたん地獄なら味わいたいね。 俺の彼女、貧乳だし。
133 :
デフォルトの名無しさん :2001/01/21(日) 20:01
>>132 お馬鹿。オヤジギャク。30後半と見た。
一緒にするなよ
135 :
デフォルトの名無しさん :2001/01/22(月) 01:22
半導体線形メモリーのポインタでこんなに苦しむのに、 量子メモリーの時代になったら、いったいどうなるんだろう?
136 :
デフォルトの名無しさん :2001/01/22(月) 01:40
>量子メモリーの時代 フジテレビでやってたけどどうなるの? 「一般人には想像もつかない」 みたいなこといって教えてくれなかった。
137 :
デフォルトの名無しさん :2001/01/22(月) 04:41
メモリーが演算能力を持って自分で計算するんだよ。 人の脳をシュミレートすることも可能。超並列量子コンピュータという。
ポインタで位置を特定すると、状態がわかんなくなったら笑えるね。
量子的プログラミングの不確定性原理とかね
140 :
デフォルトの名無しさん :2001/01/22(月) 20:43
C 言語やってると実体に触れなくても、ポインタや、ポインタのポインタを、触れるだけで、満足になってくるなあ。
>>140 ポインタの先は実体を指しているかどうかは気をつけていた方がいい
穴の空いたバケツに水を入れると自分の足をぬらす事になる
142 :
デフォルトの名無しさん :2001/01/23(火) 09:55
143 :
名無しさんi486 :2001/01/23(火) 12:16
今更でしょうが
>>101 は
------------------
i>typedef void ( *tproc)( int );
ii>typedef tproc signal(int, tproc);
まず(i)で『"int型の引数を持つtproc型の関数へのポインタ"
をvoid型と同義であると宣言する』
これでtprocという形が(*void)(int)という形と同義である
と宣言されるのでしょうか?
次に(ii)で『signalはintと(*void)(int)の二つを引数に持つ
(*void)(int)という型の関数へのポインタと同義である』
ということで、関数signalと同じ構造を持つわけですね?
iii>signal *psignal;
iv>signal *psignal[5];
それでやっとsignal型のポインタが宣言できる。
という解釈で良いんでしょうか? どうかお教えください(__)
144 :
名無しでGO! :2001/01/23(火) 15:08
ちなみにii)はtypedef tproc (*signal)(int tproc)ね。 i) tproc=void (*)(int) ii) signal=tproc (*)(int,tproc)
145 :
65 :2001/01/23(火) 15:16
「signal」を型名に使うから混乱するんじゃないかな。 っていうか、signal.h をインクルードしてたら、名前が衝突しない?
146 :
デフォルトの名無しさん :2001/01/25(木) 02:26
なんで、<int型の大きさ3の配列>へのポインタ の宣言は、 int (*a)[3] なんですか? int[3]* a とか int[3] *a とかなら理解できそうなんですが… なんで(*a)なんですか?????
[3]*a とかだと乗算と見分けがつかんと思う。 []が最初に来るのも困るし、()を付けないと *(a[3]) だかなんだかわからないし。
148 :
名無しさんi486 :2001/01/25(木) 09:59
>144,145さん ありがとうございます。何となくわかったような気分にな れました(^^;) ポインタって極めようとおもうと難しいです ねぇ。 >146さん *よりも[]のほうが演算子の優先度が高いからじゃないか な? int *a[3] だと意味変わっちゃうし・・・ そっかぁint [3]* a とか int [3] *a なんて書き方もで きるのですか・・・勉強になりました
149 :
SAGE :2001/01/25(木) 17:54
(*a) … a is a pointer [3] … to an array(size 3) int … of int 「 a は、[int型の、大きさ3の配列] へのポインタ 」 って感じに、優先順位の強いものから順に解釈していくとわかりやすいらしい。
intの3個配列へのポインタなa。 日本語だと外側(優先順位の低いほう)からね。
151 :
デフォルトの名無しさん :2001/01/26(金) 16:35
void *a;をcharの配列のように扱うにはどうすれば良いのでしょう? 例えばchar *c;は c[1] = '\0';できますが (char *)a[1] = '\0';とやるとエラーになってしまいます。 ((char *)a)[1] = '\0';とやるとエラーになりませんが、 C的に見て正しい文法なのでしょうか? 識者の方、よろしくお願いします
(char *)a[1] = '\0'; じゃなくて (char *)&a[1] = '\0'; ならいいのかなぁ。。 どっちにしろ void *a; char *b; b = (char *)a; ってやるな。おれなら。
153 :
デフォルトの名無しさん :2001/01/26(金) 19:07
>>151 >void *a;
>a[1];
の部分
void *
の配列ってなんだ?
サイズは?
>>153 > void *
> の配列ってなんだ?
void *a;をcharの配列のように扱いたいのです。
>>152 さんのように
char *c = (char *)a;として
c[1] = '\0';としてもいいんですが余計な一時変数は使いたくないのです。
一応、((char *)a)[1] = '\0';としたらうまく動いてますが
これが*たまたま*うまく動いているようにみえるのか
それともCの文法上正しいかどうか知りたいのです。
よろしくお願いします。
155 :
152 :2001/01/26(金) 19:38
>それともCの文法上正しいかどうか知りたいのです。 ((char *)a)[1]は正しいよ。 voidポインタaをchar型ポインタにキャストする。 そこからoffsetが1の領域に代入するって意味。 (char *)a[1] = '\0'; だと void型配列のポインタaを基点としてoffsetが1の変数をcharポインタ型にキャストする っていうわけの分からんことをやってる。 だいたいa[3]とかはいいのかなぁ。。 voidポインタの場合、基点しか使えない気がする。 どっちにしろおれはこんな使い方しないからこれ以上言うこともないし 調べようという興味もないな。。。 >余計な一時変数は使いたくないのです。 そのためにキャストだらけのコードになったら、普通の人は読みたくないと思うよ。
>>155 > ((char *)a)[1]は正しいよ。
ありがとうございます。
>だいたいa[3]とかはいいのかなぁ。。
駄目でした。void *a[];ならば正当なのでしょうけど...
>>余計な一時変数は使いたくないのです。
>そのためにキャストだらけのコードになったら、普通の人は読みたくないと思うよ。
そうですね。void *も本来ならあまり多用すべきでないんですけど、
局所的に封じこめてしまって、そこは汚くてもいいやと開き直ってます。
どうも、ありがとうございました。
157 :
デフォルトの名無しさん :2001/01/27(土) 13:31
unsigned char* MemorySet(int nCapa, char nWor); int main( void ) { int i=0; unsigned char yyy[10] = {0,}; unsigned char* st = MemorySet( 10, '\0' ); unsigned char* hBuff = MemorySet( 10, '\0' ); unsigned char* pch = MemorySet( 10, '\0' ); yyy[0] = '\x03'; yyy[1] = '小文字のオ'; pch[0] = yyy[0]; pch[1] = yyy[1]; for( i=0; i<2; i++ ){ sprintf( (char*)hBuff, "%X", (char*)pch[i] ); //st="2B5" st[0]='3' st[1]='B5'// } return 0; } unsigned char* MemorySet(int nCapa, char nWor){ unsigned char* TempBuf = (unsigned char*)malloc(nCapa); memset(TempBuf, nWor, nCapa); return(TempBuf); } 最後、コメントに書いてあるようにしたいんだけど、スマートなやり方教えて
158 :
デフォルトの名無しさん :2001/01/27(土) 13:33
字下げが、全部消えてる・・・すみません
とりあえず「"」と「'」の区別がついてないね。
160 :
デフォルトの名無しさん :2001/01/27(土) 13:51
その辺も、教えてください、どこがまずいか
まずやりたいことがわからん。 //st="2B5" st[0]='3' st[1]='B5'// って書いてるけど、st[0] = '2'の間違い? あと、stは今のままではすべて'\0'で初期化されてるけど、 sprintf(st,...)の間違い?
st[0] == '2' st[1] == 'B' st[2] == '5' st[3] == '\0' にしたいんだよね? それと yyy[0] = '\x03'; の'\x03'ってなに?
163 :
デフォルトの名無しさん :2001/01/27(土) 15:04
/st="3B5" st[0]='3' st[1]='B5'//の間違いでした 説明下手ですまんです。 yyy[0] = '\x03'; yyy[1] = '小文字のオ'; という、文字のアスキーコードの16進値がほしいんです。 それぞれのアスキーコードが '\x03'…3 '小文字のオ'…B5 とsprintfの行で変換されて、変換するたびに hBuffは更新されるんで、それを別のところに保存する 例えば unsigned char last[10] = {0,}; 見たいな配列に last[0]=3,last[1]=B5 というようにしたいんです。 お願いします。
164 :
偽名無しさん :2001/01/27(土) 15:29
要するにやりたいのはこういうことか?? 理解するのに時間かかったぞ。 main(){ char buf[10][10]; char ch[2]; ch[0]='0x03'; ch[1]='0xb5'; for(int i=0;i<2;i+) sprintf(buf[i],"%X",(int)ch[i]); }
165 :
偽名無しさん :2001/01/27(土) 15:30
ch[0]='\x03'; ch[1]='\xb5'; じゃん。打ち間違い。
>>164 ちがうような気がする。こいつ(>163)何やりたいのかさっぱりわからん。。
だれか解読してくれ!
#include <stdio.h> int main(void) { int i; unsigned char yyy[10]; unsigned char hBuff[10]; yyy[0] = '\x03'; yyy[1] = '\x0B'; yyy[2] = '\x05'; yyy[3] = '\0'; printf("%d, %d, %d\n", yyy[0], yyy[1], yyy[2]); hBuff[0] = yyy[0]; hBuff[1] = (yyy[1] << 4) + yyy[2]; printf("%X, %X\n", hBuff[0], hBuff[1]); return 0; } これ?ってワケないよね。。
168 :
デフォルトの名無しさん :2001/01/27(土) 16:39
167さん、これ hBuff[1] = (yyy[1] << 4) + yyy[2]; これでやっていることをやりたいのです。 でも sprintf( (char*)yyy, "%X", (char*)pch[i] ); で変換したとき 167さんの yyy[1] = '\x0B'; yyy[2] = '\x05'; にあたる部分が yyy[0] = 'B' yyy[1] = '5' になってるんです。 どうしたらいいでしょうか?
#include <stdio.h> int main(void) { int i; unsigned char yyy[10]; yyy[0] = '3'; yyy[1] = 'B'; yyy[2] = '5'; yyy[3] = '\0'; i = strtol(yyy, '\0', 16); printf("%X, %X, %X\n", yyy[0], yyy[1], yyy[2]); printf("%X", i); return 0; } もしかしてお望みのものはこれ?
みんなやさしいよな、、、 俺だったら C言語の前に日本語やりなおして来いムキー!! とかいってきれちゃうょ、、、
けっきょく質問者は礼も言わずに去っていった。。。ひゅるりぃ~
どうもありがとうございました 167さんの方法でいくことにしました。
173 :
デフォルトの名無しさん :2001/02/27(火) 05:44
174 :
デフォルトの名無しさん :2001/02/27(火) 09:47
つーかポインタ専門の本なんて読む必要あんのか? アセンブリをちょっと勉強したら、いやそこまでしなくても デバッガでプログラムの流れを追ったらわかるだろ、普通。
175 :
デフォルトの名無しさん :2001/02/27(火) 11:41
176 :
デフォルトの名無しさん :2001/02/28(水) 00:08
>>173 ちょっと目次みてみたけど
>1・3 配列について
>1・3・5 ポインタ演算なんか使うのはやめてしまおう
ってとこにハゲシク同意
177 :
デフォルトの名無しさん :2001/02/28(水) 01:17
int (*hoge)(int(*)()())(int (*)()); これは何でしょう?
178 :
デフォルトの名無しさん :2001/02/28(水) 01:55
179 :
177 :2001/02/28(水) 02:51
int (*(*hoge)(int (*(*)())()))(int (*)()); あぁっ、こう書くのが正解か。わけわかんねぇゴルァ!!(逆ギレ
180 :
1 :2001/02/28(水) 05:05
自分がポインタの理解が曖昧だった頃の話だけど、よく分からない型を 片っ端からsizeofで大きさ調べるのが、結構ポインタ理解の助けになったナァ。 ポインタ配列のポインタとか、多次元配列のポインタ配列へのポインタとか 訳ワカメにナリゲなやつも、どんな型のポインタだろうがポインタ自体はアドレス値が 入った[同サイズの変数]ってのが分かれば、理解しやすいんでは。 とか昔をふりかえってミタリ。
182 :
デフォルトの名無しさん :2001/02/28(水) 07:35
アセンブラを習得ののちOOPを習得すれば怖いものなしです。 もはや私に不可能はない。
同じサイズとは限らないがな。
184 :
デフォルトの名無しさん :2001/02/28(水) 17:13
>>182 アセンブラは習得したが、OOPはいまだ習得できん
厨房なのはわかってるが、コーディング前に図を書いたりせにゃならん
のがしょうにあわない。
箇条書きで良いじゃんかよぉ~
>>184 箇条書きですむような程度のものなら箇条書きですました方がじつは楽。
その程度ですまないようなもののために
オブジェクト指向は考え出されたようなもの。
186 :
デフォルトの名無しさん :2001/02/28(水) 21:50
>>184 突き詰めると図を書いたほうがいいんだけど、
図が性に合わないのであれば、
OOが軌道に乗るまでヘッダファイルを設計仕様にしたほうがいいよ。
つまりクラス定義が仕様書件設計図面。
構造化設計あがりの人は眉をひそめるかもしれないけれど、
オブジェクト指向というのはインターフェイスが非常に重要だから、
これでも大きな問題は出ないんだよ。
でもそのうち美しいインターフェイスを構築できないことが
度々発生して、なにかいい解決方法が無いかと探すことになるでしょう。
そのときになって初めてUMLやOMTで図を書くことの素晴らしさに気づくと思います。
187 :
デフォルトの名無しさん :2001/03/02(金) 17:27
地獄じゃないんだけど。 今月から行くようになった職場、面接の時に「ポインタを理解できないと かなり大変ですよ」と脅すから、4~5段階なんて当然なんだろうなあと 思ってたら、1段階しか使ってねーの。爆笑。 しかも使わないでいいようなところで無理やり使ってるソースが大半。 面接官もよくわかってないというオチだったのかなぁ
>>187 そうやって舐めてる奴が領域確保せずにメモリにアクセスしたりして
再現頻度の低いバグを起こす。自重せいよ。
ポインタは段数じゃねえ ポインタをメンバとしてもったオブジェクトをコピーするとき、 浅いコピーなのか深いコピーなのかとか、 ポインタを返す関数をコールしたときにだれが解放するかとか、 ちゃんとポインタを理解してないと気付かずに 変なコーディングしちゃうのが一番怖いんだ。
190 :
デフォルトの名無しさん :2001/03/02(金) 18:09
186ってさり気ないけど重要なことを書いてくれてる。 186マンセー!
ポインタがあるから関数テーブルも作れるし、便利じゃない、やっぱ?
>>187 > 4~5段階なんて当然なんだろうなあ
普通、1段か2段
それ以上の場合はtypedefで抽象化する
ポインタで難しいのはオブジェクトの管理
数箇所から参照されていたり、
循環参照しているオブジェクトとかの解体が厄介
193 :
デフォルトの名無しさん :2001/03/02(金) 21:30
>>187 ってゆーか
4~5段使うなんて、愚かすぎでは?
スクナクトモ ソンナソースニハ ゼッタイ サワリタク ナイ
194 :
デフォルトの名無しさん :2001/03/02(金) 23:25
あら、ポインタって段数が多いほどすごいってことになってるのね。 世の中にはいろいろな考え方の人がいるのねぇ~。勉強させていただいたわ。 でも、ぜひ一緒にはお仕事させていただきたくないわね。ほほほ。
195 :
デフォルトの名無しさん :2001/03/03(土) 01:54
つーか、変数作りなおして入れなおそうぜ。>ポインタのポインタの・・・ とりあえず見やすいほうが命の為だよ。身のためでもある。
196 :
デフォルトの名無しさん :2001/03/03(土) 01:55
どうでもいいが2段以上は破棄だろ。 もっと根本的なところから考え直せよ
つまんねー話題上げんな アセンブラでも学習してろや>ALL
********************************************************sage
>>188 肝に命じておくが、C12年やっててそんなバカするほど愚かではない
つーかその職場、グローバル変数多すぎてポインタ使ってる意味なさすぎ
200 :
デフォルトの名無しさん :2001/03/07(水) 20:16
グローバル変数とポインタって、、、 関係ねーぞ。アホか?
201 :
デフォルトの名無しさん :2001/03/07(水) 20:22
>>200 ポインター渡ししなくて グローバルで渡してるって言うんでしょ。
まあ、判って馬鹿にしてると思うけど、一応
>>199 が
勘違いすると嫌だから。
とりあえず、グローバル変数は基本的に使うな。
途中で増やすな。
しっかり頭の中で構築してくれ。
すまん、ちょっと鬱になるプログラム思い出しちまって....
>>201 フォローサンクス。
>>200 は多分判ってないと思う。
以前Cを勉強してきたという新卒に説明したとき、同じことをけろっとした
顔で逝ってたし。
どういう風に使うかの話をしているのに、
「グローバル変数とポインタは別物じゃないですかあ」と呆れるような
ことを言ってた。
>>200 は人間として勉強する点がまだまだ多いな。
203 :
デフォルトの名無しさん :2001/05/19(土) 04:18
age
204 :
デフォルトの名無しさん :2001/05/27(日) 15:15
シングルトンと称してグローバル変数を正当化すれば万事OK
205 :
デフォルトの名無しさん :2001/05/27(日) 15:53
Java は、実は全部ポインタ渡しだってほんと? いまだによく分らない。(もう1年使ってるのに) ポインタを使ってた方が、ポインタと実体の区別がつきやすくて コーディングしやすかったYO!
アセンブラの知識がポインタの理解に役立つのは よーく分かったが、はっきし言って今の時代にはそぐわない。 今時プログラミング言語初心者に Basic を勧めるようなもんだ。 とおれは思った。
207 :
デフォルトの名無しさん :2001/05/27(日) 16:39
チンコ *ちんこ マンコ まんこ ちんこ=&まんこ
209 :
デフォルトの名無しさん :2001/05/27(日) 17:11
>>206 >Basic を勧めるようなもんだ
それっていいことなんじゃないの
文脈をよむと悪い例に使ってるようだけど・・・?
207=208
211 :
デフォルトの名無しさん :2001/05/27(日) 17:20
データがメモリー上にどういう風に展開されているのか… そのデータをどのように参照するのか… その辺をイメージできるようになるのは重要かと。 この辺テキトーに済ますと立派なプログラマーにはなれませんよ?
>>209 いや、悪い例のつもりで言ったんだけど(^^;
MSX とかの頃 (若いからよく知らないけど) ならそれがベスト
だったと思うけど、大抵の優れた処理系がフリーで手に入る
今の時代に、Basic から入らせるってのは無理があると思って。
213 :
207 :2001/05/27(日) 17:26
>208 ちんこががまんこのアドレスをさしてるんだよ。
214 :
デフォルトの名無しさん :2001/05/27(日) 17:31
>>204 憂鬱本の解説が白眉だが、
それってスコープの問題が残るなあ。
グローバル変数に「グローバルスコープ」そのものを
(名前どおりに)望むなら健全なんだけど、
実は望んでいるのが「長い寿命」のほうだったりして
スコープは広くなくてもいいのにな、という場合だと、
管理上おかしなことになることがよくあるよね
(別のプログラマに、スコープの広さは望んでいない、と伝わらないとか)、
という話>憂鬱本
Cだと気分的代用として(グローバルな)構造体のメンバに
押しこめることもある。が、釈然としない。
>>209 Basic、よくないと思う。
ポインタのことも考えると、初心者には
rubyとかのほうがまだしもマシじゃないかな。
抽象化されたポインタ(というか参照:C++は除外)を知る重要性と
具体的なアドレスを知る重要性とは、かなり別の概念と思われ。
スコープなら、PascalやSchemeのがいいよ
216 :
209 :2001/05/27(日) 20:35
>>212 >>214 プログラミングのABCとは
A アセンブラ
B ベーシック
C C
という持論があるので言ってみただけ。
BASICでポインタはまず使わないし、そういう概念がほしいと
思った時点で別の言語に目を向けるのもいいかな・・・と。
BASIC信者のたわごとなんで、あんまり気にしないでください
Σ(゚д゚lll)ガーン しまった!このスレはポインタのスレだった!
218 :
デフォルトの名無しさん :2001/05/27(日) 20:38
Javaはおもいっきしポインタ渡しですね。 primitive型が実体渡しなのに、キモイったらありゃしない。 ポインタ地獄はいつでもどこでも健在death!!!
219 :
デフォルトの名無しさん :2001/05/27(日) 20:48
>218 Javaって実体わたしたいときどうすんの? class tinpoko{ void tinko(int Thickness,int Length) { Thickness=10; Length=30; } } void main(){ int fff=200,ggg=3000; tinpoko tnk; tnk.tinko(fff,ggg); } これだとfff,gggはどうなるわけ?
publicが抜けた
221 :
デフォルトの名無しさん :2001/05/27(日) 20:48
>218 >primitive型が実体渡しなのに、キモイったらありゃしない。 実体渡しというか、classじゃないのがキモイが、 Singletonだと考えれば参照渡しと考えてもいいんじゃない?
Javaには、なんで new があるのに delete がないの? つくりっぱなしってすっごい不安じゃない?
ガレージ・コレクション
224 :
デフォルトの名無しさん :2001/05/27(日) 21:00
>219 fff, gggの型を Integer にすると Javaの威力が分かる(藁
225 :
デフォルトの名無しさん :2001/05/27(日) 21:08
>>222 自分でdeleteする方がすっごい不安ですよ。
特に大規模になればなるほど。
>>255 MASMは単体で既に構造化アセンブラだぞ
>227 OK。サンクス。
229 :
225 :2001/05/27(日) 23:28
>>227 最近は構造化だけじゃなくて、オブジェクティブと称している。
きわめて不完全ながらも、それ系の機能をある程度もっている。
>>228 高等なツッコミだねえ。高等すぎて228=225と間違われるぞ。
で、いつまでポインタに悩まされるの?
>>226 コンテナに置いておけば恐れることは無い。
工夫すれば直接deleteする機会はほとんどない。
232 :
デフォルトの名無しさん :2001/05/28(月) 00:14
>>216 てゆーか、ポインタって「初心者は後回しにすべき難しいもの」
なのかなあ?
たしかに俺もCの前はBASだったが、
ポインタの概念はサクっと抵抗無く脳に入ったなあ。
それはBASICに飽き飽きするまで馴染まない限り
得られないサクだったと考えるべきなんでしょうか?
それともBASなんか実は不要だったんでしょうか…
ポインタ=URL 説 まんせー
いや、ポインタなんて完全制覇読めば誰だってわかるようになるとおもうぜ
>ポインタ=URL 説 まんせー アホ発見
>>233 だよねえ。
ところで番号が未来なんですけど…
236 :
デフォルトの名無しさん :2001/05/28(月) 00:45
>>1 ポインタでだけでなく、つまずくことはダメダメではありません。
むしろ当然です。
完全に理解できるまで、じっくり何回も本を読みましょう。
しかし悪い本では、じっくり何回もよむだけ時間の無駄。
いい本に出会ったらそれは幸運です。
237 :
デフォルトの名無しさん :2001/05/28(月) 01:13
ポインタは関数参照のために使うものだとわかったら すんなりわかったよ。
238 :
デフォルトの名無しさん :2001/05/28(月) 01:20
ポインタがわからんって言ってる人は、 URLなんだよとかなんとか、説明を受けてぼんやりとわかるものの、 実際に使ったこと無いし使い道もわからんので、 なんとなく怖いから使わない、だからわからない状態になってると思われ。 ポインタじゃないとできないこと、 ポインタでできることの目がさめるようなサンプルがあれば 役に立つんじゃネーノとか思ってみる。 俺はオナーニで忙しいから誰か作って。
239 :
デフォルトの名無しさん :2001/05/28(月) 01:29
>>238 確かに「ポインタとは何か?」ていうのはなんとなく分るとして、「で、何の役に立つの?」ってとこでつまずく初心者は多い(自分はそうだった)。
>ポインタでできることの目がさめるようなサンプルがあれば >役に立つんじゃネーノとか思ってみる。 それ、オレ見たい。
int i = 0, *p = &i; (*p)++; printf("i:%d *p:%d\n",i,*p); ↓ i:1 *p:1 眠くなってきた。
242 :
onamae :2001/05/28(月) 01:35
C言語ポインタ完全制覇という本が分かりやすかった。 この本によると void ( *signal(int, void(*)(int)) )( int ) みたいな複雑なものは英語で解釈して signal is a pointer to a function(int, a function(int) returning void) which is returning a function(int) returning void. って鬱だ。
243 :
onamae :2001/05/28(月) 01:38
あ、かぶった… ごめんなさい
244 :
onamae :2001/05/28(月) 01:41
<a function(int) returing void >a pointer to a function returning void
241がわからないやつのために解説してやろう。ばかもの。 まず、iが0なわけだ。 そしてint型のポインタ変数pがさすアドレスはiなわけだ。 そして*pは何をあらわすかというと実体だ。pはアドレスだ。 つまり(*P)を++ということは実体を1プラスする。 つまりiは1になる。 それをprintfしてやると当然i:1,*p:1になるわけだ。 感謝しろよ貴様ら。
246 :
デフォルトの名無しさん :2001/05/28(月) 01:44
連結リスト 対 配列 で、なんかいいサンプルを見れば、ポインタの有用性が実感できると思います。 なんかないかのぉ
247 :
デフォルトの名無しさん :2001/05/28(月) 01:47
>>242 の
>void(*)
ってなに?(void*)では無くて?
248 :
onamae :2001/05/28(月) 01:50
<signal is a pointer to a function >signal is a function to a pointer うう、はずい 逝ってしまいます。
249 :
onamae :2001/05/28(月) 02:13
>>247 わかりません。
どっちでもいいようにおもわれ
250 :
デフォルトの名無しさん :2001/05/28(月) 02:27
>ポインタでできることの目がさめるようなサンプルがあれば K&R本の文字列コピー あれを超えるサンプルはみたことない。 だんだんコードが短くなっていくさまは壮観だよ。感動できる。
251 :
名無し関数のλさん :2001/05/28(月) 02:37
>>247 void(*)(int) までで一塊で、
int を引数にとり戻り値がない関数へのポインタ
って意味。
void(*)(int) は関数へのポインタで、void * はデータへのポインタ
なんで、意味が全く違う。
C の型宣言は非常に読みにくいんだが、気合で慣れてくれ。どうして
も分からなくなったら typedef で書き直すと、少しはマシになる。
typedef void (*sig_t)(int);
sig_t signal(int, sig_t);
>>242 -251
なんでカッコがいるのかとか、演算子の優先順位からやった方が良いと思われ。
ポインタ同士で割り算 int a=40,b=5,c; int *A,*B; A=&a; B=&b; c=*A/*B;
>253 たんにc=a/bとすればよいのではないかバカモノ。
int division(int a, int b){ return a/b; } int (* calc(int (*f)(int, int)))(int, int){ return f; } calc(division)(10,2);
ギャグなんだよう・・・わかってくれよう・・・
c=*A/*B; ↑
そういうことかバカモノ。
>>250 わしは逆に「あ、そう」としか思えんかったなぁ。
struct data {
char *name;
char sex;
int height;
int weight;
struct data *next;
};
"struct data *next;" を見て「おぉ」と思った。
二項演算子の前後にはスペース入れるだろ不通
261 :
デフォルトの名無しさん :2001/05/29(火) 00:36
引数省略 windowsのDLL関数の引数の組み立てを動的に 行なう方法があったら教えてください。 名前と関数型が後で分かる場合とかに対応したいんです。 例えば、名前と、関数の型を文字列で与えると、その方式で呼ぶ様な感じを考えています。 dllcall("stdcall int f(int a, char *b)", a b);
262 :
デフォルトの名無しさん :2001/05/29(火) 01:39
>>261 C言語だけでも不可能ではないんじゃない?
当然、未定義な挙動を散々使うことにはなるけど。
まぁ、__fastcallと構造体の値渡しor値返しな関数の
呼び出しはアセンブラ使わないと無理じゃないかな?
具体的なやり方だけど、プロトタイプを解析しつつ<stdarg.h>の
マクロで引数を取得して行き、サイズがわかった時点で_allocaで
スタックにメモリを確保する。で、そこにさっき計ったサイズ分だ
け自分の引数の先頭のアドレスからコピーして、戻り値の型で分岐
して、(戻り値の型 (*)(void))でキャストして関数を呼ぶ。
__cdeclでも__stdcallでもちゃんと呼べるはず。スタックのずれも
自動的に修正されます。これはスタックフレームをEBPを使って構築
しているから。ESPが引数のサイズ分ずれようが、EBPから位置を得
られるんで問題ないというわけ。
呼び出し側のプロトタイプは次のような感じでしょう。
void __cdecl dllcall(const char *prototype,
void (*proc)(), void *result, ...);
素直にアセンブラ使ったほうが安全な気もするけどね(笑
263 :
261 :2001/05/29(火) 21:06
>>262 ありがとうございます。
とりあえずコンパイラの出力コードを真似てみます。
264 :
デフォルトの名無しさん :2001/05/29(火) 22:53
ボインたれ地獄(当方28歳)
265 :
デフォルトの名無しさん :2001/06/09(土) 23:32
---------------------------------------------------------------
266 :
デフォルトの名無しさん :2001/06/10(日) 22:52
age
(*((void (*)(void))1234))(); ↑ こんなの書いても注釈行と扱うコンパイラがあるのね。
struct data { char *name; char sex; int height; int weight; struct data *next; }; ってうちのコンパイラ(グリーンヒルズ)じゃ通りません、なぜ?
安物だから
>>268 struct data {
char *name;
char sex;
int height;
int weight;
data *next;
};
じゃ駄目?
>>267 PascalかModulaコンパイラか。