1 :
デフォルトの名無しさん :
2007/10/24(水) 04:07:56 なんと!意外にもスレが無かったので立ててみました 先日のソフトウェア開発技術者試験午後UのB木のポインタ表現 近年の基本情報技術者試験の午後C言語問題の自己参照構造体 など物凄く出来が悪いです。 ゆとり?文系?自作減少? ブラックボックス化されてメモリ管理やコンピュータの細かい知識が不要となった? 本当にポインターは必要なのか!?議論しましょう
2 :
デフォルトの名無しさん :2007/10/24(水) 04:08:11
3 :
デフォルトの名無しさん :2007/10/24(水) 04:08:47
4 :
デフォルトの名無しさん :2007/10/24(水) 04:09:04
5 :
デフォルトの名無しさん :2007/10/24(水) 04:12:01
ポインタのポインタ 関数のポインタ 文字列のポインタ 配列のポインタ
6 :
デフォルトの名無しさん :2007/10/24(水) 04:12:55
/⌒\ / / ̄ ̄ ̄ ̄ ̄ ̄\ / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ |/ \ < 今、ポインタ殺してきた。リアルで。 / ∠,,_ノ ソ _ ,,.. _) \__________________ /| '',,((ノ ) ノ (\) | | |  ̄'  ̄ イ ハァ ハァ \| υ 、_/ロロロ)_ ノ /  ̄ ̄ \ /| υ \ ( .| / ノ ̄ ̄ ̄) ノ \ ヽ.|◯ | ノ ̄ ̄ ̄) /\ ○\ /.| o .| ノ ̄ ̄ ̄) / \ o゚ \
7 :
デフォルトの名無しさん :2007/10/24(水) 04:14:15
C言語は卑猥すぎる。 何がって、*がだよ。*ですよ*。もう形からしていやらしい。 しかも名前は逆参照演算子。普通とは逆に突っ込む。 意味はポインタ。挿すものだなんて…製作者は何を考えてるんだか。 *を付けた変数をファック。 とても18未満には教えていいような言語じゃないね!
作ってわかるCプログラミング(著:日下部)のポインタでつまづいてオワタ\(^o^)/
つかポインタのサンプル何本か読んで理解できなかったら適性がない。 この先無理やり続けてもろくなことにはならないから 素直に公務員を目指したほうがいい。
10 :
デフォルトの名無しさん :2007/10/24(水) 07:18:49
11 :
デフォルトの名無しさん :2007/10/24(水) 07:30:45
1:何も付けない 2:*を付けてみる 3:&を付けてみる 全部試して落ちないのが正解
どうでもいいけどCのポインタの記法はキショい
13 :
デフォルトの名無しさん :2007/10/24(水) 07:54:11
int *p; int* p; どっちの書き方します?
後者は素人
int i, *ip; って書き方を考えると前者。 C++だと後者かな。
C だと int *p; C++ だと int* p; と書いている。
そのネタでしか伸ばせないならもう終わろうぜ
じゃあ次はモナドはどうやって学ぶべきかで頼む
ポインタ理解できない人は、メモリにデータが配置されるってことを 「紙の上」でのみ理解してるんだろうね。
理解できてる人は何で理解してんの? やっぱイケてるC使いは実際にアセンブリ言語でメインメモリいじくっちゃったりしてたんスかね?
メモリ配置がうんたらより 単純に演算子がややこしいだけ
アセンブリで書いていたこともあるけど、あんまり関係なくないか。 やっていればそりゃあメモリのイメージを掴むのに有利かもしらんけど。 とにかくなんかメモリの塊があって、そこを指している矢印があって、 その矢印がポインタだというイメージでいいんじゃないの。
24 :
デフォルトの名無しさん :2007/10/24(水) 11:28:48
>>20 いや、ワンボードしかなかった時代に、コンピュータをいじり始めたから、分かるだけなのだが...。
間接参照表現にキャストする演算子だと思えばいいんでねえの?
27 :
デフォルトの名無しさん :2007/10/24(水) 14:42:26
俺なんかポインタのポインタを扱えるようになるのに10年かかった。
>>27 例えばstrtol()みたいな関数も使えなかったわけですね?
>>28 ポインタのポインタを使った処理を思い通りに(納得行くかたちで)組めるようになるのに10年てこと。
関数の呼び出し方が分かったら、なぜポインタが必要かわかる
ポインタへのポインタが分からないと 2次元配列の動的確保さえできないんだよな…
d
アセンブラを学べばポインタも身につくってホント/ウソ?
ポインタはランダムアクセスイテレータ
ポインタ、面白いと思うんだけどな。
>>37 その面白さを若い奴らにどう伝えていくのか
技術の継承もおじさん世代の役目
40 :
デフォルトの名無しさん :2007/10/25(木) 13:23:34
42 :
デフォルトの名無しさん :2007/10/25(木) 18:41:27
ポインタを知らないと、参照渡しと値渡しの違いが分からないだろ 逆にその違いが分かればポインタも分かる
44 :
デフォルトの名無しさん :2007/10/25(木) 19:08:18
想像力のない奴め、教えてやるよ。 それは、ポインタという形にしてアドレスを意識しなくてもプログラミングできるようになったから C以降にプログラマになった奴はアドレスを意識する必要性に迫られなかったからだ。 覚える必要がないから覚えなかった。だから理解できなかった。そういうことだ。
ポインタ役たつけどなぁ
ポインタを安全にした仕組みでできなくて、ポインタでできる有益なことってなにかある?
連結リスト
ダブルポインタ
>>47 ノードオブジェクトがほかのノードオブジェクトの参照を持つ、ではだめか?
>>48 オブジェクトがほかのオブジェクトをもって、そのオブジェクトがまたほかのオブジェクトを持つ、じゃだめか?
ポインヨはランダムアクセスイテレータの実装の一つです
C言語をいくらやっても分からず、アセンブラを学んだとき ドミノが倒れるように全てを理解した あの感動を体験したいならまずC言語からやるのだ メモリやアドレスの定義もない、入門書からやるのだ これは数学と似ている。 集合も論理学も教えない。だからクラスの誰も分からない 大学に入って初めて秘密を知るのだ。 まあ無駄なのでアセンブラからやれ
52 :
デフォルトの名無しさん :2007/10/25(木) 21:56:23
>>51 CASLUでもいいですか?試験の為に本買ったんですが、Cの勉強(学校)が忙しくて放置したままです。
8086がいい。
54 :
デフォルトの名無しさん :2007/10/26(金) 07:12:07
初めて読む8086とかいうやつ?
55 :
デフォルトの名無しさん :2007/10/26(金) 11:30:54
>>53 まあ使うことのないだろうx86系のアセンブラで勉強するか、組み込みで使う可能性のある、ワンチップ
マイコンのアセンブラで勉強するか、どっちが実用性があるんだろうか?
ポインタよりもC++の参照がよく理解できない
>>56 俺も。
一回参照設定したら変更できないのが参った。
ポインタの変り種だとおもったんだけど違うらしい。
>>55 パソコン買えば漏れなく付いてくるx86系の方が実効性は高い
>>56 C++の参照は、constなポインタ。
変数宣言時、関数の引数、コンストラクタの初期化リスト内でしか
値を初期化できないように制限してある。
ポインタには、大きなデータのコピーを避けるための"共有"の意味と
配列等で個々の位置を表すための"イテレータ"としての意味とがあるけれど、
後者は使い方を間違えると危険だから前者しかできなくなっているということ
参照は正直、std::stringやstd::listを渡すときくらいしか使わんな
なんとなくポインタだと不自然だから参照で渡してる感じ
>>46 とあるメモリー上のデータの塊を、プログラマの都合で「違う解釈の仕方で読む」ことができるのが魅力
当然スピードを気にしなければJavaとかでもできるが、スピードの劣化が一切無くできるのがポインタの魅力
>>56 要するに、int *p と int &pは無関係
int *const p と int &p
const int *const p と const int &p
が対応してる
62 :
デフォルトの名無しさん :2007/10/27(土) 00:42:03
アナルアナルうるせーよ
63 :
デフォルトの名無しさん :2007/10/27(土) 10:36:58
演算子の表記法に問題があるんだよ。 同じ*でも、型宣言と、中身を取り出すときの両方で使うから初心者にはややこしい・・・
>>59 へーへー
俺もC++の参照よくわからんかったのでもっぱらポインタで代用してたけど
こういう意味だったのね
>>60 > 参照は正直、std::stringやstd::listを渡すときくらいしか使わんな
> なんとなくポインタだと不自然だから参照で渡してる感じ
俺はむしろ逆だな。ポインタとしての機能を必要としない限り参照
(あるいは値)で渡す。安全第一だからね。
>>65 大抵shared_ptr使っちゃうからなぁ
>>66 boost は俺も結構使うけど、あまり必要無いときは使わない。
参照で OK なのにわざわざ boost 持ち込むとかはせん。
68 :
デフォルトの名無しさん :2007/10/28(日) 10:04:33
あ
アセンブリ言語から始めよう
ポインタは特定の場所をポイント、だから!指差すものだと何度いったら。。。
なぜポインタを理解できないのかが理解できないから、教えようがないんだよねえ。
POD型の動的な多次元配列をポインタを使って実装するなら問題ないけど テンプレートメンバ関数ポインタを引数に取る関数のポインタの配列のポインタ とかなると意味わからなくなるんだけどこれは理解できてないからだな
ポインターをうまく言い表す日本語が鍵だな
>>61 C++ の参照渡しは、
int &p で宣言した関数に対して
呼び出し側では普通に int を渡すのが混乱した。
c++ の場合は定義の際は & つかうくせに実際に呼ぶときは 普通に呼べるのは便利だが、混乱の元でもあるね。
つーか。参照渡しを表す & とアドレス演算子を表す & に 同じ記号を使うように決めたデザインがド間抜けに一票。
ポインタもポインタで定義の際に*使うくせに 実際に呼ぶとき*をつけると中身が出てくる謎仕様 宣言と間接参照演算子が同じってだけで、結局は慣れなんだけどね。
>>78 int *p;
ってのは、「*pがint型」という意味でそのような仕様にしたらしい。
呼び出し側のソースを見たとき値渡しなのか参照渡しなのかわからないから参照嫌い
単純な8bitCPUとかPICとかのアセンブラを学んで見ると良い。 アセンブラで登場する各種のアドレッシングモードを理解出来れば ポインタなんてそれほど難しいもんじゃないよ。
82 :
デフォルトの名無しさん :2007/10/29(月) 18:48:11
Ruby使え
>>79 おお、なるほど。そう説明されればわかりやすいな
ポインタのポインタと 配列のポインタを 混同または理解していない香具師が多い
ポインタの配列?
ポインタのそのまたポインタのそのまたポインタ・・・・・訳わかめ
ポインタって、↓こうあるべきじゃね? int i = 0; pointer p = new pointer(i); pointer p2 = new pointer(p); p.type → int *p → 0 p2.type → pointer *p2 → p **p2 → 0
89 :
デフォルトの名無しさん :2007/10/30(火) 16:48:43
プログラマなら、いるいらないではなくて、常識です。
90 :
デフォルトの名無しさん :2007/10/30(火) 19:49:04
91 :
デフォルトの名無しさん :2007/10/31(水) 06:55:33
・ポインタとは、「メモリ上のアドレスを指し示す」変数である。 ・ポインタのみでは実体が無いため、malloc()でそのアドレスを先頭とした実領域を確保する必要がある。 この2点だけ意識してれば十分使えると思うんだけど。何故理解出来ないのかが理解出来ない。
データはふわふわと浮かんでるようなイメージでも持ってるのかも ある「どこかに」はなく、箱の中をただよっているという
そういうのを意識してたら 「関数ポインタを引数にとる関数ポインタの多次元配列のポインタ渡し」とかパッと書けるもんなんでしょうか? だとしたら俺は理解できてないな…
四則演算だったら、どれだけ長くなっても難しいとは思わないだろ 1+5-3+2*6+・・・ ポインタだって同じ
そりゃあ規則が明確だからね でもポインタ演算の規則を明確に理解しようと思ったらタイプ理論とかの知識がいるんでしょ?
97 :
デフォルトの名無しさん :2007/10/31(水) 11:29:07
0から100までの偶数の合計を求めるプログラムを作成せよ. ただしfor文を使用すること. また,条件分岐(if文とswitch文)を使ってはならない. 課題3 かけ算の九九を以下の例のように表示するプログラムを作成せよ. ただし,for文のネストを使用すること. 1 x 1 = 1 1 x 2 = 2 1 x 3 = 3 ... 1 x 9 = 9 2 x 1 = 2 2 x 2 = 4 ... 9 x 9 = 81 課題4 トランプのカード(ジョーカーを除く)を以下の例のようにすべて表示するプログラムを作成せよ. ただし,for文のネストとswitch文を使用すること. スペードの A スペードの 2 スペードの 3 ... スペードの 10 スペードの J スペードの Q スペードの K ダイヤの A ダイヤの 2 ダイヤの 3 ... 助けてくれ。。。 じゃヴぁで頼む。。。
プログラムが扱えるメモリ空間からスタックと静的領域除いた全てをmallocすればアドレス直指定だけで変数の宣言も定義もいらない幸せプログラミングが
そんな風にやるなら、そもそもmalloc必要なくね?
宣言の場合、全ては void* で、アドレスであると考える 使う場合、通常の変数とずれがあるので混乱するが、以下の関係がある *pointer = var; pointer = &var; *foo.pointer = *foo->pointer = foo.var = foo->var; foo.pointer = foo->pointer = &foo.var = &foo->var; どちらの形式をとっても、 アドレスと値のどちらにもアクセスできるようにしてあるという点が重要 (ただし、&var には代入できない・const void*とみなせる) 通常の変数は値を出し入れすることに主眼が置かれていて、 ポインタ変数はアドレスのほうを出し入れすることに主眼が置かれている
>>99 全てを自分で管理するなら、そもそも高級言語は必要ないんじゃ?
int *(*(*ponta[N])(int, int (*)(int)))(int); やっぱ、ポンタってむずいな、orz
ポンタwwww
>>85 84が言いたいのは↓こういうことじゃね
#include <stdio.h>
int main()
{
short *p, **pp, *pa[9], (*ap)[9];
pp = &p;
printf("ポインタのポインタ: size:%d",sizeof(pp));
printf("\tstep:%d\n",(void *)(pp+1)-(void *)pp);
printf("ポインタの配列: size:%d",sizeof(pa));
printf("\tstep:%d\n",(void *)(pa+1)-(void *)pa);
printf("配列のポインタ: size:%d",sizeof(ap));
printf("\tstep:%d\n",(void *)(ap+1)-(void *)ap);
getchar();
return 0;
}
103が言いたいのは↓こういうことじゃね #include <stdio.h> int main() { short *p, **pp, *pa[9], (*ap)[9]; pp = &p; printf("ポンタのポンタ: size:%d",sizeof(pp)); printf("\tstep:%d\n",(void *)(pp+1)-(void *)pp); printf("ポンタの配列: size:%d",sizeof(pa)); printf("\tstep:%d\n",(void *)(pa+1)-(void *)pa); printf("配列のポンタ: size:%d",sizeof(ap)); printf("\tstep:%d\n",(void *)(ap+1)-(void *)ap); getchar(); return 0; }
ポンタ微笑ます
>>106 103がいいたいのは
>>94 でしょ
typedef (*pfpf)(int (*)(int));
pfpf pfpfaa_tmp[9][9];
pfpf*** fuck;
fuck = &pfpfaa_tmp;
typedef int(*pfpf)(int (*)(int));だった(’ω´)
110 :
デフォルトの名無しさん :2007/10/31(水) 20:54:21
* をデリヘル演算子って呼ぶのがはやってた
111 :
デフォルトの名無しさん :2007/10/31(水) 20:59:15
エロ写真の乳を如何に鷲掴みしようとしても それはポインタであり実体はそこにはないのである。
下手
113 :
デフォルトの名無しさん :2007/10/31(水) 23:02:27
>>1 これから技術者として生きていきたいと、もし君が思っているとしたら。
「〜〜だから、これは学ばなくていい。」という考え方は、
ひとまずやめたほうがいい。
まだ君は、どの情報が必要で、どの情報が必要でないと判断できないわけだから。
まずは、とにかくトコトン悩んでやってみることだよ。
自分の方向性を決めるのは、その後でも十分だと思う。
114 :
デフォルトの名無しさん :2007/11/02(金) 08:35:23
JavaやC#などの次世代の言語にもポインタの概念はしっかり受け継がれてるから知っておいて損はないかと
教えたがりしかいねーなこのスレw
116 :
デフォルトの名無しさん :2007/11/02(金) 19:13:53
これで文字列が代入されないのは何故ですか??? ↓を改善させるためにポインタのポインタを使わなきゃいけない理由は何故ですか? void myalloc(char *p1, char *p2) { p1 = malloc(20); strcpy(p1, "first string"); p2 = malloc(20); strcpy(p2, "second string"); } int main(void) { char *p1; char *p2; myalloc(p1,p2); printf("p1=%s p2=%s\n", p1, p2); return 0; }
>>115 ポインタがよくわかりません。教えてください><
>>116 myalloc(char *p1, char *p2)のp1,p2とmainのp1,p2が別の人だから。
119 :
デフォルトの名無しさん :2007/11/02(金) 19:42:46
>>118 値渡しではなく、参照渡し(アドレス渡し)にしているのにですか?
>>119 どこが?
void myalloc(char *p1, char *p2)
はchar*の中身を渡しているだけで、
char*自身を渡してないよ。
int main(void) { char *p1 この段階ではp1には不定な値が入っている。例えば0xfefefefeだとしておこう void myalloc(char *p1, char *p2) { これが呼ばれた段階で p1 == 0xfefefefe p1 = malloc(20); この段階で p1 には何かしらのアドレスが入る。例えば0x00001000 としよう myallocを抜ける段階でp1という変数は消えてなくなる。 なぜならp1はローカル変数だからだ 結局のところ、myallocのp1は、mainのp1が保持していた 0xfefefefeという値とコピーしたローカル変数に過ぎない そのローカル変数にmallocの返り値を保存しても、mainのp1には何の影響もないわけだ
>0xfefefefeという値とコピーしたローカル変数に過ぎない 0xfefefefeという値「を」コピーしたローカル変数に過ぎない だった。意味が通じなくなりそうだから念のため修正
仮に void myalloc(char p1, char p2) で考えてみよう。 main(){ char p1='a' char p2='b'; myalloc(p1,p2) } こうした時myalloc(p1,p2) にやってくるのは'a','b'という値。 なのでmyalloc(p1,p2)の中でp1,p2を変更してもmainの中のp1,p2は変化しない。 あとは*をつけるだけ。 void myalloc(char *p1, char *p2) main(){ char* p1="a"; char* p2="b"; myalloc(p1,p2) }
124 :
デフォルトの名無しさん :2007/11/02(金) 20:09:33
あ〜なんとなくわかった気がします つまり・・・
125 :
デフォルトの名無しさん :2007/11/02(金) 20:11:15
mainのchar *p1が指すアドレスが入っているだけで、 mainのp1自身のアドレスを渡しているわけではないんですね
>>125 そうです。結構はまるポイントですね。これ。
127 :
デフォルトの名無しさん :2007/11/02(金) 20:17:40
あれ?いやまた分からなくなってきた ↓改善したプログラムですが・・・*p1と*p2もローカル変数だから消えちゃって・・・ void myalloc(char **p1, char **p2) { p1 = malloc(20); strcpy(*p1, "first string"); p2 = malloc(20); strcpy(*p2, "second string"); } int main(void) { char *p1; char *p2; myalloc(&p1,&p2); printf("p1=%s p2=%s\n", p1, p2); return 0; }
128 :
デフォルトの名無しさん :2007/11/02(金) 20:20:22
まちがった ↓改善したプログラムです void myalloc(char **p1, char **p2) { *p1 = malloc(20); strcpy(*p1, "first string"); *p2 = malloc(20); strcpy(*p2, "second string"); } int main(void) { char *p1; char *p2; myalloc(&p1,&p2); printf("p1=%s p2=%s\n", p1, p2); return 0; }
129 :
デフォルトの名無しさん :2007/11/02(金) 20:21:08
130 :
デフォルトの名無しさん :2007/11/02(金) 20:23:27
>>127 実に惜しい
つーか怖いwww
void myalloc(char **p1, char **p2)の中のp1はmainのp1をポインタに持つポインタなので・・・
mainのp1のポインタに対してmallocするには・・・
ていう。
こういうところでポインタ宣言と間接参照演算子が同じってのが邪魔してくるんだよな あと名前の設定をミスってるのが大きい。 char*のやつは文字列型っぽい名前にしなくちゃいけないし、 引数のほうは文字列型のアドレスっぽい名前にしなくちゃ。
ってよく見たらmallocおかしいじゃねえかw
>>129 一回名前かえよう
void myalloc(char **pp1, char **pp2)
{
}
int main(void)
{
char *p1;
char *p2;
}
とすると、pp1はp1を値に持っている。なので*pp1=p1
*pp1をいじると当然p1も変わる。
134 :
デフォルトの名無しさん :2007/11/02(金) 20:29:31
図で描けたら簡単なんだけどな・・・
135 :
デフォルトの名無しさん :2007/11/02(金) 20:30:38
>pp1はp1を値に持っている 『pp1は&p1を値に持っている』じゃなくて>『pp1はp1を値に持っている』ですか?
>>135 サーセン『pp1は&p1を値に持っている』です。
ソースコードでオナニーできて一人前
138 :
デフォルトの名無しさん :2007/11/02(金) 20:40:49
いや、pp1はp1を値に持っているでいいんだ。
&&pp1 &pp1 pp1 *pp1 **pp1 ***pp1 処理の度に全部printfで表示させればいいんだよ
140 :
デフォルトの名無しさん :2007/11/02(金) 20:58:48
ベテランの人たちはダブルポインタを扱うとき いちいち頭で考えて使っているんですか? それとも体が勝手に動くものなんですか?
別にベテランじゃないけど上にあるやつくらいだったら まともな命名法と*の読み方しだいで何とかなる範囲じゃね?
当然頭は使ってるけど何度も使ってれば考える時間は短くて済むようになる
C++ならダブルポインタは使わないで済むけどね
145 :
デフォルトの名無しさん :2007/11/02(金) 22:00:46
freeはいつ呼べばいい?myfree作るべき?
宗教論争になりがちだからお好きなように…かなw
スマートポインタ使え
148 :
デフォルトの名無しさん :2007/11/02(金) 22:45:47
ポインタって要するに参照渡しのことですよね?
参照渡しっていうとなにかとC++の参照が出てくるから困る
「ダブルポインタ」っていうのは素人が使う言葉
「ダブルポインタ」「ポインタのポインタ」 なんて呼び方はやめて普通に 「ポインタへのポインタ」 って呼べばいい という主張をどこかで見たな
素人は「ダブルポインタ」なんて知らんだろ
参照とダブルポインタは違うよね?
155 :
デフォルトの名無しさん :2007/11/03(土) 14:01:21
問題は「ダブルポインタ」と言ってしまうと 「配列へのポインタ」と「ポインタへのポインタ」の どっちの話をしているのかが決まらないまま話が進むこと ↓ だから素人同士の会話でしか使われない表現ということ
ダブルポインタなんて2chでしか貴下ねーな
157 :
デフォルトの名無しさん :2007/11/03(土) 14:03:22
補足 × 問題は「ダブルポインタ」と言ってしまうと ○ 問題は「char **p;」の表記だけを見て「ダブルポインタ」と言ってしまうと
ちょっと暇つぶししてみた ダブルポインタ に一致する日本語のページ 約 3,040 件 ポインタのポインタ に一致する日本語のページ 約 9,800 件 配列のポインタ に一致する日本語のページ 約 672 件 ポインタへのポインタ に一致する日本語のページ 約 616 件 配列へのポインタ に一致する日本語のページ 約 14,800 件 最近はブログのせいでごみばっかり引っかかるようになってしまった と言っても以前はマニュアルのコピーばっかり引っかかってた訳だが
159 :
デフォルトの名無しさん :2007/11/03(土) 14:13:28
(T** a)みたいにするんじゃなくて (T* *a)にしたら少し理解しやすくなったかもしれないこともなかったような気がした
左の * と 右の * はどっちが優先度高いんだっけ?
char str[256]; char *p; p = str;
漏れがCやり始めた頃はダブルポインタなんか言ってる香具師は一人もいなかったな だれが流行らせたんだ?メジャーな入門本に書いてあるのか?
>>163 int *p; イントポインタ
double *q; ダブルポインタ
これをだれかが間違って解釈して
馬鹿の間で蔓延したと思われ
それは確かにダブルポインタwwwww
>>164 それ見てダブルポインタなんてアホな呼び方してるのは
日本人だけだろうと思って調べてみたが
毛唐の間でも普通に使われてるのな
double *p;
int **p;
両方の意味でw
>>157 char **p;
と書いて配列へのポインタと解釈することなんてありえるか?
配列へのポインタといったら
char (*p)[N];
じゃないのか?
>>167 int main(int argc, char **argv)
ちなみにmeta-pointerって呼び始めたのは俺。 MITで今じゃ完全に定着しているって後輩が言ってた。
配列のポインタとポインタの配列は区別しようぜ
馬鹿が馬鹿に説教するスレはここですか?
>>171 ポインタの配列とダブルポインタの区別はしなくても平気ですか?
馬鹿じゃないよ C言語は得意だけど日本語が苦手なだけだよ
double *pは「double型へのポインタ」だろ。そうとしか読めない。
ダブルポインタって言葉をほとんど聞いたことが無い
俺はある
二重ポインタならよく聞くけど、ダブルポインタは滅多に聞かないな。
二重ポインタは初耳 ポインタへのポインタばっかり
今の今までインディレクトポインタと呼んでいたぞ。
昔、面接で「ダブルポインタはOKですが、トリプルポインタは自信がありません」と言った香具師がいた。 案の定、ポインタを理解していなかった。
そうだ。ダブルポインタとはdouble*のことに違いない。
ポインタへのポインタへのポインタは使ったことがない気がする
*** は滅多に使わないけど全く使わないということはない ただそういうときには typedef するか struct になってることの方が多い
187 :
デフォルトの名無しさん :2007/11/04(日) 06:03:01
3次元の配列の動的確保
190 :
デフォルトの名無しさん :2007/11/04(日) 13:17:16
文字列の二次元配列を使おうとしたときに どうすればいいか分からなかった漏れが来ましたよ
char Array[32][16];
文字の二次元配列だな
std::vector<std::vector<std::string> > Array;
std::vector<std::vector<std::string *> *> *Array;
std::vector< tr1::shared_ptr< std::vector< tr1::shared_ptr< std::string > > > > ary;
198 :
デフォルトの名無しさん :2007/11/04(日) 20:31:42
ベクター
ベクトル
う゛ぇくとぉ
typedef char *string; string Array[32][16]; /* 200 get */
え?
ウルトラ警備隊に聞いてみろ
ポインタを理解できない人は、C言語 ポインタ完全制覇を読みなさい。 それでも、わからなければ・・・・ 私は知らん。
考え方や概念よりも、文法がややこしいんだと思うよ。 変数に成り代われるのは演算子のおかげであって、ポインタ自体はアドレスを指すことしか出来ないんだから。
ああ、ポインタの概念自体をさっぱり理解できない人はまずいない。 演算子の扱いとか、関数の引数や戻り値としての扱いとか、直観に反する振る舞いをするのでつまづく。
滅茶苦茶直観的だけど
ここに書いてあったので「へー、ダブルポインタって呼ぶんだ、初めて聞いたな」と思ってダブルポインタと早速呼称してたorz
210 :
デフォルトの名無しさん :2007/11/05(月) 19:02:30
ポインタなんて、実はだだの正数値が入ってる変数なんです 変数と知れず変数を指し示す物と考えると理解が難しいのかもしれません int a; int *p; p = &a; *p = 10; printf("%d",a); 結果: 10 普通はやりませんが以下の様に正数型をポインタとしても使えます int a; unsigned int p; p = (unsigned int)&a; *(int*)p = 10; printf("%d",a); 結果: 10 このようにキャストをしっかりしてやれば代用が利いたりします でも、64ビットOSだとこれは変更が要りますが64ビットOSはポインタのサイズが32ビットが64ビットの正数型になるだけなので64ビット長の正数型を用意するだけで良いだけのことですけどね
処理系依存なことを言語仕様に定められてるかのように書くなよ・・・
>>210 そもそも正数っていうのは0より大きい実数のことであって、
unsigned intっていうのは0以上の整数のことであるわけだが。
じゃなくてあってんのか。 まあいいや。
というかこんなことが出来たとして何の役に立つの?
出来ない奴が役に立たない
ポインタをintにキャストする人は役に立つんだね 知らなかったよ
俺は知ってた
過去に一回だけそんな使い方をしたことあるな・・・ なんでそれをやったかは忘れた
ポインタ値の配列の宣言がわからなくてintの配列で代用した こんなあたりだろ
ポインタの配列ってこうでいいんじゃないんですか? int* pointa[10];
確かにそうだが変数名が気に入らないw
224 :
デフォルトの名無しさん :2007/11/06(火) 00:52:22
ポインタの配列 int* ponta[10]; int配列へのポインタ int(* ponta)[10]; でいいんですよね?
int[]型みたいなのが無いから書き方がカオスだな
226 :
デフォルトの名無しさん :2007/11/06(火) 00:58:13
ポインタの文法を学ぶ前になんでポンタが必要かを理解させないから苦労して学ぶ気になれないのでは なんで?最近の言語はコンパイル時に勝手に最適化してくれるんじゃないの? WEB系ではいらない? 汎用系では? 制御・ファーム・ハード系では? ソフト系では?
『昔のPC・OSではな〜メモリが64KBしかなくてな〜』とか言う懐古厨はお断り
最近の若い子はなんでも参照で済ますから・・・
int a; double *p; p = (double *)&a; *(int*)p = 10; printf("%d",a); 結果: 10
当たり前って言えば当たり前
>>230 それは流石に駄目だろう
多分、出来なくはないだろうけど浮動小数点数の演算が適応されないポインタに対してこれはナンセンス過ぎないか?
int a;
double p;
p = (double)&a;
*(int*)p = 10;
printf("%d",a);
結果:
>>232 これと勘違いしてない?
sizeof(int*) <= sizeof(double*)な処理系じゃないとダメじゃね? まあこれを満たさない処理系なんてあるのか知らないけど
初心者だけど
>>233 のコードが実行できると
どっかのメモリに10が代入されるってことなのか?
239 :
236 :2007/11/06(火) 15:34:16
>>237 ポインタのサイズは指している型に関わらず同じ、なんてことは無かったような気がするんだけど
間違ってる?
aに10が入る
>>239 ポインタはint型のサイズと同じって記憶があるけど。
>>239 ポインタのサイズが型によって違う処理系教えてくれ
243 :
デフォルトの名無しさん :2007/11/06(火) 15:47:56
>>238 doubleにintポインタのアドレスを入れるけど、
doubleの値をintポインタにキャストしてるから、
結局int aに値を入れてるのと同じ。
244 :
デフォルトの名無しさん :2007/11/06(火) 15:48:44
>>243 語弊があるな、intのアドレスをdoubleの値に入れる。かな
>>243 なるほどね、読み返して見たら納得できた。
246 :
236 :2007/11/06(火) 16:24:31
どっかで見た気がしたんだが記憶違いだったか しかし、void*とかmallocとか考えるとありえないなorz スレ汚しすまんかった
現状そういう処理系が実在しないにしても 規格上はint *とdouble *が安全に変換できるとは限らない void *を介しても同じ事
昔々、ポインタにはfarとnearがあっての…
ポインタなんて今時覚える必要ないと思う。 C#とかポインタを気にせずプログラミングできる言語が主流になりゃいい。 今後PCはどんどん高性能化していって統合環境が整うんだからポインタみたいな 危険な構造、なくしてけばいいよ。 そういうのはコンパイラに任せとけ。
例えば貴方の身の回りの家電や車の制御プログラムにC#を入れるとな? こういうマイコンは限られたメモリをいかに容量的に効率的に高速に使うかが大事
>>252 ただ現実にはそういう方向かもね。携帯とか Java 走ってる。
あと、C 使いこなすにはポインタ理解する必要はあるけど、
必要以上にポインタを使い回す事はない。パフォーマンスが
心配なら実際 profiling してから直すべき。
ついでに、あまり複雑なことをしなけりゃポインタも簡単。
Javaとかにも、配列の途中からを指す方法があればなあ 配列そのものと、何番目かをあらわすIndexと。二つ渡すのが非常にかっこわるい
SubList使えよ
携帯Javaにはそんな便利なもんねえ
257 :
デフォルトの名無しさん :2007/11/07(水) 06:26:59
>>251 C#、Javaはむしろポインタだらけじゃないか?
>>243 >doubleにintポインタのアドレスを入れるけど、
>doubleの値をintポインタにキャストしてるから、
>結局int aに値を入れてるのと同じ。
double*に入れるときは問題ないけど
doubleに入れるときはアドレス値がdouble値としてふさわしくないときに
正規化されて他の正しい浮動小数点数に変換されるだろうから
int*にキャストしたときには別の場所を指してる可能性があるね
そんな環境実際にあんの?
>>259 確かにその通り。正規化云々以前にポインタ値をdouble変数に入れられない。
どうせ二進表現の数なんだから、ビット幅さえ合えば入れられるんじゃないの? 数値としては別な物になるだろうけど。
アセンブラをやれ でFA?
>>261 longに入れたりintに入れたりは幅だけ合ってれば出来るけど
doubleの場合は規格化された値しか入れられないよ
>>261 union {
double d;
int *p;
} hoge;
hoge.p = (int *)-1;
printf("%f", hoge.d);
これやってみ
なんていうか 無理に1000いくまで議論しなくてもいいと思うんだ・・・
関数ポインタ int func(int a) { return a*2; } main(){ int (*p_func)(int); p_func = func; (*p_func)(2); //実行方法 }
関数へのポインタだろ
関数へのポインタへのダボーポインタだろ
これは何ですか?関数配列へのポインタ?関数へのポインタの配列? void (*p_funcs[])(void) = {funca, funcb};
271 :
デフォルトの名無しさん :2007/11/07(水) 22:43:34
ポインタの配列 int* ponta[10]; int配列へのポインタ int(* ponta)[10];
272 :
デフォルトの名無しさん :2007/11/07(水) 22:45:56
これだと関数の戻り値へのポインタなのか誰か関数とかまとめて void *func(void);
273 :
デフォルトの名無しさん :2007/11/07(水) 22:51:54
関数って配列にできるんですか
274 :
デフォルトの名無しさん :2007/11/07(水) 22:55:31
関数配列の戻り値へのポンタ int *ponta[10];
// 関数ポンタ配列 #include <stdio.h> typedef int (*pKANSUU)(int); int pontax0(int ponta){ return ponta-ponta; } int pontax1( int ponta ){ return ponta; } int pontax2(int ponta ){ return 2*ponta; } int main(){ pKANSUU ponta[3]; //int (*ponta[3])(int); ponta[0] = &pontax0; ponta[1] = &pontax1; ponta[2] = &pontax2; printf("x0: %d, x1: %d, x2: %d\n", (ponta[0])(100), (ponta[1])(100), ponta[2](100) ); return 0; }
なんか変なレスが混ざってるんだが、わざとやってるのか?
277 :
デフォルトの名無しさん :2007/11/08(木) 00:00:13
なんか間違ってね?
関数配列ってなに
280 :
デフォルトの名無しさん :2007/11/08(木) 00:14:16
>>279 つ kannsuuhairetsu[] = {kannsuu0, kannsuu1, kannsuu2,......};
関数ポインタって代入時の&と実行時の*ってなくても動作変わらないよね? もともとはどっちが正しいの?
元々必要だったらしいが、gccがなんか理論武装して独自拡張として省略しても良くしたら、 世間に受け入れられたなんて話を聞いたことがある。
余計ややこしくなった気もしますね
ジャンプテーブル
285 :
デフォルトの名無しさん :2007/11/08(木) 06:50:19
関数の戻り値へのポインタ void *func(void);
286 :
デフォルトの名無しさん :2007/11/08(木) 06:52:01
関数の戻り値の型が不貞の時は void func(void); で宣言していいんですか?引数が不貞の突起も?
287 :
デフォルトの名無しさん :2007/11/08(木) 07:05:56
://local.joelonsoftware.com/mediawiki/index.php/%E9%96%93%E9%81%95%E3%81%A3%E3%81%9F%E3%82%B3%E3%83%BC%E3%83%89%E3%81%AF%E9%96%93%E9%81%95%E3%81%A3%E3%81%A6%E8%A6%8B%E3%81%88%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B
>不貞の突起 なにやら面妖な…… 関数の戻り値型は一致しないといけません。まぁ、呼び出し側で値を使わないなら何でも構いませんが。 引き数に関しては、プロトタイプ宣言するなら一致している必要が出てくるのでなしと宣言したらなしになるので、 宣言したくないならなし(void)書いてはいけません。
289 :
デフォルトの名無しさん :2007/11/08(木) 17:33:36
教えてください。 void swap_ptr(char **a, char **b) { char *temp; temp = *a; *a = *b; *b = temp; } int main(void) { char *str_a = "ABC"; char *str_b = "123"; swap_ptr(&str_a, &str_b); printf("str_a=%s str_b=%s\n", str_a, str_b); return 0; } ↑のは正常に文字列の入れ替えが出来ます。 ならば void swap_ptr(char **a, char **b) { char *temp; *temp = **a; **a = **b; **b = *temp; } にしたら先頭の一文字だけ交換されるのか・・・と思ったら、交換されない上Warningまで出ます。 何がおかしいのでしょうか?
290 :
デフォルトの名無しさん :2007/11/08(木) 17:35:09
さらに void swap_ptr(char **a, char **b) { char *temp; &temp = a; a = b; b = &temp; } にしたらコンパイルすらできません。この場合はaとbのスタック変数のメモリアドレスそのものを(物理的に)交換しようとしているからなのでしょうか?
291 :
デフォルトの名無しさん :2007/11/08(木) 17:39:22
あ、
>>289 はWarningは出ないけどコンパイル後実行させた時に
>『問題が発生したため、a.exe を終了します。 ご不便をおかけして申し訳ありません。』
という致命的なエラーで落ちます。
>>289 の後者は、
void swap_ptr(char ** a, char ** b) {char temp = ** a; ** a = ** b; ** b = temp;}
でないと辻褄が合わない。
そもそもchar * temp; だけではポインタは初期化されていないので、* temp = ...; とした場合不正アクセスになる。
変数に入ってる具体的な数字をprintしてみればすぐわかる
更に、>290のように&演算子を使った値は右辺値なので代入ができない。
295 :
デフォルトの名無しさん :2007/11/08(木) 17:54:38
printしたらAが出ました。 printf("%c\n",**a);
アホかい。
297 :
デフォルトの名無しさん :2007/11/08(木) 18:10:38
&str_aを引数で受け取った場合、 char **a; &a: ? a: ? *a: a配列全体を指すアドレス **a: aの実体(1文字) ローカル変数のスタックはどこにいった
&a: 文字列のアドレスのアドレス a: 文字列のアドレス *a: 文字列(文字配列へのポインタ) **a: 先頭文字
299 :
デフォルトの名無しさん :2007/11/08(木) 18:14:52
違った、 *a: 文字列(文字へのポインタ)
&a: ローカル変数a自身のアドレス a: aの指すアドレス *a: aの指すアドレスの中身(文字配列全体)を指すアドレス? **a: aの指すアドレスの・・・?
まとめてみます これでなんでエラーが出るんでしょう。 #include <stdio.h> void swap_ptr(char **a, char **b) { char temp; temp = **a; **a = **b; **b = temp; } int main(void) { char *str_a = "ABC"; char *str_b = "123"; swap_ptr(&str_a, &str_b); printf("str_a=%s str_b=%s\n", str_a, str_b); return 0; } 予想される結果:str_a=1BC str_b=A23 現実:コンパイルは通るけど実行後何も表示されずに即エラー落ち
>>299 >292を使うには、main()でchar str_a[] = "ABC"などとしないといけない。
304 :
デフォルトの名無しさん :2007/11/08(木) 18:38:19
str_a[0]='1';
>>303 む
char str_a[] = "ABC"; (引数&str_a)もしくは
char **str_a = "ABC";(引数str_a)で宣言すると
無事に"文字列"全体が交換されたんですけど、先頭文字だけでは無いんですね。何故か
いや、なんでもないです。
>>305 は無視してください
307 :
デフォルトの名無しさん :2007/11/08(木) 19:56:18
ポインタのポインタのポインタのポインタとか ヘンタイじみたモノは使うのを辞めましょう
文字列リテラルを書き換えてはいけない
309 :
デフォルトの名無しさん :2007/11/08(木) 23:51:48
>>305 どうでも良いけど、警告でねーか?
引数とわたす値の型が違ってるんだし
全体が交換されたからといって
こんな間違ったポインタの使い方
なんの役にもたたねぇぞ
310 :
デフォルトの名無しさん :2007/11/09(金) 00:27:30
void main() { (*************printf)("hello\n"); } これがコンパイルできるのはなぜですか? 気になって夜もろくに眠れません。 誰か教えて!!
寝なくていいよ
312 :
デフォルトの名無しさん :2007/11/09(金) 03:30:41
プ
void main() { (*************************************************************************************************************************************************************************printf)("hello\n"); } これも出来たから大丈夫
314 :
デフォルトの名無しさん :2007/11/09(金) 22:16:57
つーかこれ通るんだから。 int main(void) { 1; return 0; }
316 :
デフォルトの名無しさん :2007/11/10(土) 00:39:09
main(){ ('A') }
懐かしい!!ポインタは面白いね char *s1, *s2; while (*(unsigned long long *)s2 = *(unsigned long long *)s1); この超ドSなコピーとかやってみ?ほんとハラハラさせてくれるよね
s2++,s1++するの忘れた ついポインタに目がいってしまいました
319 :
デフォルトの名無しさん :2007/11/10(土) 01:52:25
main(){ ('A')マンドクセ }
ボインたん (;´Д`)ハァハァ
321 :
デフォルトの名無しさん :2007/11/10(土) 02:21:33
(ポインタをメンバに持つ構造体)をメンバに持つ構造体へのポインタ あたりの自己参照構造体が難しいのですが・・・どうすりゃいいんだ〜〜〜〜
struct Node { struct Node *pNext; void *ptr; }; 自己参照構造体ってこんなんだっけ?
323 :
デフォルトの名無しさん :2007/11/10(土) 02:31:10
こんなやつ 自己参照構造体が苦手でよくソフ開受かったな俺 typedef struct _person { int number; char name[40]; struct _person *prev; struct _person *next; } person; main() { prson *p; }
324 :
デフォルトの名無しさん :2007/11/10(土) 02:34:46
メンバで「struct _person」を使う理由はまだ宣言されていないから 「struct _person」を「person」という省略名で宣言したいが、 メンバの定義段階では、「struct _person」は定義済みだが未だ「person」は定義されていないため 「struct _person」というダミーの名前を使わないとコンパイルエラーになるからって奴。
typedefとか使わなくていいんじゃないかと思う今日この頃 C言語は今でも struct _person { int number; char name[40]; struct _person *prev; struct _person *next; } ; main() { _person *p; } こういう書き方はだめなんだっけ?
>>326 そうなんかd
最近「C言語で開発」とか言われても、開発環境がC++だから
どこまでがCの仕様なのかわからなくなることがある
C++コンパイラ使ってベターCな開発するのはいいが、 その機能がCのものなのかC++のものなのかも理解して いないような香具師らもウジャウジャいるから気をつけろ。
329 :
デフォルトの名無しさん :2007/11/10(土) 03:18:38
331 :
デフォルトの名無しさん :2007/11/10(土) 03:20:49
>>326 あ、今試したらだめだった
なんでダメなんだっけ?
structの部分も含めて「型」なんだって事じゃないの?
333 :
デフォルトの名無しさん :2007/11/10(土) 03:26:19
つまり、main() { struct _person *p; } にしたらOKってことか
334 :
デフォルトの名無しさん :2007/11/10(土) 03:59:01
ヌルポインター
335 :
デフォルトの名無しさん :2007/11/10(土) 04:10:51
以下のコードでコメントアウトをはずすとエラーが起こるのは何故ですか?? #include <stdio.h> int main(void) { char *p = "ABCD"; char *q; q = p; // q[1] = 'D'; printf("p = %s\nq = %s\n", p, q); return 0; }
336 :
デフォルトの名無しさん :2007/11/10(土) 04:12:55
char p[] = "ABCD"; と宣言したら正常に動作した(ADCD)のですが、 なんでですか?
337 :
デフォルトの名無しさん :2007/11/10(土) 04:13:26
ポインタは配列で操作出来るのでは
338 :
デフォルトの名無しさん :2007/11/10(土) 04:17:07
339 :
デフォルトの名無しさん :2007/11/10(土) 04:19:02
あげ
341 :
デフォルトの名無しさん :2007/11/10(土) 05:34:26
int readfile(LINE *hook, char *fname)
{
FILE *fin = fopen(fname, "r");
char stemp[256];
hook->next = hook->prev = hook;
if(!fin) return 0;
while(fgets(stemp, 256, fin)){
if(!(hook->prev->next = malloc(sizeof(LINE)))) return 0;
if(!(hook->prev->next->str = malloc(strlen(stemp) + 1))) return 0;
strcpy(hook->prev->next->str, stemp);
hook->prev->next->prev = hook->prev;
hook->prev->next->next = hook;
hook->prev = hook->prev->next;
}
このコードを書いたのは誰だあッ!
hook->prev->next->next とか hook->prev->next->prev とか(平気で書ける神経が)理解できねえ(笑)
http://www.kt.rim.or.jp/~kbk/zakkicho/07/zakkicho0708b.html ■ げねれーた
>>335 "ABCD" は 暗黙の const char * だから。
343 :
デフォルトの名無しさん :2007/11/10(土) 07:33:21
>>342 char p[] = "ABCD";とした時も暗黙のconst char * なのですか?
344 :
デフォルトの名無しさん :2007/11/10(土) 09:11:30
ぬるぽ
>>343 それは本当の char p[] だわさ。
だから書き換えても大丈夫。
#include <stdio.h>
int main(void)
{
const char p[] = "ABCD";
const char *q;
q = p;
q[1] = 'D';
printf("p = %s\nq = %s\n", p, q);
return 0;
}
をやってみたら?
>>336 char配列の初期化には、例外的に文字列リテラルが使えるという決まりがあるから。
347 :
デフォルトの名無しさん :2007/11/10(土) 10:36:20
>>345 普通に実行できた
$ ./a
p = ADCD
q = ADCD
char *p = "ABCD"; は静的なところにある"ABCD"のアドレスをpに入れてるだけ って認識であってるよね?
cc -S a.c して a.s 読めば一目瞭然。
350 :
デフォルトの名無しさん :2007/11/10(土) 11:28:17
>>349 流石に20代だから
流石にアセンブラなんて知りませんよ。流石に
>>350 いや。読むだけならアセンブラは簡単。
ポインタの理解にはアセンブラが、
オイラの持論だ。
アセンブラを理解するのには、ものすごく基本的な メモリとアドレスの事知る必要がある。 それがポインタを理解する上でも必要ってだけのことだ。 運転覚えるのにエンジン分解したいひとは、アセンブラからどうぞ。
分解したくはないけれど、どんな気筒が幾つ、どんな風に配列されているかは知りたいぞ。
float f = 10.0f; int i = *(int*)&f; printf("%f %f",i,f); 結果: 10.000 10.000 ちょっと遊んでみるw
そのとおりだな。 アセンブラを知らないプログラマーは 自動車運転できるのにボンネットを一度も 開けたことの無い人に相当する。
俺アセンブラ知らないけどあんまりポインタで困った覚えがない ボンネットはウォッシャー液が切れたら空ける
学習のとっかかりとしてはいいけど、基本的に アドレスとポインタとは切り分けて考えた方がいいよ
ΩΩ Ω<ナ、ナンダッテー アドレスとポインタって違いを3行で
ポインタには(対象の型)という情報が含まれている。 アドレスと言う概念にはそんなものは全くない。 強いて言うなら、void * のようなもの。
ほんとに3行だw ありがとう
そもそも規格には、ポインタの値はアドレスであるなんて一言も書いてない。 ってほんと?
普通に考えればそうだろ 変数を間接的に指し示してくれさえすれば用は足りるわけだし
ポインタはアドレスを入れるための変数。 お茶碗とごはんの関係。
ポインタはただの変数だ〜
>>355 そのたとえで行くならば、IC やトランジスタ弄ったこと
ない人も同じだな。
物理化学やら量子力学を勉強してない人も(ry
一人の人間の一生程度じゃどうしようもない範囲ですな
369 :
デフォルトの名無しさん :2007/11/11(日) 01:31:28
俺は頭がいいからなんとかなるけど 低収入のオマエラじゃ無理だな
>>369 はいはい、掲示板では何とでもいえるさw
>>341 実際こう書くこと多いけど何か問題でもあんの?
読みにくいってだけじゃないの?
373 :
デフォルトの名無しさん :2007/11/11(日) 03:15:32
>>371 ,372
まぁ論外だ。論外だということを理解できない君が、プログラマでない
ことを願う。
374 :
デフォルトの名無しさん :2007/11/11(日) 03:31:38
残念
で実際なにがいけないの?
377 :
デフォルトの名無しさん :2007/11/11(日) 09:51:13
何故にポインタが存在するのか。これがわかれば楽勝
俺は第一印象で、途中にNULLがあったらどうするんだ?って思ったが。
コーディングは暗号解読じゃねえんだ
いやぁ、コメントと改行とインデントがちゃんとしてれば 結構普通に読めると思うけど でもこれはポインタの話とは違くねぇ?
>>380 ポインタは普通の構造体に比べてコピーのコストかからないんだから
逐一名前を付け替えたほうが可読性あがるしそっちのほうが良かろう
可読性はポインタには限らないじゃないってことを言いたかった
英検準2級に落ちたああア
中間ポインタを置いたほうが 読みやすいってことなの?
まず中間ポインタって何よ
387 :
デフォルトの名無しさん :2007/11/11(日) 17:59:52
まぁ、C言語だと、短縮した記述とか、複雑なポインタの連鎖をつかって、 「俺、おまえらと違って頭いいんだよ」 と分り難いコードを得意げに自慢げに晒すヤツが けっこう居る
うん
頭が良いことは良いことだ
390 :
デフォルトの名無しさん :2007/11/11(日) 19:10:38
>>388 ,389
ソースコードの読み手が、「このコード大丈夫か?」とか
心配させるようなコード書くようなヤツは頭がいいとは言わない。
ソースコードの読み手が、立ち止まることなく「このコードは
大丈夫」だと確信しながら、スラスラ読めるコードを書くヤツは
頭がいい。
結論としては
>>341 のようなコードを書くヤツは頭が悪い。
たいていの商品は分かりやすさこそ売り物の価値なんだよ。 高齢化社会を迎える日本だと特にそうだ。 戦後の日本文学が、難解であれば崇高だと勘違いして衰退してしまった反省を ソースコードにおいても生かしてほしいもんだ。
同意ではあるんですが 読む人のレベルにもよりませんか?
394 :
デフォルトの名無しさん :2007/11/11(日) 19:52:45
>>392 もちろんプログラマとしての常識は、身につけている
という前提は必要。
常識というのは、言語に関する知識、アルゴリズムに
関する知識、慣用句に関する知識くらいかな。パッと
思いつく限り。
あとは、プログラムが対象としている分野ごとの
知識は前提とするけど。例えば、デコーダのプログラム
のソースコードならば、読み手がそのデコードの
アルゴリズムを知っているという前提をした上で、
プログラムを書くことになる。
でも.Net Framework、SQL、XML、WebServices、などなど…。 色々ありすぎて、「言語に関する知識」「アルゴリズムに関する知識」という定義が やっぱり人それぞれになってしまうと思う。
>>395 それはどれも応用プログラミングの専門知識であって常識ではないんじゃないか。
現場の常識という事はあるかもしれないが、それでは一般論とはいえない。
ある範囲で分野を定義した時にその中の最低限の知識というのがあるわけで、
それ以上のテクニックだかノウハウだかを理由も無く濫用するのが良い習慣でないのは
間違いないだろう。
つうかそんな基本的なところで俺SUGEEやってないで仕事に集中しろよと
べた集中するための遊びだろ。 だいたい1:9ぐらいかな。
オ…オ…オレSugeeeee! …って思うもんさ、プログラマなら…
>>341 はただのポインタ連結だからいいけどさ、
これがC#のプロパティで同じことやられたりしたら、
もう理解不能だな。
401 :
デフォルトの名無しさん :2007/11/13(火) 17:11:27
char dmoji[36][7][7] = { { " ##", " # #", " # #", " #####", " # #", "# #"}, { "##### ", " # #", "##### ", " # #", " # #", "######"}, { " ####", " ## #", " # ", "## ", " ## #", " ####"}, 。。。略・・・
402 :
デフォルトの名無しさん :2007/11/13(火) 17:13:41
464 名前:仕様書無しさん 投稿日:2007/11/13(火) 16:33:04 SEの兄がいつも独り言で死にたいあー死にたいってよく独り言を言ってます そんなに仕事は厳しいんですか? 465 名前:仕様書無しさん 投稿日:2007/11/13(火) 16:35:49 動かないものを動きますと言わないといけないからとか?
宣言に問題あるよな、 最初からそういうもんだと思ってたからあまり考えなかったけど。 int *p, *q; じゃなくて *int p, q; にすりゃいいんだ。
pointer<int> p; こうだろ
>>403 その記法で関数ポインタとポインタを返す関数をどうやって区別する?
>>404 実際、C++だとstd::tr1::add_pointer<int>::typeとか
boost::mpl::identity<int*>::typeとか書ける。
::typeとか冗長だけどうまく使えば便利に思うこともある。
407 :
デフォルトの名無しさん :2007/11/13(火) 21:39:21
const int a = 1; int* p = &a; ってしたら、*pでaの値を変更できる? *&a ってした場合は、どう?
408 :
デフォルトの名無しさん :2007/11/13(火) 21:49:06
すいません、上を少し訂正します const int a = 1; const int* p = &a; ってしたら、*pでaの値を変更できる? *&a ってした場合は、どう?
409 :
デフォルトの名無しさん :2007/11/13(火) 22:10:44
つ const_cast
410 :
デフォルトの名無しさん :2007/11/14(水) 05:54:34
>>408 #include <stdio.h>
int main(int argc, char** argv) //char *argv[]
{
const int a = 1;
const int* p = &a;
printf("a=%d *p=%d\n&a=%p p=%d\n", a, *p, &a, p);
return 0;
}
FreeBSDでの結果
a=1 *p=1
&a=0xbfbff8fc p=-1077937924
411 :
デフォルトの名無しさん :2007/11/14(水) 05:56:03
さらに #include <stdio.h> int main(int argc, char** argv) //char *argv[] { const int a = 1; const int* p = &a; printf("a=%d *p=%d\n&a=%p p=%d\n", a, *p, &a, p); *p = 5; a = 9; printf("a=%d *p=%d\n&a=%p p=%d\n", a, *p, &a, p); return 0; } コンパイルエラー ×2ケ所
412 :
デフォルトの名無しさん :2007/11/14(水) 05:57:54
あ、
>>410 は間違った
最後は%dじゃなくて%p
printf("a=%d *p=%d\n&a=%p p=%p\n", a, *p, &a, p);
FreeBSDでの結果
a=1 *p=1
&a=0xbfbff8fc p=0xbfbff8fc
>>410 あ、何となくわかってきた。
タイプ
ア
ド データ
レ
ス
アドレス*タイプでデータを指し示すから、*pで、データをアドレス&タイプに変換するから、
&aなんだな。
413が何を言ってるのかわからんのだが
>>414 「*」や「&」という変な文字を使う理由について推測しただけ。
&は変数のアドレスを得る演算子 *はポインタの先にある実体を得る演算子 p = &a; は変数aのアドレスをポインタpに代入。 *p = 5; はpに入っているアドレスの先を書き換える処理 というのは理解してるのかな?
ポインタ変数を使うからよく分からなくなるのではないか? longかなんかの変数にポインタを代入して、いろいろやってたら何となく分かって来るよ。きっと。 環境依存だけど。
なぜわざわざ・・・
それやるくらいだったら、 アセンブリ言語使ってみろというほうがずっと有意義。
よくアセンブリ言語薦めるやついるけど、 JavaとかC#とかの高級言語触らせたほうが、どうしてポインタが欲しくなるのかを理解するのにはいいんじゃないか?
421 :
デフォルトの名無しさん :2007/11/14(水) 18:00:35
>>420 JavaとかC#だって、ポインタはあるのだから、欲しくなんてならない。
アセンブラなんてしなくてもC++とXbyakで遊べばいいんだよ
423 :
デフォルトの名無しさん :2007/11/14(水) 18:02:49
ポインタや再帰を駆使したアルゴリズムの本ない?
Javaにもポインタってあるんですか?
>>421 ちげーよ、安全に使えるようになってるから理解しやすいかと思ったんだよ。
ポインタと再帰はあんまり関係なくね?
>>420 アセンブラは良く知らんが同意
>>421 趣味でちょっとしたTCP/IPプロトコルを実装しているんだが
ポインタがないと俺には無理ってぐらいだ
こんなものをC#とかJavaとか他の言語でどうやって書けと(ry
ポインタとmemcpyを使ってソース書くときれいになって読みやすくなってるぞ
C#にポインタはあるよ
C脳から抜け出せてないのやら他言語に疎いのやら
432 :
429 :2007/11/14(水) 18:15:35
どういう点が?
ポインタだけに点
これはいい脱力感
わふ?
438 :
:2007/11/16(金) 00:10:00
アセンブラ役にたたんかもしれんが 理解を深めるには結局は近道だと思われ
ポインタの理解には、メモリとアドレスについて知れば十分。 インストラクションコードの知識が必要になるのは、もっとずっと後。
絶対アドレッシングと相対アドレッシングまで押さえれば完璧
441 :
デフォルトの名無しさん :2007/11/16(金) 09:11:57
//
い・・・いんす・・・とらく・・・?
たー・・・のお・・・ね・・・えちゃん・・・?
444 :
デフォルトの名無しさん :2007/11/17(土) 06:48:29
ハンドアセンブルで COM ファイルを書いてみる。
ORG 100
ハンドアセンブルが許されるのはZ80までだよねー(AA略
全てのものはメモリ上においてあって、位置はアドレスで示せて、ポインタはアドレスを入れる変数、 でいいんじゃね?
ポインタの「型」を忘れるなと何度言ったr
449 :
デフォルトの名無しさん :2007/11/18(日) 12:56:38
?
エスパーのおれが解説を試みてみる
char *cp;
int *ip;
/* いろいろやる */
cp++;
ip++;
の最後の2行の挙動が
>>447 には含まれてないってことじゃね?
なるほど。ご指摘&解析ありがとう。 では447の補足。 ポインタには加算減算が定義されている。加算結果のアドレスがいくつ増えるかはポインタの型に依存する。 intが4バイトの処理系でintのポインタに+1するとアドレスは4バイト移動する。 これはメモリ上の連続領域にかかれたintデータにアクセスする際に便利。 ぜんぜんわかりやすくないな。サーセン。
なるほど。ご指摘&解析ありがとう。 では447の補足。 ポインタには加算減算が定義されている。加算結果のアドレスがいくつ増えるかはポインタの型に依存する。 intが4バイトの処理系でintのポインタに+1するとアドレスは4バイト移動する。 これはメモリ上の連続領域にかかれたintデータにアクセスする際に便利。 ぜんぜんわかりやすくないな。サーセン。
加算減算に触れるのには相対アドレス絶対アドレスみたいなのも理解が必要だと思うけど こういう仕様が表に出ている事のメリットがいまひとつわからない
>>447 厳密に言うとメモリ上にない変数もあるのだ、ふっふっふ。
レジスタ上ってこと? 確かに忘れてた。ご指摘感謝。 まぁポインタの話をするときはメモリ上って事でいいのでは?
いまレジスタってあるの?
あるよ、何言ってるんだ?
458 :
デフォルトの名無しさん :2007/11/18(日) 16:28:51
全然意識したことないや
じゃあ register int i; &i; ってやってみるといいよ。コンパイラに怒られるから。
C言語に register はあるけど、どう扱うかはコンパイラ任せ じゃない?実際任せるしか無いと思うけど。多少配慮は してくれるはずだが、下手するとかえって遅くなる場合もある。 CPU 上の話はまたそれはそれで違うよね。
レジスタ増えすぎだし人間が管理するより任せた方がいいわな 高級言語でわざわざ意識する機会なんてまず無いわ
462 :
デフォルトの名無しさん :2007/11/18(日) 17:50:14
registerなんてもう10年位使ってない
ま、今時register修飾なんか無視するコンパイラがほとんどだよね。 ただしアドレスだけは取れないようになっている。
そういえば俺も 10 年以上前にどの変数を register 宣言すると速くなるか、 とか一所懸命自分のコードで調べてた覚えがあるな。けどもうずっと使って なくてコンパイラ任せ。
registerを使わなきゃならんような場面、今後はもうないだろうね。 少ない資源で必死に高速化してた頃が懐かしす。
組み込み系ではまだ、たまに使う場面あるけどね。
regster使うくらいだったら、自分がアセンブリ言語で書いたほうがいいと考えてしまう。
&使わないループ変数には付けときゃいいんだよ。 レジスタが空いてないなら勝手に使われないだけなんだから。
そういうど素人なコードは書きたくないなあ。 組み込み系だったらつけるのはわかるけど、 それ以外だったら間抜け以外の何物でもない。 下手したらオプティマイザーを混乱させてかえって遅くなることもあるし。 つっても今の処理系だったらみんな無視するだろうから大丈夫とは思うけど。 なので場所を弁えずregister修飾入れているやつはど素人。
>>468 逆!逆!よっぽどの理由がない限りつけないのが普通だってば
471 :
デフォルトの名無しさん :2007/11/21(水) 18:50:12
アドレスを取られたく無い時ぐらいしか思い付かん
アドレスを取られたくない時ってのが思いつかん
gnuのソースなんか付けまくりだぜ
太古のソースを後生大事に保持してるからねえ
今時のコンパイラなら謹んで無視するだろ。
C++ならregister変数でもアドレス演算子が使えた気がする。
最適化なんてコンパイラにやらせときゃいいのさ。 いろんな環境に移植するソースで、いちいちregister付けたり 外したりなんて馬鹿らしくてできん。
478 :
デフォルトの名無しさん :2007/11/25(日) 13:08:45
Cでヌルポが(void *)0ってマクロ定義される理由が分からん。 C++では、「ヌルポを(void *)0って定義してはダメ」って記述されてる 本があるけど、その理由も分からん。 結局、ヌルポは、どう理解しておいたらいいのだ? Cでは、ヌルポの型は、(void *)なの? C++では、ヌルポの型は、なんだ?
C++の本の方は(void *)型の話じゃなくて 0がダメって言ってるだけじゃないの? C自体も0とは定義してないはず 型は・・・どうなんだろう 強いて言えばvoid *型な気がするけど
NULLは0じゃない。0がNULLなんだ。 この法則に則って考えれば、NULLはCでもC++でも0と定義されるべきであり、それ自体は8進定数と言うことになる。
>>478 の論点は「型は、なんだ?」だと思うが・・・
ちなみになんで8進?
ポインタくらい簡単なものが一般的に「ポインタが難しい」とされてるおかげで、C始めたばっかの人が「ポインタが理解できません」と言ってくれるので(難しいとされているので躊躇せずに言いやすい?)面接のときのモグリ排除に大いに役に立っている。
それを考えて新人に特別な扱いせずに 普通に変わった変数としてポインタ教えてたら やっぱり2年目になっても分かってなかった
0で始まるから8進数。
ポインタって精々理系にとっての微分積分程度のレベルでしょ
486 :
デフォルトの名無しさん :2007/11/25(日) 14:21:10
16進は0から始まりませんか?
微積分マスターよりポインタマスターの方が数段楽。覚えなきゃいけない事項の絶対量が少なすぎる。
ポインタって何を覚えるんだ・・・
ポインタ(の存在意義)がわかりませんって面接で言ったらなにがわからないのか聞いてくるから とくとくと語ってみたら面接官涙目になってた。
面接官って技術者の人やってんのかー ウチの会社は総務だか人事だかがやってたなぁ・・・
ポインタがわからないって、ものごとの裏側(仕組み)が どうなってるのか少しも考えてこなかった証拠じゃね? コンピュータの中で関数がどうやって呼び出されてるのとか、 変数はどうやってわたされてるのとか、 時計の針はどうやってまわるのとか、 えんぴつとか棒付きアイスはどうやってつくるのとか 普通は自分なりに考えてみるものじゃん
赤ちゃんはどうやっ(ry
>>492 そうやって裏側の裏側の裏側の……って調べていくとキリがないので、
あるところで計算を打ち切ってcall-by-needで遅延的な思考をすることだってあろう。
そのためにいろんな学問やら処理系やらは多層構造になってるし、
インターフェースが決まってれば実装が見えなくたってかまわないんでしょうよ。
コンピュータをやるなら最低でもアセンブラとかマシン語が云々、とかいう人はそこが分かってない。
このスレポインタスレだからしょうがないかと思っていた
アセンブラ出身の俺からみてポインタはなんであんな面倒な仕組みなのか理解できないよ。
おっちゃん乙
>>494 違うんだ
具体的な仕組みを正確につきとめるというより
少なくとも自分のなかでつじつまが合うように
モノゴトの裏側を想像するってこと
抽象化して考えることが出来る奴は、少なくとも
具体の一例を想像して挙げてみることができると思う
合理的に考えられる奴ならポインタのおかしさ、不自然さに気づくだろうよ
>>478 ぬるぽは、あらゆるポインタ型について存在する。
int*のぬるぽ、void*のぬるぽ、char*のぬるぽ、void(Foo::*)(void)のぬるぽ・・・
定数「0」は任意の型のぬるぽに暗黙に変換できるので、NULLマクロを0と定義しているのは妥当。
単なる0でなく(void*)0と定義してる場合もあるが、その理由は、単なる0は整数型にもなるので、
char c = NULL;
と書くバカがしばしば現れるため。
(void*)0は整数型としては通らないので、これで一応そういうバカを少しは防げる。
Cではvoid*はあらゆるポインタ型に暗黙に変換できるので、これでも特に問題はない。
C++ではvoid*の暗黙の変換が無くなったので、(void*)0をNULLの定義には使えなくなった。
つまり例えば
int *p = (void*)0;
というのはCでは通るがC++では通らない。
>>486 16進定数は0xで始まらないといけないので、数値0をあらわすには0x0とする必要がある。
kwsk聞いたら宣言の話だった、というのは無しにしてほしい。
8進の0って表記では00じゃないの?
どっちでも一緒だからどうでもいいよ、ポインタと関係ないし
世の中にポインタと関係ないものなんてないよ
Javaにはポインタは存在しないのに なぜ NullPointerException が出てくるんですか?
語呂がいいから
JavaにポインタがないこととJavaVMにポインタがないことは別だから。
ポインタがわからないという概念がわからない
概念は分かるけど、使い方が難しい、使いどころが分からないってことなんだろう多分
同じことをするのに何通りも方法があるのが混乱のもと。
だから、バカ用言語のjavaが出来たのだよ
Javaは単に見えなくしてるだけじゃないのか?
Javaは全部ポインタなのさ。
プリミティブ型はポインタがない。 かつ、オブジェクトでも明示的なアドレス演算ができないという意味では ポインタとしては不完全。
519 :
デフォルトの名無しさん :2007/11/27(火) 21:33:49
ぷ・・・ぷれみあむがた?
アドレス演算なんかあってもしょーがない
しょうがないというかJavaにはその概念がないんだからできなくて当然だ。
できないからやれないのとできるけどやらないのとの間には越えられない壁がある
できないけどやるやつが始末悪い
言語仕様上可能だからってやるやつも始末悪い
Cでは明示的なアドレス演算がないとプログラムが書けないだけのこと。
Cを10年やってきた俺が断言しよう。 ポインタのないC#が理想系にもっとも近い。 C++のように氾濫するライブラリを使いこなすためにキャストの嵐もないし。
俺もそう思うー
C++を10年やってから言ってください^^
aho
C++も2〜3年はやってるがこんな扱いづらい言語はないよ。 自分で一から作るならいいけど、実際の現場じゃ色んな人が触ったソースも 見なきゃならないわけで、当然のように色んなライブラリが使われてる。 次から次へと覚えることが多すぎてヘボな俺の頭はついてけないぜ。 あとC++は文字列だけを見てもCString、std::string、System::String*、TCHAR*、WCHAR*、 CAtlString、BSTR、CComBSTRなどなど。おぞましいほど多様な形態がある。 C#だと、ほぼstring型で統一されてるだがなぁ。 C++は使い古されてもうカオス状態。言語としては何でもできる良い言語だけど 俺はもう嫌だ。ボスケテー
>>おぞましいほど多様な形態がある。 それはC++のせいではない。 そこの区別がつかないようでは(略
CLI(笑)
C++は
その中でC++の文字列型と言えるのはstd::stringだけじゃねぇ?
まぁ C++ は歴史も引きずってて自由でやり放題だからな… 自分でさらっと書くのには Java とかより楽で好きだけど、 他人のコードには手を入れたくないな。
おまえのも他人からそう思われてるよ 自分のが一番綺麗だと思ってるうちはまだまだ未熟
そういうカオス領域の扱いに長けているのがC++だと思っている。
>>536 別にきれいだと思っているとは書いていないよ。勉強して努力はしているが。
できるだけ自分で責任を持って直したいと思ってる。
539 :
デフォルトの名無しさん :2007/11/29(木) 22:36:54
ポインタと関係ないですが
趣味でオナニープログラムして楽しむならC++だな。 仕事では、使いたくねぇ
>>539 ポインタを語るスレではないからな
そもそも学びたい奴がいないならこのスレいらんだろ
ポインタがわからんやつとかいないじゃん
ポインタをどうやって学ぼうかってスレなんだから ポインタわかんない人も来るだろw
ポインタ勉強中でなんとなく面白くなってきた 関数は常に値渡し 参照渡しでも結局はアドレスと言う値を渡してるに過ぎない って認識であってる?
うん
545 :
デフォルトの名無しさん :2007/11/30(金) 19:29:27
C言語は値渡ししかできない、でいいんですよね?
今更Cやポインタなんて勉強してるやつはバカだろw 言語なんて勉強する意味がない。 コーダーは中国から買ってくれば良い
547 :
デフォルトの名無しさん :2007/11/30(金) 19:38:14
そうして中国に追いつかれることに気付かない日本人。 私は自分のためにCやポインタを勉強する。
お前がバカなんだっつの
まともなコードが書けない奴が、まともな設計できるわけねえし
他にも勉強する事が多くてなぁ・・・ まともなコードが描ける頃には髪の毛白くなってそうだよ
コード書きは全てに優先するんだよ 無知か?おまえ
なかなか粗悪な暇の潰し方だな
職人みたいに低能頑固薄給視野0になりたければ コード書けばいいと思うがなw コーダーなんてインドから集めてくればいい
コーダ以外コード書く必要ないと思ってる化石か
マ板でどうぞ
GoogleやMSの社員もコード書いている件について
マネージャクラスでもな
それが普通
じゃあなんで日本のマネージャクラスはコード書かないのが多いの? なんで日本の文化ではコード書きは底辺がすることって信じられてるの?
typedef void* NULL; #define NULL 0
>>559 それが一番妥当かつ効率性が高いとう結果
なんだよ。結局コードなんて書いても成果を
出しましたって小細工しているにすぎないからな
日本語で
>>556-558 書くモノしか見てないけど Google とか技術部いい感じだよね。
Norvig さんとか。
いい感じじゃねーだろ
英語身に着けて外国でもなんでもいけばいい。 コードも書けない奴の言うことなんて誰もきかない。
視野が狭すぎてすげーなw
昔と比べてコードの抽象度が高いから、自然言語を使う必要性が減ったってことでしょ コーダにコーディングをアウトソースするときに、インプットとして「コード」が必要になったってこと 昔と大して変わってない
今日帰りにインド人がやってるカレー屋に行ったんだけど、 カレー注文したらスプーンがついてこなくて 「あ、本格的な店なんだ」とか思って手で食ってたら、 半分くらい食ったときに、インド人の店員が奥から すげー申し訳なさそうな顔してスプーン持ってきた
570 :
デフォルトの名無しさん :2007/12/04(火) 15:03:58
>>128 が改悪したようにしか見えない件についてw
うおおぉぉ! Javaばかりでプログラム組んでいてC++にに戻ってきたらメモリ管理だるすぎて泣きそうだw Javaはメモリ管理が楽だからいいよな よくC#、Javaはポインタがなくて良いとか言う奴いるけど、これらの言語の利点はメモリ管理の楽さだろと突っ込みたいぜw それにC#、Javaはむしろポインタの固まりだしな C++のメモリ管理の経験があると、ガーベジコレクション等に負担をかけず高速なプログラムを組めることが身に染みてわかったぜ、自動解放だからってテキトーに組むとメモリリークは発生しないにしろ遅いなw 結論、C++のようなメモリ周りがシビアな言語をやる価値は今でも十分すぎるほどあると
C++ならスマートポインタ使えばいいのに
違う違う。 C++ならスマートポインタ実装すればいいのに
俺は、自分でメモリ管理しないと、不安でしょうがない。 JavaやC#だと、本当にリークしてないのか不安になってたまらない
aho
GUIでガベコレの遅延がはっきり感じられるとつらいね 元々もっさりなのに時々かくかくではストレスもたまる
なんでそうなるコードを書くの?
リソース管理が自動化されてる言語しかやったことがない、とか
580 :
デフォルトの名無しさん :2007/12/13(木) 16:16:38
int array[10]; で&arrayってvoid*?
int**
自己レス
int (*)[10]か。
>>581 あれ?それでもいいの?
試してみます
583 :
デフォルトの名無しさん :2007/12/13(木) 17:13:53
配列のポインタと、ポインタのポインタを間違えるな
584 :
582 :2007/12/13(木) 17:24:09
int**はダメだた・・・
585 :
デフォルトの名無しさん :2007/12/13(木) 17:32:46
>>572 俺にはC++のメモリ管理がだるいと感じるお前が理解できない
new したらdeleteすればいいだけじゃん
なにがだるいんだか・・・
それがだるい。
>>580 配列名だけで先頭要素のアドレスになる。
ただし、それは変数じゃないので&を付けても無駄。
int array[10];
printf("%p¥n", array);
printf("%p¥n", &array);
で試してごらん。
>>586 よきにはからえ、じゃないと駄目だよね。
ゆとりプログラミングの時代さ。
>>588 arrayは配列の先頭要素へのポインタ
&arrayは配列へのポインタ
だから値は同じだけど意味が違うんじゃないですか?
>>589 コンパイラ使うのも似たような言葉で馬鹿にされたものだけどね。
>>588 違う。
arrayはポインタでは「ない」。
ポインタは変数。配列名は定数。
単にarrayと書いたときに「どう解釈されるか?」の話じゃないの?
アレーイ?
アルェーイ?
596 :
デフォルトの名無しさん :2007/12/14(金) 10:44:32
配列とポインタは違うのに同じだ、 と言うニュアンスでK&Rで解説されたために、 その後のC言語の入門書で、 よく分ってないヤツがゴチャゴチャにして説明するようになって、 今に至る
基本的に違うけど引数としてはどっちでもとれるって状況 だと思うが引数として使うってのが けっこうメジャーな使いかたなためごっちゃになってるって 状況だとおれは認識してる。
>>597 >基本的に違うけど引数としてはどっちでもとれるって状況
間違い。
引き数としては、常にポインタ。
# 但し、Cの場合。
学校で課題で「配列とポインタの違いを説明せよ」みたいなのあったなぁ・・・
>>585 自分がnewしてdeleteするなら別に面倒では無いだろうけど
リスト構造でなおかつ、その構造が要素追加にnew、削除にdeleteを使うようなプログラムはが何万行と続くとデバック作業がかなり面倒だろ?まあ、それはそれで利点もあるがな
それを面倒臭くないというお前はすごいな、それとも極小規模なプログラムしか組んだことないのかな?
>>599 配列は箱を列に並べたもの
ポインタは矢印
でいいかな?
602 :
デフォルトの名無しさん :2007/12/14(金) 18:43:34
>>601 大学のレポートって、お絵かきでOKなの?
>>598 そういうことじゃなくてポインタ変数でも配列変数でも
代入できるだろうって意味。
住所そのものと住所を書いた紙が別なのは当たり前だろが 住所そのものを変えるには市町村合併でもするほかないが紙に書かれた住所を書き換えるだけなら簡単
>>604 なんかオブジェクト指向の例え話なみに微妙な話だな
たとえ話に住所って言葉を使うのが間違ってそう
ポインタなんて [C言語 ポインタ完全制覇] 読んで理解したなら 後は、実践を繰り返すだけだろーよ
どんなに微妙でも人間の脳構造はアナロジーの利くものの方が 覚えやすくできてんだからそれでいいじゃんよ。
>>609 配列の不完全型ってヤツか?
良く分からんが、違う構造体同士で相互参照する時なんかに使う
構造体の不完全型の親戚みたいなもんかな
611 :
デフォルトの名無しさん :2007/12/15(土) 02:27:42
VC++ExpressEdition d:\work\vc\array\arrayptr.cpp(9) : error C2440: '=' : 'int (*__w64 )[10]' から 'int (*)[]' に変換できません。 指示された型は関連がありません。変換には reinterpret_cast、C スタイル キャストまたは関数スタイルのキャストが必要です。
613 :
デフォルトの名無しさん :2007/12/15(土) 04:19:56
Cより先にアセンブラやれ!! アドレスの概念を理解しないでいきなりやるから 難しくなるんだよ!!
それも極端な話だなあ、と思う反面確かにそれが近道だよなあと思っているおれがいる
ちょっと疑問なんだが、配列自体が先頭のアドレスを示しているのに、 さらにそれのアドレスが欲しい場合ってどういうケース?想像つかないんだけど。
616 :
デフォルトの名無しさん :2007/12/15(土) 10:40:49
こんな感じなら理解できるか? #include <stdio.h> #define N 5 void aryfunc(int ary[N][N]) { int *temp; for(temp = &ary[0][0]; temp != &ary[N-1][N]; temp++){ (*temp)++; } } int main() { int ary[N][N] = {{1,2,3,4,5},{6,7,8,9,10},{11,12,13,14,15}, {16,17,18,19,20},{21,22,23,24,25}}; int *temp,i; for(temp = &ary[0][0],i = 1; temp != &ary[N-1][N]; temp++,i++){ printf("%d ",*temp); if(!(i%5)) putchar('\n'); } aryfunc(ary); for(temp = &ary[0][0],i = 1; temp != &ary[N-1][N]; temp++,i++){ printf("%d ",*temp); if(!(i%5)) putchar('\n'); } return 0; }
>>616 添字でアクセスできるのに、わざわざポインタつかってわかりにくくしてる気がするんだが。
↓と同じことでしょ?
void aryfunc(int ary[N][N])
{
int i, j;
for (i = 0; i < N; i++)
{
for (j = 0; j < N; j++)
{
ary[i][j]++;
}
}
}
>>615 配列の配列とか、配列の配列の配列とか、つまり多次元配列を
関数の引数として渡すときに必要だな
>>615 配列名は、配列の「先頭の要素」のアドレス。
配列名に&をつけた場合は配列「そのものの」のアドレス。
ポインタの値としては同じ値だが、意味が違う。
なんか思い違いをしてる気がするぜよ
620 :
615 :2007/12/15(土) 12:48:40
>>618 多次元配列も、型と先頭アドレスと要素数を何らかの形で渡せばいいわけだから、
アドレスに関しては配列名のみを渡せばいいんじゃないの?
>>619 意味の違いは理解してるつもりだが、これじゃなきゃできない、というケースが思いつかなくてさ。
先頭の要素のアドレスと、配列そのもののアドレスが違うことがあれば理解もできるってもんだが…
&つけようがつけまいが 値同じだから意味は同じ しょうもねー議論してるんじゃねーよw
そんな乱暴なw
>>621 おまい、ポインタはvoid*さえあればいい派だなw
void *と void **あれば何もいらねーだろ。 型に束縛される書き方してると 汎用性失う言語だし 携帯のドライバなんかは int Inithoge(void * data1, void *data2, void *data3) こんなの普通だぞ?
携帯用のドライバなんかどうでもいい
>>627 関数の引数は常にポインタしかとらない。
字面上配列の形をしていても、そいつはポインタだ。
だから、
void foo(char *pa[]);
void bar(char **pp);
char aa[10][10];
という関数と配列の配列があったとして、以下の呼び出し
foo(aa);
bar(aa);
のどちらも違法(コンパイラが怒る)だ。
これが「配列の配列は、ポインターへのポインターへ成り下がることはない」の意味だ。
ちなみにmainに渡されるargvはポインタの配列であり、これはポインタのポインタで受けられる。
argvがポインタの配列だから void hoge(char str[])を void hoge(char *str)と書けるのと一緒で int main(int argc, char *argv[])を int main(int argc, char **argv)って書くのは全然おかしくないわけか。 むしろ後者の方が実際にやっていることとイメージが近いな。
const char* const argv[] って書きたいところだけど
ポインタの配列と、配列の配列の違いを、 いくら説明しても全く理解できないヤツ、 会社に一人くらいいるよな・・・ プロのプログラマーのはずなのに
・ポインタを「何かを指している矢印」 ・配列を「何かが入っている箱」 という図を描いてみて、その上で配列の配列とポインタの配列を描いてみればすぐわかると思うんだけどな。
>>631 専門書籍で使われてる言葉をそのまま使っても伝わらないよ
一度日本語に直す、相手に伝わる言葉に直す
そういうリファクタリングを繰り返してバカ矯正プログラムが完成するんだ
ダブルポインタと呼ぶのはやめてほしい
図ばかり頼りにして、言葉を大事にしないのは、理系プログラマの欠点だ
文章から何かをイメージする能力が読む側に備わってない 理系文系だ関係なく読解問題が苦手なの増えてるだろ? だからこっちでイメージを用意してやりようやく相手が理解できる マンガと同じだわ
そうゆうこと 嫌韓を読めばよくあの国が理解できるのと一緒
嫌韓って漫画じゃねえよあれ。カット集じゃん 全編挿絵っつうか
マジレスすること自体 ゆとりだと自己主張しているものだな。 このスレ削除でよくねーか?
時々思いがけない議論があってちょっと楽しいから 削除しないで放置しておいて欲しい
マジレスでもなんでもないだろw どんどん話題が枝葉にそれてるだけで
まず、学ぶべきことを定義するのが先じゃないか? アドレスの代入、アドレスが示す値の参照 関数へのアドレス渡し ポインタを利用するアルゴリズムを理解 こんな感じでさ
レス600過ぎてから定義されてもwww
老いて益々盛んってことわざもあるし 人生に手遅れって言葉はないと思うんだ
645 :
デフォルトの名無しさん :2007/12/17(月) 04:57:57
w w
図に書いて説明するより、ソースレベルデバッガでポインタ変数にどんな値が入って、 その値が指すアドレス(とその前後アドレス)にどんな値が入ってるのか 見せた方が分かりやすいと思う。
>>646 ポインタの実際の値がいくつなんて、
どうでもよいことじゃね?
ポインタをsizeofすると正体がわかるよね 32bitの処理系なら型に限らず全部4だし
>647 いや、そういう正体のつかめ無さが、初心者には分かりづらいんじゃない? まずは抽象度を下げて、具体例から入った方がいい。
>>648 ただそんなことに頼っていると書いているコードがしばらくたって
使おうと思うと動かなくなる。
ポインタは単純だ for (int i = 0; dst[i] = src[i]; i++); がポインタのおかげで for (; *dst++ = *src++;); できるだけだ
あまり違わない気がする・・・
つか、C++使い始めてからポインタなぶるなんて中々無くなったわ
関数での受け渡し以外にポインタなんて使う?
mallocなどで確保するときに使うよ
文字列だってポインタじゃん
>>654 自己参照型構造体使ってないのか?素人さん?
玄人さんがお見えになったぞ!
ポインタ使うのに、玄人も素人もない
グローバル変数の初期化順序が保証されてないから、初期化順が重要な グローバルオブジェクトはポインタだけ定義しといて、初期化関数で順番に newしていくとか。 (順序が重要なオブジェクトをグローバルにすることの是非は置いといて)
>>654 オブジェクトいろいろ弄る時に使うよ。入れ替えたりとか便利。
コールバックするのにつかうー longjumpするのにも使う
もう「無いと困る」でいいんじゃね?
>>657 データ格納するならデータベース使わね?
組み込みなら、一時的な(親機に渡す日次処理で消えてしまうよな)データの格納に使ったりするけど
今は組み込みもDBの採用が進んでるし
それとこれとは話が違う・・・
話が違うというか、本物が来ちゃったようだ・・・
667 :
デフォルトの名無しさん :2007/12/19(水) 02:37:02
ポインタ使って2−3木を作りたいと思っているのですが ここを見ればおkていうサイトとかありませんか?
データ構造とアルゴリズムを扱った書籍を買った方がいいと思うね
てか作ればいいじゃん
自己参照構造体というのを試してみたんだが、メモリの開放が面倒そうだ。 自分を指してる一つ前の構造体のアドレスってどうやって取得するの? 元々そういう風に構造体を作らなきゃダメ?↓みたいな感じで。 typedef struct tree { struct tree *prev; struct tree *next; int x; } tree_t;
駄目
自分は初期の頃はtree->next->nextでNULL見つけてtree->nextを解放したら, tree->nextをNULLにする.ポインタ最初に戻してまた上から見るみたいなことやってたw 双方向だとその辺ずいぶん速くなるよね.
>>672 うん,いまは順方向だけの場合そうやってる.
順j方向リストの場合サーチかけてるポインタじゃなくて
その次に対して操作すると一つ前のアドレスはサーチかけてる
ポインタそのものになるということをいいたかった.
675 :
デフォルトの名無しさん :2007/12/19(水) 12:56:15
おまいら、1方向の線形リストならもっとうまい手があるだろうが。 あるノードを消す場合は、その後ろのノードを消すノードに上書きして、 後ろのノードをfreeするんだよ。
一方向の線形リストなら「上書き」って必要ないでしょ 消すノードの前のノードと後ろのノードを繋げてから 対象ノードをfreeすればいいんじゃないの
678 :
676 :2007/12/19(水) 17:39:23
1方向って*prevがないやつか ごめんなさい
おれ677だった ごめんねごめんねごめんね
>>679 許すからキニシナイ。
真面目な話、あるノードを消したければ後ろのノードの内容を上書きして後ろの方の
ノードを消すなんてのは一方向線形リストを扱う時の基本的なアルゴリズムだよ。
先頭からまた検索するなんて、無駄無駄無駄〜!
じゃ、あるノードの前に新しいノードを追加する時はどうすれば無駄がないか
考えてみそ。
ポイントを押さえて学ぶべき
2次元配列を渡すときに大きさが分からなくて void hoge(int array[][SIZE])見たいな書き方ができないときは void hoge(int* array[])か void hoge(int** array)で書くしかない?
動的確保してポインタへのポインタで渡す
動的静的関係なくね?
渡す側がサイズを知らないってどういうこと?
よくあること
>>682 また、ポインタと配列がゴチャゴチャになってしまって分からないヤツがきたな
受け取る側が渡す側からサイズを教えてもらえないと、2次元として扱うのは無理なのだが
番兵くんがいればそうとも限らない
もう、なんでもかんでもvoid*で渡して、 後は、渡されたほうの関数の中で好きにすれば、 なんでもOKだ
691 :
682 :2007/12/19(水) 20:46:15
int sum(int** array,int i_size,int j_size){ int sum=0; for(int i=0;i<i_size;i++) for(int j=0;j<j_size;j++) sum+=array[i][j]; return sum; } a[3][4],b[10][20]が宣言されてたとして、 上の関数ならsum(a,3,4)もsum(b,10,20)も実行できるけど *じゃなくて[]を使おうとすると大きさ分からなくて困るじゃん… と書こうとしたんだが、静的配列じゃ動かないのなこれ。 いろいろ勘違いしてたすまん。
malloc()したときに確保した要素数わかってるんだから、 それを関数に渡せばいいだけだと思うが。 要素数を教えないで、どうやって終端を認識するの?
void hoge(int **ary, int m, int n) { /* ごにょごにょ */ } int main(void) { int **ary; int m, n, i; /* m, nに配列長を代入 */ ary = malloc(m * sizeof(int *)); for (i = 0; i < m; i++) ary[i] = malloc(n * sizeof(int)); return 0; } こういうことじゃないの?
配列でもポインタが扱える では無く、むしろ 配列はポインタで処理される と考えるんだ
つか、STL使えよって話だよな
OTLもなかなかいいよ
ポインタの壁に挫折した人みたい
いろいろ書いて実行してみること。 アセンブラしてたからかな?すぐ理解できた。
今からポインタ学ぼうって人が「じゃあアセンブラからやろう」って思う訳が無い
アドレス変換テーブルの話なんか聞かされて よけいわけわからなくなっちゃったような奴なら じゃあアセンブラからやろうと思うんじゃないか
やる気さえあればすぐ覚えられる 最長でも1日悩み抜けば覚えられるレベル 厄介なのは、すぐ意気消沈してしまう性格
702 :
デフォルトの名無しさん :2007/12/22(土) 03:07:15
** をポインタのポインタなどと訳する事で余計に初心者の理解を妨げてるように感じる。
じゃあなんて
ポインタ(変数|オブジェクト|インスタンス)へのポインタ
ようするにポインタへのポインタじゃないか
pointer to pointer 「の」は適切じゃないかもな
707 :
:2007/12/22(土) 11:26:53
ポインタ変数を型とするポインタとか
toに引きずられてるアホども
ポインタとポインタでいいじゃん 2こ仲良くていいじゃん
int x = 1, *px, **ppx; px = &x; ppx = &px; printf("%d %d %d", x *px, **px);
>>711 いいたいことは判るが
> printf("%d %d %d", x *px, **px);
printf("%d %d %d", x, *px, **ppx);
「ポインタのポインタ」と聞いて、その本質と真意を理解できないおまえらは、頭悪い。 100の言葉をもって、最初から最後まで全てを語りつくさないと理解できないのか?
初心者にとっては解りにくいって話が、どうしてそうなる?
それは誤解 言葉がわかりにくいんじゃないんだよ
char *cp; を「charのポインタ」って言うんだから、 void **pp; を「ポインタのポインタ」って言ってもいいじゃないか。
うん
俺char *は「charへのポインタ」と言っているよ。
>>717 ポインタ=何かを指す=指向性のあるもの。よって、
char *cp は「char型へのポインタ」
void **pp は「void型へのポインタへのポインタ」
うん
>>720 それでもいいけどね、「へ」は無くてもいいんだよ。
俺も意識して 「〜のポインタ」とか「関数ポインタ」とかじゃなくて 「〜へのポインタ」って言ってる
それでも通じるからいいんじゃね
「へ」は重要だ。「へ」があることによって、何かを指してると認識できる。 「〜のポインタ」だけだと意味が通じない。 …ということを言いたかった。
いや「へ」はなくても通じるんだよ
そもそもポインタって何かを指すものじゃん
初心者にとって、という話だろ?「へ」はあったほうがいいよ。 既に理解してる人にはどっちでもいい。
初心者にとっても有っても無くても同じ。
じゃあvoid ***pppはなんていうの? char ****cpppはなんていうの?
そんなものは出てきてはいけないw
___ ━┓ / ―\ ┏┛ /ノ (●)\ ・ . | (●) ⌒)\ . | (__ノ ̄ | \ / \ _ノ /´ `\ | | | | ___ ━┓ / ― \ ┏┛ / (●) \ヽ ・ / (⌒ (●) / /  ̄ヽ__) / . /´ ___/ | \ | |
「への」に1票
735 :
デフォルトの名無しさん :2007/12/22(土) 22:39:37
>>731 void ***pppやchar ****cpppなんて使う機会ない
へ へ の の も へ
>>731 初心者がそんなもの使うかアホ
極論に持って行こうとするなよボケ
ダブルポインタでええやん。
じゃあダブポで
ゾッ
**のまま使ってる時点でほとんどクソコードだろ。 ふつうtypedefにするかstructにいれる。
いやいや、ある構造体の領域をヒープから確保する関数の場合とか、 **を渡した方が自然な場合もある。
どうせならデュアルポインタのほうがかっこよくね?
クアッドポインタにオクタポインタっすね
ポンタでよくね?響きが萌える
ポイポインタ
つ[*&]
ポインヨ
ツインポインタ
ポインポイン
ポインティングゥー!ポインタァー!!!
日本語でいいだろ。「二次ポインタ 」
「ポインタ」も日本語にしろ
刺す人
そういわれればポインタの日本語訳って見かけないね イテレータは反復子と訳されるのに
じゃ、「二次指示子」
ポインタの和訳は…そうだな…「オブジェクトリファレンス」ってのはどうだい?
参照じゃねーかw
その前に突っ込むところがあるだろw
761 :
デフォルトの名無しさん :2007/12/27(木) 07:59:20
ポインタはウルトラマンセブンに出てくる乗り物だよ
ウルトラマンのやつは「ポ↓イ↑ン↑タ↓ー↓」 コンピュータ用語のほうは「ポ↑イ↑ン↓タ↓ー↓」
違うだろ。
764 :
デフォルトの名無しさん :2007/12/27(木) 16:35:25
和訳なら矢印だな
int *ip int* ip ptr<int> ip 1番目より2番目の方が、2番目より3番目の方がわかりやすいと思うんだけどどうよ。
どうといわれても
ポインタ宣言子と間接参照演算子が別の記号だったら混乱起こさなかったのに。
C++のスマートポインタはその点で気が利いてる。 Cだと表現しようがないんだけど。
いまさら宣言の記法に注文つけてどうなる。
770 :
デフォルトの名無しさん :2007/12/27(木) 20:27:21
宣言の記法に注文付けたい奴は typedef int* intptr; とでもしやがれってんだ。 こんな事してるソース見たことはないが でもwin32apiのソース読むと typedefしまくりで、あんぐりする。
int* p, q;
int q, *p;
これと
>>771 が等価ってのはひどい。
>ポインタのポインタ ハンドル…。
>>773 昔のMac以外にそういう呼び方をする流儀ってあるのか
>>774 別に流儀じゃなくて、一つのメモリ管理モデルとしてあるわけで。
(MacOSに影響受けているから当然と言えば当然だけど)PalmOSでもハンドルで管理していたし。
776 :
デフォルトの名無しさん :2007/12/29(土) 12:23:49
string使えはええやん。
は?
CPUエミュレータ作るとき、関数ポインタの配列を使いまくった。
クラスのメンバ関数の宣言にvirtualを使用すると関数ポインタになる件に関して クラスの変数の初期化が面倒だからmemset(this,NULL,sizeof(*this))でうっかりvirtualを含むクラスを初期化してしまうと実行時エラーにw
あたりまえやん
>クラスの変数の初期化が面倒だから そういう用途にはmemset使うなってエロイ人が言ってたよ。
memsetなんてもうずーっと使ってないなー
>>779 >memset(this,NULL,sizeof(*this))
ここでNULL使うのはおかしくね?
そもそもmemset()使うのがおかしいからどうでもいいよ。
構造体単体でもmemsetする奴は危険だよ
別にmemsetそのものは危険じゃないよ。
する奴は って書いてある
うん、そうだね。書いてあるね。 でもそんなことは関係なしにmemsetそのものは危険じゃないよ。
ポインタと全然関係ない話題ですねw
struct A a; memset(&a, 0x00, sizeof(struct A)); もう馬鹿かとw こんな後に if( a.hoge != NULL) とかやってる奴ちょっと来い ぬっこしてやるから
勝手にすればぁ〜
局所変数の初期化って不要なの? struct { int a; int b int c; } data; struct data; data.a = 0; とやったとき、bとcには何が入っているのか確定してる?
もちろん不定
>>793 スレ違い。まぁ、そもそもコンパイル通らないだろうからどうでもいいけど。
構造体を初期化するのにmemset()を使わないなら、memset()なんて何に使うのさ? そもそもゼロクリアなんていらねーよ、って話?
>>796 そもそも NULL == アドレス0 って保証はないわけなんだが
>>797 メンバにポインタが含まれる構造体の話か。でもそれなら、
struct DATA data[10] = {0};
という書き方も正しい保障は無いということになるよね。どうすりゃいいの?
={0} は正しい。memsetでゼロクリアするのとは異なる。
>>800 void *p = 0;
などとしたとき、p はアドレス 0 を指すわけじゃないぞ。
定数 0 は処理系依存のヌルポインタのビットパターンを作り出す。
struct DATA data = {0}; は、構造体 DATA の各メンバを
定数の 0 (ビットパターンが 0 なわけではない) で初期化するから、大丈夫だよ。
釣られすぎ
なるほど、釣りだったということにしたいわけか
ヌルポ インタ
今はVSでクラスなんかをガシガシ使ってるから使わないけど、 一昔前にUNIXで開発してた頃はstructでデータ構造を設計して、 使用時には memset(&data, 0x00, sizeof(data)); などのように初期化してから使う、というのが常套句だったよ。俺は。
はい、スレの皆さん
新年特別DQN
>>806 入りました〜
かわいがってやってください。w
808 :
806 :2008/01/14(月) 17:20:45
■データ構成 #define DATAMAX 255 struct { struct { int code; char name[16]; } table[DATAMAX]; } data; ■初期化 memset(&data, 0x00, sizeof(data)); ■DB等からセット for(i=0; i<DATAMAX; i++) { data.table[i].a = a; data.table[i].b = b; } ■取得関数 char empty[16]; char *getName(char *code) { for(i=0; i<DATAMAX; i++) return data.table[i].name; return empty; } ■使用 strcpy(name, getName(code));
809 :
806 :2008/01/14(月) 17:21:05
>>807 かなりはしょってるが、上のレスのようにやってた。
DQN?俺がDQN?
他人に頼らず、テメーだけの力で批判でも何でもしてみろや。
他力本願な口だけ野郎。
コンストラクタで初期化してメンバは隠蔽した方がいいと思う
【虎の威を借る狐】 他人の権勢に頼って威張るザコのたとえ
>>809 本当にそんな汎用性のないキモイおもちゃ作り
ずっとやってたの?w
取得関数とかクエリ合わせてチューニングも
選択もできねーしこんな設計じゃ拡張性もない
ゴミすぎるだろw?
>>806 WindowsAPIのほとんどは今もそうだね
>>809 DQNかどうかは兎も角、>808を書いている時点でお郷が知れている。
やっぱり
>>806 は痛い奴だったか
そんな臭いがプンプンしたしなぁ
反論してみ?
お前のかあちゃんデベソ
きさまっ!いってはならないことをぉおぉぉおおおお
環境や用途によってやり方は違うだろうに「キモイ」って評価しちゃう奴はある意味スゲェと思う。
>>818 OSS宗教様達は多いよ
リーなんちゃらという変態指導者の
影響だろうけど
自分達の受け入れたくないコード=グロ
って定義だし。
実際見たら、グロなんだろ。
グロいものほど美味い。これは定説です。
ポインタ使った事無いから事故にならなかったんだろ。 こっそりやってるなら、どうせわからないからいいけど、 堂々と自慢されると、やっぱりな、あれだよ・・・
823 :
796 :2008/01/15(火) 09:15:50
よーするに、memset()は使い道が無いってことかい?
>>823 環境依存でもよくて、標準の真っ当なコードに較べれば多少は速いかもしれないコードを使いたくて、
Intrinsicが用意されていないか使えなくて、インラインアセンブラが用意されていないか使えなくて、
他の手段が見つからないか、過去の遺物を使う為に必要。
とりあえず書いとけば誰かが直してくれるさ
826 :
808 :2008/01/15(火) 14:26:44
まともな反論は
>>812 くらいか。
かなりはしょってて共通の関数なんかをすべて省いてるから
>>812 の感想はもっともだけど、
実際の事務処理アプリの現場ではその「キモイおもちゃ作り」とやらが蔓延していたのもまた
事実としてあるんだから、自分だけ高みから見下して一蹴してしまうすような
>>812 は、俺には
少し世間知らずに見えてしまうな。
>>815 「やっぱり」ってなんだ?
テメーで反論せずに誰かに反論してもらって「やっぱり」って思ったの?
まさに
>>811 に出てる「虎の威を借る狐」=ザコだなお前。
あと「反論してみ?」って見下してるけど、テメーは何も言ってないよねw
なんなんだお前は〜w
こんなネタで盛り上がれるお前らの時間の贅沢な使い方に脱糞
828 :
808 :2008/01/15(火) 14:31:40
このスレ、極少数は経験も知識も豊富っぽいのがいるかも知れないけど、
その他はザコばっかだね。しかも性格が悪すぎ。
>>806 に対しての
>>807 は何だ。
知識も経験もないけど一方的に悪口言ってストレス解消ですか?
反論したいならテメーでしろ。
できないなら実のある話しろやボケ。
だから過疎るんだよこの板。
うん。
血圧が高いんじゃない? 高血圧は万病の元だよ。 まじで心配
>>828 で、ちみはポインタの何がわからなくて躓いてるんだ?
ポインタとmemsetって関係なくね?
もとは、ポインタをビットパターン0にしちゃだめだろ、って話だったけどな。
memsetの話出てからこのスレつまんなくなった
どこまで行けば面白くなるのか遡ってみたら
>>1 に到達してしまった
結局memsetで初期化することの問題点は、 浮動小数点数やポインタの内部表現が環境依存であるから 0.0やNULLに初期化されるとは限らないということだけ?
>>838 そだよ
つか, memset なんて組み込みやるときの bss の初期化にしか使った事ねぇし…
某A賞のシステムでもそんなの誰も気にせずmemsetしてるけどな
Cでgotoは絶対に使ってはいけない、という神話に似てる
まじで病院行け。
835は俺です 他は違います
頭のおかしい人にマジレスしてもw
__,. -─-- 、_ , - ' _,´ --──‐- ) ,イ´__-___,. -‐ '__,. - '´ `ー----, - ' ´ ̄ `` 、__ __,ィ ヽ. `ヽ. , '⌒Y / 、ヽ ヽ ヽ. / / i /l/|_ハ li l i li ハ . // 〃 /l i|j_,.//‐'/ lTト l、l j N i | {イ l / l li //___ リ_lノ lル' lハ. ソ ___◎_r‐ロユ i| /レ/l l l v'´ ̄ , ´ ̄`イ !| ll,ハ └─‐┐ナ┐┌┘ _ ヘ____ ハ| ll∧ハヽ ト、 '''' r==┐ '''' /l jハ| ll ll /./┌┘└┬┘└┼────┘ロコ┌i 〃 ‖ レ'¨´ヽiへ. _ 、__,ノ ,.イ/|/ ノ ll l| </  ̄L.l ̄ ̄L.lL.! ┌┘| ll ll { ⌒ヽ_/ } ー‐<.__ ′ l| ‖ ‖ ‖ ヽ, /、 〈 |:::::::| `ヽ ‖ ‖ {. ハ ヽ Y`‐┴、::::v l ‖ ‖ |iヽ{ ヽ_ゾノ‐一’::::ヽ. | ‖ ‖ |i:::::`¨´-- :::......:...:.:.::.}| ‖ ‖ |i::::::ヽ._:::_:::::::::::::::::::_ノ | ‖ ‖ |i::::::::::::i___:::::::::::/ | jj::::::::r┴-- `ー‐ '⌒ | 〃:::::::マ二 _,ノ //::::::::::::i ー 一 '´ ̄::. ,','::::::::::::::i::::::::::::::::::::::i::::::ヽ
847 :
デフォルトの名無しさん :2008/01/18(金) 13:58:42
ぴぴるぴるぴるぴぴるぴ〜
memsetだってwin32api使ってたらよく使うし まぁ、ようは、どんな関数でも使う奴しだいだろ
ほとんど見かけないようなプラットフォーム向けにも移植性を確保しておきたいかどうかだな zlibみたいなライブラリではそうする価値があるかもしれないが、俺が書くようなコードではどうでもいい…
>>849 スピード命のコードだと, 内周ループで数エントリの構造体を
memset するのってやたらコストがでかい。
実際には、サブルーチンコールのオーバーヘッドがでかいんだが…
去年 MPEG 関連の仕事を途中から引き継いだんだけど、とろくって
使い物にならなかった元のコードの memset を代入文に変えただけ
で実行時間 60% 程度まで短くなった。
それは使っているコンパイラが悪いような希ガス。
>>850 memset初期化を使うのは、システム起動時か、再起動時でしょ。
あとはオブジェクトが生成されたときとか。
頻繁に生成、破棄を繰り返すようなオブジェクトで、システム上重要な
パフォーマンスに影響をあたえるものにたいして、memset初期化をするかしないか
というのは「高速化」の話。memset初期化のよしあしの話ではない。
>>851 それは言えてるんだが、組み込み物ではコンパイラの選択肢は限られる。
ましてや、クライアント指定のコンパイラだ
>>852 > システム上重要なパフォーマンスに影響をあたえるもの
に、対して memset で初期化しておいて、直後にその大半を意味のある
値で再度上書きしてた。
> よしあしの話ではない。
かもしれないが、元のコードを書いた奴の神経をうたがったわな。
Win32APIみたいに設定項目が山のようにあり、 常に全部を使うわけでもなく、 0で埋められる項目の頻度が高ければ十分ありだろ。 C/C++以外では今時クラスインスタンス0フィルされる言語も珍しくもないし。 ケースを指定するでもなく一般論としてあーだこーだいってる奴はアフォ。
>>855 いいえ。
高が、struct someStruct foo = {0} で済むことのためにmemset()を使う必然性は殆どありませんね。
それがstruct someStruct * foo = malloc(sizeof(* foo))した領域でも同じこと。
memset使わないで struct someStruct * foo 何か処理 foo = {0};って感じでまた初期化すればいいだけ memset使うやつは馬鹿今の公開されている まともなソースでmemset使ってるのコードは皆無だぞ?
>>857 >foo = {0};
それ無理じゃね
0fillがいかんからmemsetがいかんに話がずれてきてるな
パフォーマンスだけに限って言うと、memsetをインライン展開するコンパイラなら使う事もある。
>高が、struct someStruct foo = {0} で済むことのため 宣言と同時に初期化しない場合はどうするの? というよりこれってコンパイラ依存なんじゃないの?
memsetは危険だから使うなって manとかMSDNに記述あるんだな
お前は何を言っているんだ
manページより: >説明 >memset() は s で示されるメモリ領域の先頭から n バイトを c で埋める。 >返り値 >memset() は s へのポインタを返す。 >準拠 >SVr4, 4.3BSD, C89, C99, POSIX.1-2001. 俺の目がおかしいのかもしれないが危険性がどこにもみつけられない。 MSDNとか読むきしないから他のヤツよろしく。
>memset() は s で示されるメモリ領域の先頭から n バイトを c で埋める。 これは嘘だろw nバイトをcで埋める可能性もあるが正解
冬 真 っ 盛 り
埋めない可能性もあるのか? まぁSEGVるかもしれんが
>>869 >まぁSEGVるかもしれんが
>>866 がそんなことで「埋めない可能性がある」とかバカなこというわけないじゃないか。
>>866 は、きっともっと違った根拠があっていってるのだよ。
ECCメモリを使っていない場合に起こるのかもしれないなw
>>871 ワロスwww
その「可能性」言い出したら、マニュアルなんて書けない気がするがwww
釣り堀だなw
struct someStruct foo = {0} これはできるけど、動的確保した構造体だと無理じゃね?
>>876 struct someStruct * foo = malloc(sizeof(* foo));
struct someStruct blank = {0};
* foo = blank;
よほど気の利かないコンパイラでもなければ、blankの実態は作られない。
なんと言う糞コードというか糞スレ・・・
>struct someStruct blank = {0}; こんなコンパイラがサポートしている「かもしれない」機能を 「使わないのはおかしい」と主張されてもな。
>コンパイラがサポートしている「かもしれない」機能 そうなの?
>>880 サポートしていないコンパイラをご存知ならご提示くださいませ。
以後規格外品として、広く存在を知らしめてまいりたいと思いますので。
>>882 むかし使ってた、ARMの純正コンパイラではサポートされてなかったな。
もし論点があってそれを覚えているのなら3行にまとめてくれたまへ
つまり、昔のARM純正コンパイラは構造体の初期化ができないと?
>>884 , 885
つか、
>>882 は「Cが処理系に依存しない高級言語だ」って
思ってる可愛そうな奴なんだよ
>>887 いや、全部のメンバに代入すればOK
struct A {
int a;
int b;
};
OK:struct A a = {0, 0};
NG:struct A a = {0};
お前らまずは日本語を学べ スレタイが読めるようになったらまた来い
ポインタは友達!
ポインタ「げ。また
>>891 だよ・・・マジウザイ・・・
ひでえw
昔記事を見て馬鹿にしてた教材が一番わかりやすかった
memsetを使う利点は使い方によっては構造体の初期化のソースを短く出来る事かな 巨大な行列を持つ構造体を初期化するとか普通に代入でまかなうとマジで馬鹿にならないくらいソースが膨らむから ループで回して初期化するのも遅いしな
896 :
デフォルトの名無しさん :2008/01/21(月) 00:52:45
>>896 どうでもいいのだが・・・
>当然ですが、あらゆる標準関数の使用を認めません。
>
>・strlen() を自作せよ。
>・strcat() を自作せよ。
標準関数の使用を認めないくらいなら、strlenとかstrcatとかキケンな
関数じゃなくて、ふつうはもっと安全な代替関数を自作するでしょ。
>>896 >C++未経験ながら、1人でC++の10万行のソースコードの保守及び、3万行の開発を行った。
これ単にCとして使ったとかじゃ
いまどき行数で規模示すなんて クラス数と各クラスのメソッド数で競ってくれ っつーかすれ違いか
競うなよ。どっちも少なければ少ないほど良い。
さすがにクラスは適切な数ってのがあるだろうな。
PIC等の単純なCPUで機械語でもやってアドレッシングモードを習えば ポインタは理解出来るんじゃね? 余計に混乱するかな?
PICとかアドレッシングモードとかわけわかめなんだけどどうすれば習えるの?
PICは余計なところが気になりすぎ、16ビット以上推奨だな。 AVRとかHC08とかARMがいいんじゃね? あと、アセンブラのアドレスはせいぜい指してる先のバイト数 の情報くらいしか持ってないから、ポインタまでには、まだまだ 壁があるのでよろしく。
>>895 おれは構造体を定義したら、必ずその初期化関数を作るけどな。
だからソースはさほど膨らまない。
まあその関数の中でmemsetをやっている場合もあるんだが、
それでも素のmemsetは使わないな。
動的にその行列のサイズが変わる、その平均が100X100から1000X1000近くになって 最悪5千近くなる行列は動的に変わるんで代入じゃ無理だし、ループでまわして初期化するよりはmemset使った方が速度は確保できるし 何が糞なんだかなぁと思うわw まあ、動的に確保して中身をゼロクリアしたいのならcalloc使えって話だけどなw しかし、途中で初期化したくなったらmemsetかな?
>>905 > あと、アセンブラのアドレスはせいぜい指してる先のバイト数
> の情報くらいしか持ってないから
TRON chip を否定したな!WwwWW
>>908 > TRON chip を否定したな!WwwWW
は? TRON Chipのポインタも、持ってる情報はアドレスだけですが?
ポインタに情報を持たせるのはLisp処理系とかで、ワードアラインの都合で
使わない下2bitに型の情報を入れ込んだりとか、アドレスが24ビットだった
68000用のやっぱりLisp処理系で上8bitに型の情報を入れたり、とか。
ポインタが本格的に(?)型の情報を持ってるアーキテクチャったらIBMの
System/38→AS/400とかだろ。
>>909 ショボいCPU使ってプログラムを作ると自分でポインタを作って管理しなきゃいけなくなるよ。
それでポインタがマスター出来るだろうと思う。
>>907 そういう0クリアする必要があるときのmemsetには、誰も異論を唱えていない。
>>907 それやるとどこか1バイトだけ
初期化されず危険というコンパイラもある
>>912 「そうする機能を持つ」ということと、「バグでその機能が働かない」というのを
ごっちゃにすると、ワケワカンナクなるからやめようぜ。
>>909 本家本元のLispマシンを忘れてるぞ。
っていうかアドレスの使ってないビットにむりやり型情報詰め込んだりしてんのも
Lispマシンからの処理系移植のために苦肉の策で
はじまった事じゃないか。
nt aref(int **a, int i, int j) { return a[i][j]; } int test() { extern int array[3][5]; return aref(array, 0, 0); } コンパイル時に passing argument 1 of 'aref' from incompatible pointer type って怒られるのはなぜ?
>>915 エラーメッセージが指摘しているように、関数arefの第一引き数の型が違うから。
>>915 こうすればおk
int aref(int (*a)[5], int i, int j)
>>917 つ、ことはですねぇ…
コンパイラは int array[3][5]; を 1 次元の配列と認識してるで ok?
>>918 int[5] が3つある1次元配列という認識なら、正しい。
>>919 つ, ことは
aref の a に渡す変数は
int i; char a[3][5]; char *ap[3];
for (i = 0; i < 3; ++i)
ap[i] = &a[i];
で, 出来たポインタ配列以外は × って認識で ok?
ポインタの配列と 配列の配列をごっちゃにするな
>>920 おまいさんは配列の配列なんぞを使わずに、一次元配列二次元的にアクセスすることを覚えた方がいいよ。
>>920 以下の3つの違いを明確に理解せよ。
特にメモリ上でどう表現されるかについて考えるといい。
(a) 3つの int[5] からなる配列 int a[3][5]
(b) 3つの int* からなる配列 int* a[3]
(c) int[5] へのポインタ int (*a)[5]
(a) と (b) は似たようにアクセスできるかもしれないが全くの別物。
(a) から (c) に自動変換が効くのは一般の配列の場合と同様。
>>924 > (c) int[5] へのポインタ int (*a)[5]
なるほど…
ありあがとう, やっと意味がつながりました。
NULLポインタは0とは限らないといってる奴がいたのだが 空ポインタが0以外の処理系とか存在するのか?
928 :
926 :2008/05/04(日) 17:12:15
>>927 なるほどです。処理系はともかくANSI Cは0で決まっているようですねw
ありがとうございました。
ヌルポインタを数値型にキャストしたとき0じゃないかもしれないんだっけ? boolは0だよな
>boolは0だよな いいえ、boolは型です。
ヌルポインタをboolにキャストした場合を言ってるんじゃないか? でもfalseのビットパターンって全0だったっけ。
>931 falseのビットパターンは全0で正解。 残念ながらNULL pointerをbool型にキャストした場合にfalse(全0)になる保証はない。 ifやforの条件部にpointer型を使用した際に、それがNULL pointerのときかつそのときのみfalse扱いになるのは別の仕組みによる。(C FAQなどに詳しい説明あり。)
933 :
デフォルトの名無しさん :2008/06/02(月) 03:43:07
>>9 に同意。
プログラミングのセンスがないやつがプログラミングを続けても
たぶんどこかで脱落する。
少なくとも劣等感にまみれた人生になると思ふ。
「一般の」「あらゆる」「全ての使い方での」 ポインタなんて考えると、手に負えなくなる。 自分の良く使うアルゴリズムに使うときの パターンを手コピーしながら覚えるのが 結局は使いこなしにも良い気がする。 定番の型を何度も使っているうちに やがて脳内に回路が育ってくる、 そういうのでいいんだと思う。 ポインタに限らないけど。 野生のポインタ… それは ぬるぽ
それは理解できないやつの負け惜しみ。
ポインタって理解すると何が難しかったのか よくわからなくなるとこが厄介な気がする。
難しいところなんかない
ポインタの絡んだ宣言が、最初はわかりにくいかもしれん。
ポインタの概念自体が難しいってより、 複雑なデータ構造とか、デバッグとか、そっちじゃないかね
「int型」のポインタ変数p って覚えるからごっちゃになるらしい。 「int型のポインタ変数」p って覚えれば割とすんなり覚える。 だから教えるときは int *p; より int* p; で教えてる。
まぁ、そういう考え方もあるのか〜、と。
intとintポインターは別物
誤りはなさそうだが、 ポインタ初学者向けの記事だとしたらひどい内容だな。
そもそも、ポインタを理解できてない香具師に限ってアドレスを持ち出したがる傾向がある。
そうか? ってか、実生活ではポインタわからんなんて奴はいないな。 じーっと黙ってるだけなで、向かいの居乳のIさんは、ポインタをおそる おそるナデナデしてんのか?
Yeah, I'm speaking Japanese now, huh?
>じーっと黙ってるだけなで
okey, drop "な"
ポインタ脳特有の同化現象だな
概念がわかっても表現方法が糞なせいでつまづく。
ポインタ=(アドレス保持,型情報)
Cならアドレスに毛がは得たものだと思っておけばいいが C++だと配列newとか仮想関数とかあるからな…
ヌルポインタの内部表現は 0とは限らないから 「構造体をmemsetで初期化してはいけない」という話がこのスレにある だが実際はそんな特殊な環境はめったに無く、人事だろうと思ってたんだ
ところがどっこい、身近な環境でそのような例を作れることに気づいてしまった 以下のコードを実行すると、大抵の環境で2回目のassertに失敗する 手元の x86の VC7.1と gcc 3.4で確認したぜ #include <assert.h> #include <string.h> int main() { struct A; struct { int A::*p; } hoge = {0}; assert(!hoge.p); // こちらはOK memset(&hoge, 0, sizeof(hoge)); assert(!hoge.p); // This assertion fails }
958 :
デフォルトの名無しさん :2008/07/05(土) 15:26:03
age
メンバへのポインタのNULL表現か これは興味深い
struct A { int n; }; なら&A::nは0になるから、 0をNULLに使えないというわけか。
gcc 3.4で実験 #include <stdio.h> struct A { char elem1; char buf1[0x7FFFFFFF]; char buf2[0x7FFFFFFE]; char elem2; char elem3; char elem4; }; union UP { char A::*p; size_t n; }; void test(const UP &x) { printf(" nval=%08x, is_null=%d\n", x.n, (x.p==0)); } int main() { UP hoge; printf("sizeof UP=%u\n", sizeof(UP)); hoge.p=0; test(hoge); hoge.p=&A::elem1; test(hoge); hoge.p=&A::elem2; test(hoge); hoge.p=&A::elem3; test(hoge); hoge.p=&A::elem4; test(hoge); }
結果 sizeof UP=4 nval=ffffffff, is_null=1 nval=00000000, is_null=0 nval=fffffffe, is_null=0 nval=ffffffff, is_null=1 nval=00000000, is_null=0 エラーチェック無しの gcc 君でした
963 :
マイク ◆yrBrqfF1Ew :2008/07/19(土) 07:12:13
アセンブリ言語をやるとポインタを理解しやすいって書いてあるのを 昔web検索してたらどこかのサイトで見た。
964 :
デフォルトの名無しさん :2008/07/19(土) 08:16:59
頭で理解しようとするから プログラムは使用ー>理解が原則
日本語でOK
ポインタが理解できないのは頭で理解しようとするから。 プログラムは使用することで理解する、体験学習が原則。
自然と覚える揉んだと思う 小学校でいうなら台形の公式くらいだろ
台形の公式なんて聞いた瞬間に覚える種類のもんで、理解するようなもんじゃないだろ。
上下逆さまにしたやつを横にくっつけると平行四辺形になり
その面積は 底辺×高さ=(台形の上底+台形の下底)×高さ だから
その半分で (上底+下底)×高さ÷2 と習うんだよ
>>968 は小学校からろくに勉強してない池沼
は? 対角線を引いて、上底からの三角形と下底からの三角形の面積の和でいいじゃん。 なんで平行四辺形なんて持ち出す必要あるんだ?
補助線引くだけで難易度が上がるからな
その三角形の面積は、平行四辺形の÷2じゃね
>971 それだと (上底×高さ÷2)+(下底×高さ÷2) という式になるだろ この式を(変数が入ったまま)まとめるのは面積の計算を習う時点では不可能
正しい結果が出るならどっちでもいいと思っている俺こそが真のプログラマ。
そういうのの下についた奴は本当に不幸だな
>>971 >>974 そうやっても面積は求められるねというようなことも
教科書には書いてあった気がする、公式には969で出したけど。
>>974 なんでだ?面積習う前に、結合法則も分配法則も習ってないのか?
979 :
デフォルトの名無しさん :2008/07/26(土) 12:05:12
int pupi = 5; int papu = 10; int *poin = &pupi; *poin = &papu;//なんでエラーが出るんだよ!
*いらないから。
&いらないから。
int の *poin というよりは int* の poin だからな。初心者が疑問に思うのもわからんでもない。 いっそ static みたいに記述できれば混乱もないだろうに。 pointer int poin; みたいな。
poin = &papu;か*poin = papu;
984 :
デフォルトの名無しさん :2008/07/27(日) 17:28:32
985 :
デフォルトの名無しさん :2008/07/27(日) 17:56:07
,..-─‐-..、 /.: : : : : : : .ヽ R: : : :. : pq: :i} |:.i} : : : :_{: :.レ′ ノr┴-<」: :j| /:r仁ニ= ノ:.ノ|! _ /:/ = /: :/ }! |〕) 何だって? {;ハ__,イ: :f | /´ / }rヘ ├--r─y/ / r'‐-| ├-┴〆 _, 、_ '⌒ ☆ 仁二ニ_‐-イ | | ∩`ω´) | l i 厂  ̄ニニ¬ ノ ⊂ノ <<980-981 ,ゝ、 \ \ __厂`ヽ (__ ̄) ) / /\_i⌒ト、_ ノrr- } し'し′ └-' ̄. | |_二二._」」__ノ
986 :
デフォルトの名無しさん :2008/07/27(日) 17:57:56
987 :
デフォルトの名無しさん :
2008/07/27(日) 18:06:08 中国人の平均所得は低いけど、銀座には富裕層の中国人がうろうろしていて 日本の経済に影響を与えているだろ 平均やら統計やらだと実態を返って見失う好例 話が飛んでるけど、そもそも平均だけで判断しようっていうのが間違い。 平均だけ見たらあくまで平均が分かるだけで、富裕層の人数とかなんて判断できない。 平均だけを見て「統計」とかほざくな。分散とか標準偏差を高校の教科書で見てごらん。 ちゃんと統計結果を総合的に分析すれば実態を見失わないから。 煽りじゃなく忠告。 なんかお前って考えが表面的。 公式を覚えても意味がない。 本質を、根幹を見るようにしたほうがいい。