1 :
デフォルトの名無しさん:
int i = 10;
int * p = &i;//int型ポインタpにiのアドレスを代入する
簡単。
char str1[] = "abcde";
char * str2 = "abcde";
上と下は同じでどっちを使ってもいい。
str1 = "別の文字列"; //エラー
str2 = "別の文字列"; //OK
上と下どっちを使うか状況によって異なる。
同じとかいってしまっているお前は、結局何も理解出来ていない。
if(sizeof(str1) == sizeof(str2))
puts("
>>1は天才");
else
puts("
>>1は愚か者");
* を両方から離して書くのは
かけ算と紛らわしいので嫌い
その昔、ポインタの冒険と言うゲームがあってだな
8 :
デフォルトの名無しさん:2008/07/27(日) 11:47:27
code、data、bssの何処に配置されるのかが重要
9 :
デフォルトの名無しさん:2008/07/27(日) 11:54:39
>>1 *(s+5)
s[5] (⇒ Compile時に*(s+5)に変換される)
5[s] (⇒ Compile時に*(s+5)に変換される)
は全部同じ意味だから当たり前だろ。
↑はずれ
11 :
デフォルトの名無しさん:2008/07/27(日) 12:04:28
* と []は同じ
とは限らない
char str1[] = "abcde";
char *const str2 = "abcde";
これならよかったのに
ここはバカのすくつか・・・。
char (*p)[6] = &str1; // OK
char (*p)[6] = &str2; // Error
if (sizeof str1 == sizeof str2) {
puts("same");
} else {
puts("different"); // こっちが出力される
}
str1[0] = 'A'; // OK
str2[0] = 'A'; // 未定義動作
これもだな。
str2はただのアドレスを格納するだけの変数(普通は4byte)
str1は実体を持つ(char*6 = 6byte)
"abcde"は定数でメモリのナンチャラ領域に密かに存在したまま。
"abcde"はfree()が必須ですか?
お前は一体何を言っているんだ?
1.str1は定数で、str2は定数じゃない。(str1++とか出来ない。)
2.str1の指す領域は変更可能で、str2に関しては未定義。
って感じ?
あ、いや、その・・・・
ポインタは理解できる。
がしかし、
ポインタのポインタが出てくるともう俺の頭はオーバーヒートしてしまう。
すんませんVBしか触ったことがないもので。
こんなテキストベースのコミュニティで聞くより
>>11の本を買って視覚的に学んだほうが早い
くだらない本を読んでいる暇があったら、アセンブラをかじればいいだけ。
26 :
デフォルトの名無しさん:2008/07/27(日) 17:48:22
ポインタのポインタを理解できないようでは
ポインタが理解できているという言葉も怪しいな。
ポインタは理解できたけど、ポインタのポインタが理解できないってのは
大抵ポインタは配列の表現を変えた物と認識している
で、ポインタのポインタ=二次元の配列と考えてしまい混乱する
29 :
デフォルトの名無しさん:2008/07/27(日) 22:47:46
ポインターが理解できないのは
mov eax,esi
と
mov eax,[esi]
の違いがわからないのと一緒。
この違いがわかればポインターが難しいはずがない。
文法が曖昧で難しいのであって、ポインタが難しいのではない
このスレタイみたいなことを職場でいう奴がいると本当に萎える
ポインタが分かる・分からないという話自体、ど素人が好む話題だから
・なぜポインタを使う必要があるのか
・どういう場合にどういう風にポインタを使うべきなのか
この二点を誰も説明してくれないんだよなあ。
山ほど解説書を買ったけど、前者について解説している本は皆無。
後者については、関数の引数を参照渡しして直接更新して返す
サンプルくらいしかない。
これで理解して使えという方が無理だ。
> 理解して使えという方が無理
そう、だから理解しないでなんとなくコード書いて、
そのうちなんとなくみんな分かってきた気になるというのが現状。
悩んでいる暇があったらとりあえず何か書いてみ。
>>33 いや、俺は理論から入る人間だから
使う必要性を理解してからでないと使いたくないんだ。
ただ一つ、最近の本で「配列とポインタではポインタの方が
実行速度が速い」という記述を読んだ。
これだよこれ。こういうのをなぜ一番に言わないかね。
初心者は、同じことを配列でできるのに、なぜわざわざポインタを
使うのか、そのことで悩んでるんだから。
「配列とポインタはやってることは同じだけどポインタの方が速い」
この一言だけでポインタを使う理由になるじゃないの。
>>34 俺も理論から入る人間だからこそ言える。
たぶんそういう考えの俺らはPG/SE/PMには向いてないよ。
36 :
デフォルトの名無しさん:2008/07/28(月) 00:33:24
この業界の出来る人というのは、常に最新の技術を追い続けている。
必要有か無か、流行るか流行らないか、の判断も付かないうちから、最新技術に興味を示す。
実は大嘘
配列とポインタでは配列のほうが実行速度が速い
38 :
デフォルトの名無しさん:2008/07/28(月) 00:37:12
>>34 プログラムなんてどんな言語で作られたモノであろうと結局はCPUがメモリのアドレスを行ったり来たりしている。
隠蔽されてないアセンブラ・Cが速いのは当たり前。
勿論、零細企業で小規模システムの開発しかしていない人にとってはJavaどころかVBでも十分
速度と省メモリ
40 :
デフォルトの名無しさん:2008/07/28(月) 01:04:18
結論:ポインタを考えた奴は馬鹿
C言語の文法が糞
もっと紛れのない文法の高級アセンブラが普及すべきだった
ポインタの必要性くらい書いてある本はある。
書いてないようなら捨ててしまえ。
>>40 >>41もいってるが文法がクソなだけ。
先にポインタの概念を取得してからCに入れば
表現の違いでしかないんだけどな。
44 :
デフォルトの名無しさん:2008/07/28(月) 02:25:06
>>32 やっぱプログラミングの入門書には
データ構造の話とかも書くべきだよな。
>>34 ちょwwwwwwwwwwそんな理由www
>>34 それが事実じゃないからさ
ポインタと配列は別物であり、使える場所も変わってくる
例えば関数の引数として使えるのはポインタだけで
配列使ってるように見えるのは見せ掛けで実はポインタ使ってるとか
そういう細かい事実があるわけ
今の処理系じゃポインタの方が速いなんてことも別にないし
46 :
デフォルトの名無しさん:2008/07/28(月) 07:36:31
>>37 ハァ?
メモリ上の配列とポインタの事言ってんだったら変わらねーよ。
例え配列がスタックで、ポインタの方をヒープのつもりで発言してても、
確保に時間が掛かるだけで、アクセス速度は変わらん。
特定のコンパイラの実装・最適化の話とか?
まー配列の方が当たりをつけやすい場面が多いとはおもうけど
それをもって速いってのもなぁ。
ポインタ判らないとかいってるやつはクローじゃ、ラムダ指揮、公開関数(なぜか変換できない)理解できるのか?
訂正
→できないのかな?
Cのポインタは参照・束縛の概念だけじゃなく
メモリアドレスを意識できなくちゃいけないしな。
ポインタ自体の演算や型キャストもできるわけだし
高級言語にくらべたら無法に近い。
>>48 一見関係ないように思えるけど……。
Cでポインタを使わなくてはならないケースは
malloc関数で動的にメモリを確保して使う場合と
scanf関数の引数だろ。
これ以外でポインタを使う香具師はDQN。
>>51 | | | | | | | | | | || | |
| | | レ | | | | | J || | |
| | | J | | | し || | |
| レ | | レ| || J |
J し | | || J
| し J|
J レ
/V\
/◎;;;,;,,,,ヽ
_ ム::::(l|l゚Д゚)| …うわぁ
ヽツ.(ノ::::::::::.:::::.:..|)
ヾソ:::::::::::::::::.:ノ
` ー U'"U'
後半は釣りだが、それまでmallocの話が出てこなかったのは異常。
>>52 × 説明する気もないし
○ 説明する能力もないし
1. 配列を関数に渡す際にどうしても必要
2. 構造体を関数にコピーレスで渡したい際にどうしても必要
3. 別関数内の変数の値を変更したい際にどうしても必要
4. メモリを動的に確保する際にどうしても必要
5. 特殊なデータ構造を実現する際にどうしても必要
ポインタがどうしても必要になるケースは、普通はこのくらいかね。
他にも使う状況はなくはないと思うが。
59 :
コピペ:2008/07/28(月) 11:11:54
【ポインタがないと?】
void func(char c){
c = 'z';
}
int main(){
char subarac = 'a';
func(subarac);
printf("%c",subarac);
}
mainの人「'a'って書いた紙を渡すよ」
func作業員「じゃあそれをコピーして使いますね」
mainの人「なんでんなことすんだよそのまま使えよ」
func作業員「コピーしたのをzと書き換えました」
mainの人「じゃあくれ」
func作業員「これはあなたのものではなく私たち作業員のものです、渡せません」
mainの人「結果、手元にあるaと書かれた紙が表示されるのであっためでたしめでたし」
void func(char *c){
c = 'z';
}
int main(){
char subarac = 'a';
func(subarac);
printf("%c",subarac);
}
この場合を教えてくれ
>>60 ひと目で間違いに気づかないとか、もうね…
62 :
60:2008/07/28(月) 11:43:47
ポインターはどこでもドア。
好きなところに移動してデータを置ける。
開けた先がお風呂だと大変なことになる。
66 :
60:2008/07/28(月) 12:53:55
警告は出るがコンパイルはできる
PPP.C(2) : warning C4047: '=' : 間接参照のレベルが 'char *' と 'int' で異なって
います。
PPP.C(6) : warning C4047: '関数' : 間接参照のレベルが 'char *' と 'char' で異な
っています。
PPP.C(6) : warning C4024: 'func' : の型が 1 の仮引数および実引数と異なります。
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation. All rights reserved.
/out:PPP.exe
PPP.obj
>>57 おお、いいね。
これを五つの章構成にして
実例とともに詳細解説を加えれば
画期的なポインタの解説書になるよ。
たぶん、今までこういう本はなかったよ。
本を出したら俺は印税の一割でいいよ。
1. 配列を関数に渡す際にどうしても必要
可変個引数で渡せる
そもそも、配列を使うためにはポインタ演算が必ず行なわれているわけだが。
p[i]というのは*(p+i)でしかないのだから。
# だからこそi[p]という書き方もできるわけで、3["abcd"]なんてこともできると。
仮引数を [] で受けてたら、ポインタを使っていることに
気づかない奴もいるかも知れない。
そこをきちんと説明しないから理解できないのではないかと思う。
scanfを教えるときに&を{おまじない}として教えるのも良くないと思う
ポインタの使いどころを書いてる本がないってことはないと思うんだが。
74 :
デフォルトの名無しさん:2008/07/28(月) 13:51:02
#include<stdio.h>
char func(char c);
int main(void)
{
char subarac = 'A';
subarac = func(subarac);
printf("%c\n",subarac);
return 0;
}
char func(char c)
{
c = 'Z';
return c;
}
>>59先生できました\n
char str1[] = "abcde";
だと長さが5の配列の実体が出来ると思ってたんだけど違うのか?
char *str2 = "abcde";
だとリテラル"abcde"のアドレスをstr2に代入すると思ってたんだけど違うのか?
>char str1[] = "abcde";
>だと長さが5の配列の実体が出来ると思ってたんだけど違うのか?
違う。長さは6。
>char *str2 = "abcde";
>だとリテラル"abcde"のアドレスをstr2に代入すると思ってたんだけど違うのか?
あってる。
>>69 いいや
配列p[]を *(p+i)でアクセスするのは無理だろ
>>77 自信満々に書く前に、ちょっと確認してみたら?
#include <stdio.h>
int main()
{
int i = 3;
int p[] = {1, 2, 3, 4, };
printf("%d\n", *(p + i));
printf("%d\n", i[p]);
return 0;
}
>char str1[] = "abcde";
なんで長さが5なの?
\0を忘れていました。
char str1 = {'a','3','-','o','ω'};
アドレス空間の概念が理解できてないとポインタが理解できないんじゃない?
あと、できればスタックとヒープの違いぐらいは理解して欲しいけど。
そもそもC言語の場合、スタックにたくさん積みたくない→ポインタの概念導入、っていう流れの気がする。
>>78 すまぬ
だがこういうのよく使わないかな?
sizeof (a) /sizeof (a[0])
ポインタと配列混同すると痛い目にあう例だが
だが
のつながりがよくわからないです
>>83 配列とポインタの区別がよくできていないことが判りますね。
int main()
{
short i;
short a[3];
short * p;
printf("%u, %u\n%u, %u, %u, %u\n%u, %u, %u, %u\n",
sizeof(i), sizeof(& i),
sizeof(a), sizeof(* a), sizeof(a[0]), sizeof(& a),
sizeof(p), sizeof(* p), sizeof(p[0]), sizeof(& p));
return 0;
}
きっと配列へのポインタも理解できてないんだろうなあ。
short (*pa)[3] = a;
87 :
デフォルトの名無しさん:2008/07/28(月) 20:14:21
C言語でint[100000000000000]とかにしちゃうとエラーになるんですけど
(コンパイラだかリンカだかの制約でスタックには○○MBしか積めないルール)
他の言語でも同じなんですか??
Java,VB,Ruby
88 :
デフォルトの名無しさん:2008/07/28(月) 20:18:51
89 :
デフォルトの名無しさん:2008/07/28(月) 20:20:33
>>87 仮想メモリとして扱う処理系もあるし、そのエラーと言うのは全部の処理系で確認した?
>>87 >C言語でint[100000000000000]とかにしちゃうとエラーになるんですけど
sizeof(int) が4だとして、300テラバイトを超えるメモリを割り当てられる処理系が思いつかない。
91 :
デフォルトの名無しさん:2008/07/28(月) 20:21:58
>>85 $ ./a
2, 4
6, 2, 2, 4
4, 2, 2, 4
ところで
short *ponta = a;
とやってもsizeof(ponta)は4byteでしかない。
aを使わずにqが指すshort配列の大きさを調べることはできないの?
92 :
デフォルトの名無しさん:2008/07/28(月) 20:22:49
配列へのポインタ
と
ポインタの配列
の違いと宣言文法が分からない。
93 :
デフォルトの名無しさん:2008/07/28(月) 20:24:31
訂正
>aを使わずにqが指すshort配列の大きさを調べることはできないの?
aを使わずにpontaが指すshort配列の大きさを調べることはできないの?
BCCでもGCCでも
int[200万]あたりでエラーになる。メモリは6GB積んでるのに
>>92 short (*p2a)[X]; // p2aは short[X] を指すポインタ
short *(p2a[X]); // p2a[X] は short を指すポインタ
short *p2a[X]; // 同上
>>93 不可能。
>>94 その配列が静的か動的かによって違う。
つか、6GB積んでたって全部1プロセスで使えるとも限らん。
>>95 1から勉強し直せ。
97 :
デフォルトの名無しさん:2008/07/28(月) 21:15:46
・ポインタの配列
[アドレス][アドレス][アドレス][アドレス]・・・
と言う風にアドレス空間にポインタの配列が確保されていて、アドレスが入っている。
・配列のアドレス
アドレス
↓
[データ][データ][データ][データ][データ]・・・
配列の先頭アドレス。インクリメント時にサイズだけインクリメントされる。
・配列のアドレスを保持するポインタ
ポインタ
↓
[アドレス]
↓
[データ][データ][データ][データ][データ]・・・
これが
(*p)[i];
だと思う。「配列のアドレス」を略して「配列」って呼ぶのはちょっとどうかなと思う。
わかりにくい。
ちなみに俺は
int i, *p, *a;
・・・
p = a + i;
って書き方はしないようにしてる。
int i, *p, *a;
・・・
p = &a[i];
って書くようにしてる。
理由は俺がアホで理解しにくいから、
変数は配列を考えることができますね。たとえば、次の例ではchar型変数10個の配列を宣言しています。
char charray[10];
ポインタといっても変数なので、他の型と同じように配列を宣言して使うことができます。
char *chr_ptr[10]; (char* chr_ptr[10];でもいい)
2次元配列のことをポインタの配列だという人がたまにいますが、ちょっと違います。
ポインタの配列は2次元配列などではなくあくまでもポインタ変数の配列で、上のように宣言したものは1次元配列です。
メモリの確保のされ方からいって、2次元配列とポインタ配列は全く違うものです。
別に、char型の2次元配列と思っていいんじゃないの?
ポインタは完璧!だと思ってたのにこのスレ見たら自信なくなってきた
お、おれも!
俺はアホばっか見てて自惚れそうで怖くなってきた。
**argvはポインタのポインなのか配列のポインタなのかポインタの配列なのか詳しく!
167 :デフォルトの名無しさん:2007/11/03(土) 14:30:24
>>157 char **p;
と書いて配列へのポインタと解釈することなんてありえるか?
配列へのポインタといったら
char (*p)[N];
じゃないのか?
168 :デフォルトの名無しさん:2007/11/03(土) 14:31:55
>>167 int main(int argc, char **argv)
170 :デフォルトの名無しさん:2007/11/03(土) 14:32:48
>>168 それはポインタの配列
107 :
デフォルトの名無しさん:2008/07/28(月) 21:51:27
これでFA
(intへのポインタ)の配列
int* ponta[10];
(int配列)へのポインタ
int(* ponta)[10];
108 :
デフォルトの名無しさん:2008/07/28(月) 21:52:51
(int)へのポインタ
int* ponta;
??
int(* ponta);
109 :
デフォルトの名無しさん:2008/07/28(月) 21:56:49
以下の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) に自動変換が効くのは一般の配列の場合と同様。
>>106 **argv は文字列配列の先頭アドレスが確保されている配列の先頭アドレスのポインタ。
言い換えると文字列群の各文字列の先頭へのアドレスが配列で保持されていて、その配列の先頭アドレス。
"test"
"yaruo"
"bararaika"
と文字列があったら、 "test"の "t" のアドレス、"yaruo" の "y" のアドレス、 "baranaio" の "b" のアドレス
が
[アドレス][アドレス][アドレス]
と言う風に格納されていて、その一番最初のアドレスが argv。
要するに、
argv が指すアドレス
↓
[アドレス][アドレス][アドレス]
↓ ↓ ↓
"test" "yaruo" "bararaika"
ってなってる。
>>110 >**argv は文字列配列の先頭アドレスが確保されている配列の先頭アドレスのポインタ。
文字列配列じゃなくて、文字列または文字配列じゃね?
「文字列群」が文字列配列であるかはどうかは**argvには関係ねぃし。
**argvは、機能的にはどう見ても
ポインタの配列なのだが、
星が二つついてるのだからあくまで
ポインタのポインタと理解しなければならない。
*argv[]
この書き方が好きだ
要するに、c では「配列」の実体だけを書くことができないんだよ。(anonymous 配列を書くシンタクスがない)
書けるのは「配列の名前」で、それは配列の実体へのポインタをそう呼んでいるだけ。
char a[128]; というときの a 自体は配列ではない。a は「配列の名前」で、それは [128] という配列実体へのポインタ。
その a へのポインタは、char (*a)[128];
116 :
デフォルトの名無しさん:2008/07/29(火) 01:27:34
日本語でおk
[]演算子が混乱の元だ。
シンタクス・シュガーではなく、
シンタクス・ビターになっとる。
うまくない
わざと分かり辛く書いてんだろ。
[]も*も同じだと思えばいいんだよ。そのうち違いが分かってくるさ。
>>105 俺は改めてコの業界の糞さを思い知らされた。
>>115 自慢げに適当な嘘並べるな。
オブジェクト「a」そのものは配列であり、その右辺値が「配列の先頭を指すポインタ」になるだけだ。
>>120 2ちゃんに書き込む人間はみんな糞ですがなにか?
オレモナー
122 :
デフォルトの名無しさん:2008/07/29(火) 12:06:30
>char * str2 = "abcde";
いまだにここが分からない
ポインタに何故文字列を代入できるの?
>>122 "abcde"はconstな文字列(≒char配列)ですが、右辺値はconstな文字列へのポインタになります。従って、代入できるわけです。
char foo[] = "abcde"した後、char * p = fooと言うように代入できるのと同じことです。
>>122 それは文字列の書かれてる場所を教えてるだけ。
文字列自体は別にある。
だからその後に str2 = NULL; なんてやったら、"abcde" のありかは永久に失われる。
125 :
デフォルトの名無しさん:2008/07/29(火) 12:50:00
char * str2 = "abcde";
の"abcde"はstaticな感じって言えばいいのかな?
constな無名変数とでも言うか
126 :
デフォルトの名無しさん:2008/07/29(火) 13:31:55
回りくどい言い方になるが、コード上は文字列を代入してる形だけど、実際は数字を扱ってるだけ
たとえば、右辺に"abcde"を書くということは、
あるアドレス(仮にXとする)に対して、
Xにaの文字コード97をセット
X+1にbの文字コード98をセット
X+2にcの文字コード99をセット
X+3にdの文字コード100をセット
X+4にeの文字コード101をセット
X+5に0をセット
以上を行って、左辺にXを渡している
上の例だと、*(str+3)をintにでもキャストして眺めると、100が入ってるはず
この領域は変更付加
その意味ではstaticだけど、配列の宣言と一緒にやった場合は例外
詳しくは、「文字列リテラルの変更」でググると解説が
127 :
デフォルトの名無しさん:2008/07/29(火) 13:44:37
115は良くある間違いで、(わかってて書いてたらスマン)120の言うとおりCの配列とポインタは明確に別物
どちらで宣言するかで、動作が変わる
具体的に言うと、sizeof()の動作が、ポインタの場合はポインタのサイズ(通常は4)を返すが、
配列の場合は使用バイト数を返す
混乱のもとは、[]記号が、宣言、右辺値、左辺値、それぞれのケースで意味が微妙に違うところ
整理してないと、すぐわからなくなる
>char (*a)[128];
こういう表現って普通に使います?
おいら使ったことないんだけど。
泉源寺に()つけちゃって大丈夫なんだっけ
配列へのポインタ(≠ポインタのポインタ)が必要なときはそうせざるを得ないね。
そんな宣言はしない
使う時にキャストするから。
>>129 横WIDTH個、縦HEIGHT個の長方形のchar配列を動的に確保したい時、
char (*tbl)[WIDTH] = malloc(sizeof(char)*WIDTH*HEIGHT);
とかやる。
tbl[y][x] = data;
とかいうふうにアクセスする。
>>130 論外
>>132 おまえだけ
私は
char * tbl = malloc(WIDTH * HEIGHT)で確保して、
static inline unsigned offset(int width, int x, int y) {return x + y * width;}みたいな関数を用意して、
tbl[offset(WIDTH, x, y)] = dataと言う風にアクセスするかな。
>>133 なるほどそういうことですか。ようやく意味がわかりました。
サンプルのためのサンプルじゃなくて、実際的なシチュエーションが思いつかん。
まったく無責任な想像だが、メッセージ通信処理とかで使えそうかなぁ。
1個のチャンクが固定長でうんちゃらかんちゃらとか。まーよー知らんけど。
メッセージ通信でポインタ使う奴の気が知れない。
リストとツリーをC言語で自力で実装できるぐらいポインタを理解しておけば、
現実問題としてポインタ周りで困ることはあんまりないな。
char (*p)[4];
って有ったとき、p++てやると、
pは4バイト移動するって考えると分かりやすいな。
>>139 で、実際はそうはならないので混乱する、と。
でも混乱するのは理解が足りない所為だよ。
>>136 処理を順次実行したい場合の関数ポインタの配列とか。
後は可読性を捨ててでも処理速度を稼ぎたい時とかかなぁ。
使わない方がコード的に遅くて長くても安全って場合の方が多いよなぁ。
特に複数人でコードを書く場合は。
ぱっと見で動きの想像しにくいポインタの使い方はちょっとなあ。
2次元以上だったら最大値規定して最初から配列取るわ。
>>133 それC99じゃないとWIDTHを変数にできないから困る。
できればやりたいんだけどね。
define
#define PTA(sex) *(sex)
#define TRF(sex) &sex
main(int itn, char PTA PTA)
{
int itn;
scanf("%d", TRF(itn));
write(itn, 4);
}
146 :
デフォルトの名無しさん:2008/08/01(金) 20:47:45
int a[100] = { 1, 2, 3, 4, 5,・・・・,100 };
int *po;
po = a;
int cnt;
1)
for( cnt = 0 ; cnt < 100 ; cnt++ ){
int *********************************a;
149 :
デフォルトの名無しさん:2008/08/02(土) 03:41:14
a.next->next->prev->next->next->name = "shine
>>148";
輝け148
昔、トリプルポインタを使っているコードを業務で見た。
それ自体はよくできているプログラムだし、公開されているインタフェースも
ちゃんとしていた。しかしまぁ、これを作った人(ベテランプログラマー)は
よく自分で理解できるもんだ、と素直に関心した。
終始ビット演算を使われるよりまし
むしろ何で理解できないかが理解できない
そういうこと言う奴は理解してない
5次元配列をいくつか使っているソースみて爆死した。
書いた本人はリタイアして該当コードは最初から書き直しになった。
多次元配列を扱う部分だけLispのコードから生成するとかはやるよ
ルールが決まってて単純にそのルールを繰替えし適用するだけだから
機械にやらせた方が絶対安全
配列なんて、マトリックス構成する要素が幾つにでもなるから
何次元だろうとどうでもいいじゃん。
量子化学計算やるには5次元配列が普通に必要になるよ。
小原積分計算する時に。
といいつつ、まあ実際には普通の配列にはしないんだけどな・・・。
>>151 ポインタにダブルだとかトリプルだとか属性があるような解釈の仕方をするから理解できないんじゃないの?
アスタリスクが並ぶのがいやならtypedefすればいいだけの話だし、そうしてしまえばただのポインタと同じことじゃないか。
関数ポインタを引数に取る関数ポインタの二次元配列とか
そういうのになってくると泣ける程複雑になる
こういうのってtypedef使ってもいいんだよね?
よくポインタの理解度を試すようなクイズで「typedefを使わずに」とかあるけど、
日常的に使っててもできる気がしないわ
人間がコンパイラになる必要は無いんだから
そういうクイズは無視でおkだと思う
void (*fnc[YLEN][XLEN])(int(*)(int));
Cエキスパート:出来るけど見にくいからtypedef
なんちゃってプログラマ:出来ないからtypedef、人間コンパイラになる必要はないと言い訳
typedefは見やすくするためにあるんじゃなくて、
型を抽象化するために使うべきだと思う。
関数ポインタは積極的に typedef しとけ。他は必要なし。
そういうのが直ぐできるようになるにはどうすりゃいいんだろうな
規格からルールを理解すれば少しは楽になるんだろうかね?
簡単にエキスパートになる方法を教えろと言ってるんですね、わかりません
GCCのソース読むのが近道
読めなければそれが読めるようになるまで簡単な物から読んだり
パッチ作ったりしてオープンソースコミュニティに貢献してりゃ10年もすりゃ
今君が想像してる程度のエキスパートには楽になれる
って以前言われたことがある
10年かあ・・・
確かに俺がブラインドタッチできるように
なったのは、毎日PCをさわるようになって
10年くらい経ってからのような気がする。
人間、何事も10年は精進が必要なんだね。
GCCってそんないいソースか?
ブラインドタッチに10年って・・・・身体障害者の方ですか
>>171 いや、10年くらいかかっても不思議じゃないと思うぜ。
人さし指タイピングから始めた俺は、タッチタイピングに切替えるだけでかなりの年月を費したが。
それでもまだブラインドタッチにはたどり着けない。
英語キーボードと日本語キーボードを行ったり来たりした日にはもう大変。
gaucheの作者も昔HPで
どんな言語でも10年は使わなきゃほげほげって書いてたからだいたいあってると思う
タイピングなんて我流でいいよ
どうせ出力見ただけじゃ経過は見えないんだから
出力だけ要求されるならそれでもいいが
運指が偏ってると年食ってからバネ指とか悪影響もあるから気をつけろ
年とると管理業務になるので問題ないです
>>166 無理に使わなくていいと思うぞ。それを必要と感じる時が来たらそうすればいいんじゃないか。
#include <windows.h>
#define typedef_func_ptr(returntype, yobidasikiyaku ,functionname) \
returntype (yobidasikiyaku * functionname)
main()
{
typedef_func_ptr(int, WINAPI, ptrMessageBox)(HWND, LPSTR, LPSTR, UINT);
ptrMessageBox = MessageBox;
ptrMessageBox (NULL, "セクロス", "セクロス", MB_OK);
}
ポインタ?あれはショートカットだショートカット
っていうセンパイの言葉でわかった
180 :
デフォルトの名無しさん:2008/09/07(日) 10:13:02
たとえ話は、ポインタの理解の役には立たない。
これ定説。
使って覚えろ
これが基本ですね、マクロしかりテンプレートしかり各種ライブラリしかり
アドレスとデータの区別がつけば、あとは簡単。
矢印と箱の差。
図を描いてみればアホでもわかるだろ。描こうともしないでわからないとかほざく無能は氏ね。
構造を把握したうえで、「たぐりよせる」操作と「矢印を作る」操作がわかればあとは簡単。
たとえ話で説明するやつの理解はけっこアヤシイ。
ところで、ポインタには型がある事をお忘れなく。
>>184 例えを用いずに話して相手が理解出来るなら最初っから躓いてないだろ。
例えを用いずにうまく説明できないところがアヤシイw
本当にわかっている人は例えなんか使わない。
実際にPGを組ませてビシビシしごく。
ついてこれない香具師は見捨てる。
>>185-186 喩え話ってのはどーしたって誤謬があるわけで
「理解“した気に”させる」効果しかない。
メモリ上にデータが配置されるイメージさえつかめば
ポインタ使ったプログラムの動きは見えてくるんだよな。
そんな低レベルなことまで意識しなきゃならないというのは、
教える側にするとちょっと面倒でもある。
ポインタ自体が低レベルな操作のためにあるもんだし
なんかもー面倒くさいからポインタ禁止にしてこんな感じのクラス使おうよw
template<classT>
class Shortcut
{
T *pTarget;
// ショートカットを設定
void SetShortcut( T &target ) { pTarget = ⌖ }
// ショートカット先にデータを設定
void SetData( T data ) { *pTarget = data; }
};
名前は
>>179から頂きますた。
そしてスマポへ…
それoperator=とかoperator*とかoperator->とか実装すると便利だよきっとたぶんおそらく
C++使ってるとポインタ演算をしなくなるな
STLは使わんの?
アレは見た目が似てるだけか。スマソ。
mplの
metafunc<type>もポインタっぽく思える
metafunc<type>::valueとかで参照できたりするし
Cのポインタ演算子*が悪い。かけ算記号と同じなんだもの。
この点だけは、リッチー先生を殴る権利が俺たちにあると思うよ。
俺が言語設計者なら、Data_Pointed_by(ポインタ変数)にする。
あとポインタ変数の型をなくし、すべて1バイトを示すものとする。
ポインタ変数のインクリメント・デクリメントも1バイト単位。
>>199 どうしてもポインタをモノにできなかった奴の定番台詞ですな
>>199 それなんてCのご先祖様BCPL、特に後半。
ポインタの概念を図で説明するときにアドレスの存在を明示しないやつがたまにいるんだよな。
四角から四角へ矢印を引いた図は書けるんだけど、アドレスの存在が意識されにくい図になってる。
つまりこんな図。
□→□
int aという変数にはaという値と&aという値があり、
int *pという変数にはpという値と&pという値と*pという値がある。
これらの5つの要素を図中に明示しないと上手な説明とはいえないね。
初心者ですが教えてください。
ポインタ演算で型に応じてポインタが進むのは知っているのですが、
その「どの型ならいくつ進む」という情報は実行ファイル中にどういうふうに保存されているのでしょう?
>>204 静的に決まる型を解釈して、そういう言うアセンブラコードに変換されてるんだよ
坊や。
動的に決定する型はどうやって決定されるんだろうね。
ああ、CやC++じゃそんな芸当出来ないかw
>>204 コンパイラが吐いたasm読めば分かるよ。
よく分からなかったら、型を変えて見比べてみる。
>>203 ポインタの俺解釈いいかげんおなかいっぱい
>>206 Cは兎も角、C++にはRTTIってもんがあるわけだが。
C++のRTTIはデバッグ用途以外では要らない子
>>210 いやいやdynamic_castはデバッグ用途ではないだろ。
しょっちゅう使うものでもないけれど。
×dynamic_castでオブジェクトの型を判別し、そのオブジェクトのメンバ関数を呼び分ける
→わざわざ多態性のメリットを殺さずに、仮想関数で解決すべき。
○dynamic_castでオブジェクトの型を判別し、判別している側の振る舞いを変える
→これはあり得る。けど委譲で解決したいかな。
それは、動的に判定されるというより、
予め考えられる型を全部網羅してコーディングしてるだけだしなぁ。
新たに組み込んだhogehogeクラスのポインタとか実装が無いと動かんだろ?
あ、仮想関数で呼んでもらえば自前で用意しておくだけで追加が簡単か/
JavaやC#でこういう感じのコードに時々出食わす。
setObject(new Hoge);
//別のところ
Hoge h = (Hoge)getObject(); //戻り値の型はObject型
帰ってくるオブジェクトは絶対さっきsetObjectしたときの引数という場合。
もしこれがC++だったらboost::polymorphic_downcastの出番だな。
>>214 インターフェースを利用できない理由があるの?
216 :
デフォルトの名無しさん:2008/09/11(木) 20:59:10
C言語には文字列がないので文字列ポインタ作っちゃいました的ナ
>>215 setObjectやgetObjectは既存のライブラリで、しかも標準だったり有名だったりして
自分が手を加えられるような存在ではないんだ。
Cの文字列型は廃止の方向で…
メモリモデルよくわからない
プログラマにメモリを意識させる言語は糞。
Javaが理想に近いが、記述が冗長すぎてこれも結局は糞。
これからはロジック書きのみに集中できてシンプルな
記述で済む言語がトレンドになる。
スクリプト系?
ML系やLispのようなLL言語ですね
ロジックといえばprologやマイナーですがCoq, ETIも見逃せません
>>220 バターナイフ振り回して「包丁は危険だから糞」って言ってる訳ですね、わかります
プロセス空間とかよくわかんない
糞かどうかはともかく、誰にでも向くものではないのは確かだね。
まあJavaでも十分メモリを意識すると思うが。
>>219 メモリモデルはポインタとかより遙かに悩ましいね。
229 :
デフォルトの名無しさん:2008/10/04(土) 11:47:17
あげ
230 :
デフォルトの名無しさん:2008/10/04(土) 12:01:50
char str1[] = "abcde";
char * str2 = "abcde";
>上と下は同じでどっちを使ってもいい。
これは間違い。str1は書き込みできるが、str2は書き込みができないことがある。
>>230 どっちも書き込めないときがあるだろ。
パソコン上ではどちらも書き込めるが、
ROM化環境などではどちらも固定される事がある。
これらの最大の違いは、sizeof(); で返される値。
char str1[] = "abcde";
char * str2 = "abcde";
printf("%d¥n",sizeof(str1));
printf("%d¥n",sizeof(str2));
やってみそ
233 :
デフォルトの名無しさん:2008/10/04(土) 12:28:59
要はアドレスという概念がわかっているかどうか。
あとは書式の問題でなれだな。
てすぐ結論をだそうとする漏れorz..
>>231 配列に書き込めないコンパイラがあるの?
オプション次第では、str1も書き込みできないようにできるものがあるかもしれないが、
そんなこと言ったらきりないだろ。
str1にconstがついているなら文句なしに書き込み不可だけど。
>>234 多分、配列自体に代入する式が評価中に存在すれば固定領域ではなく揮発領域に設定されるんだろうな。
まあ、ポインタという代物はその操作をコンパイラには分からせなくするチカラもある訳で、
配列で指定した領域にポインタ参照で書き込もうとしたら落ちるとかはあるよ。
>>236 すまんが何をいってるのかさっぱりだ
バッググラウンドを簡単に説明してくれないか
○○と言う本やコンパイラのマニュアルに書いてあった、でもいいから
>>237 「世間には色んなコンパイラがある」ってこと。
char s[] = "abcde";
ポインタ経由だと、これに書き込めない環境があるってこと?
ないだろ。
>>239 最適化されてなければな。
だからおまいの脳内環境だけで結論出すなよw
最適化されたからって、書き込めなくなるのはおかしいだろ。
ないってのは言いすぎだな。
ウンコな処理系ってよくあるから。
処理系じゃなくって、コンパイラの問題なの。
「処理系」ってコンパイラも含んでるだろ。ふつー。
ああ、分野が違うとこうも話が噛み合ないという見本だな。
知ったかでしゃべってるのを「分野の違い」にすんなよ。
>>239 が、ポインタ経由だと書き込めないってどんな処理系だよ。
>>246 だからさ、世の中には色んなコンパイラがあって、色んな環境で色んなCPUが色んな場所で動いてるわけよ。
その全部のローカルな俺様コンパイラ的な物では定数は全部固定データなワケよ。
特に初期化宣言以降どこに右辺に現れない変数も固定な訳よ。 わかる?
>>247 ああ、適正だ。
どこにも左辺に現れない変数な。
>>247 定数を書き込み禁止領域に置くコンパイラってこと?
それごく普通のコンパイラじゃん
文字列リテラルを書き換えようとして落ちるのはANSI仕様上も問題ない
知ったか乙
どうやら今日は誤字が多いのでこの辺で消える。
というか日本語の上手な人か
言わんとすることはわかったよ
>>247 おたくの「分野」の、どのコンパイラでそういう最適化をするのか書けばいっぱつで終了する話題だろ。
>>249 だからさ、
char t[] = "abc";
t[0] = "0";
とかあれば、このtは書き換え出来る領域に"abc"をコピーしてくるけど、
char t[] = "abc";
char *p;
p = &t[1];
*p = "0";
とかすると、落ちるとか普通にある訳よ。
まあ、コンパイラがANSIに沿ってないってオチなんてドコにでもあるわけで。
そんな事言ってちゃ、ここでマトモな議論が出来なくなるわけで。
>>253 落ちるどころかコンパイルすら通らないだろうな
まぁ、組み込み系だろうな、そういうコンパイラがあるのは。
PICとかPICとか、あとはPICとか。
>>231 > パソコン上ではどちらも書き込めるが、
> ROM化環境などではどちらも固定される事がある。
知ったか乙
汎用OS下でも処理系によって違うんだよ。
そもそもANSI読んだのか?
>>258 PIC?あんなヘタレ石に組込みを代表されてたまるかいw
>>259 処理系によって異なるのに、ANSI読んでも意味無いだろw
>>261 規格で「パソコン上ではどちらも書き込める」ように定められてるかどうか、そうでないか確認するんだから、意味あるだろ。
>>262 ANSIにそんな但し書きあるなら見てみるワ
>>263 但し書きがないんなら「> パソコン上ではどちらも書き込めるが」ってのはウソってことか?
>>264 それはWindows上のVCの実際の動きから書いてるから嘘じゃないだろ。
>>265 べつに特定の環境の話はしてないだろ。
書き込める環境もあるし、書き込めないのもあるって話だから、
>>231がウソってことになる。
いつから汎用機がパソコンという名前になったんだろう? ? ?
そもそもこの流れで「パソコン」って表現は意味が無いだろ。
ポインタはヤバイぞ・・・
ポインタのポインタとか、
二次元配列のポインタを取る時に
= の右がconstだったりすると左が酷いことになる
まずそんなことはやらないとは思うけど
そんなことやってもまあコンパイル時に警告かエラーだけどな。
>>270 警告だったら無視する習慣があったら、実行時に死亡だね?
警告って事は何かしら書き方間違えているわけで
無視しても問題ないものでもなるべく除去するよう心がけるべき
main関数の引数を使ってませんよ的な警告も無視しちゃだめですか
Visual C++で警告レベルW4にしてSTLを使ってみれば楽しいよ
>>273 int main()でいいじゃない。
argvだけ使って、argcは使っていないというのなら、int main(int, char** argv)で。
>>127 > 混乱のもとは、[]記号が、宣言、右辺値、左辺値、それぞれのケースで意味が微妙に違うところ
プリーズ詳しく
突っ込むのも面倒と思われるくらいに呆れられたんでしょ。
t[0] = "0"; とかありえないし。
t[0] = '0'; じゃね?
main(){
char *t[1];
t[0] = (char *)malloc(072);
t[0] = "0";
puts(t[0]);
}
malloc いらんがな
>>282 malloc無いとメモリリークしないだろ
>>283 しないよ。直後にmain()から抜けているから。
それより、なんで58バイト確保するのかそっちが知りたい。
三度の飯より072好きだからだろう。
おまえらしってるか
円周率にはある言葉が隠されているということを!
円周率という永久に続く小数
3.1415926…
これの小数点第93299341桁目から先をみてほしい
…0721454525520877136375156…
最初の8文字に着目だ。
そう"07214545"とは「オナニーしこしこ」のことある。
これはどういうことだ?
神は我々に何を訴えようとしているんだ…
わからないのことある。
無理数なら、そんな数列はどれでも出現するわボケ
どれでも? 無理数の定義からやり直せカス
むりっす
無理数だけに、むりっすうwww
大事なことなので日をわけて2回言ったんですね。
>>286 なに、オナニーで演習することが大事だといっているのです。簡単なことです。♂も♀も。
ポインタで正整数しか指せない時代はもう終わり
そろそろ浮動小数アドレスとか複素数アドレスとか出てきてもいい頃
いやその前に負数アドレスが先か
ネタが滑っただけ
x64のアドレス空間なんか符号付き整数だといっても差支えないような構成に思える。
その昔、8ビットCPUの時代にも最上位ビットでROM空間とRAM空間を区別するのはよくある手でしたが。
>>298 それはROMとRAMを32KBずつ割り当ててるだけジャン
0000-7FFF : ROM
8000-FFFF : RAM
今見ると少ないメモリでよくやってたな
ROMは下から使ってRAMは上から使うんだから、符号付整数として捉えてもいいじゃんw
>>300 32KiB + 32KiB 以外の構成は思いつかないのかアホタレ。
それ以外の構成でもスタックを最上位に配置する関係から、アドレス0から上下になるように配置するのが普通だと思うが。
アドレスバスをフルデコードしないでミラーイメージになっている場合もあるだろうけど。
例えばRAM48Kだと0x0000〜0xBFFFなわけだが。
>>303 素朴な疑問だけど、その環境で0c000h-0ffffhは何もない状態なの?
例えば8080やz80のようにリセット直後にはSPが0になるようなCPUだったら
SPを設定するまでスタックが使えなくて不便だと思うのだけど。
つーか、>302が想定している次元と>303が想定している次元が噛み合ってない希ガス。
>>304 「符号付整数」だと捉えると、アドレス範囲が
0x8000〜0xFFFF、0x0000〜0x7FFF となって
非常に見づらくね?つか上下逆にならね?」
程度の主張。
そういえば (
>>294 は知らんだろうが) ポインタが
{アドレス, バイト位置} だの {セグメント, オフセット} だのという
構造を持ってるてのは有り得る。
>素朴な疑問だけど、その環境で0c000h-0ffffhは何もない状態なの?
ROMがないなどとは一言も書いてないんだけど、何でそう思ったのか。
>8080やz80のようにリセット直後にはSPが0
PCも 0x0000。
相対アドレスだって結局はどこかの物理メモリにマッピングされるだろ
どうやっても、一意に区別出来る情報の形になるからデジタルなんですよ。
かならずしも物理メモリにマッピングされてるとは限らないだろ。
I/Oだったり、スワップアウトされてたり。
論理メモリーには物理メモリーにマッピングされていない闇の空間がある。
ポインタってアドレス型とかいう名前にしとけばよかったのに
アドレスという概念を抽象化したかったのでは?
実際、アドレスひとつに1バイト割り当てられてたわけじゃないし。
ポインタは別に難しくない。
ポインタが難しいと勘違いされているのは、Cでは「配列のサイズチェックをしない」というポリシーがある
ために、バグで配列の範囲外をポイントしてしまったとき、デバッグが難しくなるからだ。
また、1個のオブジェクトへのポインタも、オブジェクトの配列へのポインタも、同じに扱われることも
(これも、大きな意味では「サイズチェックをしない」ことの弊害だ)難しさを倍加している。
もしこれが、「オブジェクトへの参照」であり、更に、「確保されたオブジェクト範囲外をアクセスすると
アサーションが発生する」という仕様であれば、ポインタなんて全然難しくない。
結局ポインタのせいにしているだけで、ポインタが難しいと思っている人は、
Cの「出来る限り高速に、出来る限りチェックは省き、プログラマは完全無欠であるべき」
というポリシーに付いていけないだけだと思う。
付いていけないから難しいと言うわけで
ポインターってのは、Cが、アセンブラのへのラッパー言語だと割り切れる奴しか扱えないんだよ。
右辺値と左辺値の場合で参照レベルがひとつずれているように見ようと思えば見えるから、
そう見えちゃうとハマるんじゃねーの。
int a, b;
a=b;
aは変数、bは変数の中に入っている値
int a, *b;
a=*b;
*bは bという場所に入っている数値をアドレスとしてみて、そのアドレスの中にある値
*b=a;
*bはbという場所に入っている数値をアドレスとしてみたその場所で、その中にaの中の値を入れる
てな感じで。
左辺値だと代入する場所、右辺値だとその場所にある値、と参照レベルが一段変わる(用に見えなくもない)
shellだとaに値を代入するときはa=b、値を参照するときは$aで、aは変数、$をつけるとその値、とまあ参照レベルが統一されている。
と、ポインタわからんという人がなぜ出るのかを考えていたらそういうこともあるんじゃねーのかな、という結論に至った。
>>316 それは、理解できる人間の理屈。理解できない人はそんなレベルで理解できていないわけではない。
ある意味、虫食い算は計算できるのに方程式が解けないと嘆く中学生のようなもんだ。
318 :
デフォルトの名無しさん:2009/02/04(水) 11:04:42
ポインタの記号ってドルマークの方が良かったと思う
アスタリスクだと掛け算とごっちゃになるから嫌いなんだよ
単項演算子が二項演算子とごっちゃになるとは
是如何に。
a*=b と a=*b とか
a**b とかじゃないの?
a+++++b ?
*a*b
>>318 >>6 >>320 大昔のHP-Cで =* という独自拡張された演算子
(*= と同じなんだけど、式の値は演算“前”の左辺) があって
a=*b なんて書くと「ambiguous だぜ。演算子の後ろに空白入れな。」
という警告をくらったのを思い出した。
bがポインタかどうかで判断つくだろうに。
つか、誰が得するんだあの拡張。
>>323 無能なプログラマほど、空白を詰めて書きたがる。
で、そういう馬鹿なミスをやって人件費を無駄遣い。
それからな、=* の類は「独自拡張」じゃないぞ。
>>324 >無能なプログラマほど、空白を詰めて書きたがる。
for 内部の代入は空白あけないぞスタイルだったもんで。
>で、そういう馬鹿なミスをやって人件費を無駄遣い。
コンパイル時に警告出てんだから
数秒以内で修正可能なレベルだろに。
大袈裟だな君は。
> =* の類は「独自拡張」じゃないぞ。
mjsk
> > =* の類は「独自拡張」じゃないぞ。
> mjsk
こんなことも知らん割には、ずいぶん上から目線だな。
>>326 >こんなことも知らん
と
>ずいぶん上から目線だな。
に、なんの相関が?
つか、
>>325 程度で「上から目線」て
どんだけ繊細なんだ。
>>326 みたいな言われ方したら
ショックで死ぬんじゃないの?
ご自愛下さい。
328 :
327:2009/02/05(木) 14:05:22
C++のイテレータってのはポインタ使って動いてるんだよな?
特にvectorとかでそういう実装はあり得る。
でも、listなど中の実装もそうであるとは限らない。
もちろん、使う側の見かけはもちろんポインタの模倣だけど。
ほうほう,ありがと
vector は VC++6 あたりではポインタだったような気がする。
今はポインタで実装してる方が珍しいと思うが。
if for 変数 なんかの説明と比べればポインタは難しいよ
一度、誰かに教えようとすれば説明のし辛さが解る
文字と文字列の扱いの違いから説明してるけどな
まぁ配列の扱い方とポインタの扱いがちょっと似てるからだけど
入りとしてはやさしいとおもってやってる
操作的意味論を使ってポインタを理解したい
ポインタの理解度段階付け
0.javaマンセー
1.ポインタを使ったプログラムが読める
2.ポインタの使い方が解る。
3.ポインタを効果的に使える。
ex.ポインタを誰でも分かるように説明できる
間接参照のセマンティクス
#include <stdio.h>
#include <stdlib.h>
int main(int ac, char *av[]){
FILE *write = fopen("test.txt", "w");
FILE *read = fopen("08112801.L81", "rb");
while(!feof(read)){
int j;
for(j = 0; j < 4096; j++){
unsigned short ch1, ch2;
fread(&ch1, 2, 1, read);
fread(&ch2, 2, 1, read);
fprintf(write, "%u %u\n", ch1, ch2);
}
}
fclose(read);
fclose(write);
return 0;
}
>>337 猿や犬、またはそれに類する人間には
どう頑張ったところで理解できません。
476氏がすごいことになってます
〜はじまり〜
476 名前:デフォルトの名無しさん[] 投稿日:2009/02/16(月) 11:13:14
2次元配列のキャストとかがわかんないです。
ここでつまずく。
〜中略〜
643 名前:476[] 投稿日:2009/02/18(水) 00:33:00 (略あり)
int a[10]:
int *p;
int p=a &aでもなくていいです a(名前)は先頭のアドレスをあらわします
一次元までわかってるんです
>その例で&aと書いたら何になるか答えられるか?
649 名前:476[] 投稿日:2009/02/18(水) 00:37:14
&aだとa[0]だと思います
もう教えてください
どうすれば(*p)[5]と(float *)までたどり着けるか教えてください
脳みそ取り替えたいくらいです
脳みそ取り替えてください本当に
476氏 その2
654 名前:476[] 投稿日:2009/02/18(水) 00:42:47
641さん
よくある本の最初に書いてあるポインタくらいならわかります
int x;
printf("%p",&x);など 一次元配列のポインタなどわかります
ですがある日突然
float balance[10][5];
float *p;
p=(float *) balance;
*(p+(3+5)+1)という最悪のパターンにであいました
独習Cですんなりいってたんですが165ページという最悪のページでモヤモヤが一気にでしました
キャストは前のページにでてきて doubleをint型に変換する簡単なものでした
double i=100.2;
printf("%d",(int)i);みたいな簡単なキャスト
ですがポインタのキャストという説明も無くそんなのがでました
(float *)という意味深な物が とまどいました
調べました よくわかりません
float[n]とかいわれてもわかりません nっていうのはfloat[1]とかfloat[2]ですか?
さっぱりわかりません脳みそとりかえたいくらいです 助けてください
660 名前:デフォルトの名無しさん[] 投稿日:2009/02/18(水) 00:57:33
>>656 この問題分かるか?ポインタがきちんと理解できていれば分かるだろう。
long x;
short y[5] = {1,2,3,4,5};
x = (long) y;
x++;
printf("%d\n",*((int*)x));
このコードを実行した際に表示される数値は何か予想せよ。
(理由とともに。なお、longは8バイト、intは4バイト、shortは2バイトとする)
661 名前:476[] 投稿日:2009/02/18(水) 00:57:39
何故皆さんそんなわかるんですか?
おかしすぎです
なにやってたんですか
私はもう寝ます
明日もまた質問するのでよろしくお願いします
この問題が解消されないとむかついてストレスたまります
662 名前:デフォルトの名無しさん[sage] 投稿日:2009/02/18(水) 00:59:37
>>660 javaに毒されすぎじゃないか?
663 名前:デフォルトの名無しさん[sage] 投稿日:2009/02/18(水) 00:59:47
>>654の文章がひどいと思ったが、
>>661は、もう寝たか?
コピペにマジレスしてみるが、
ポインタをきちんと分かってる人は、こんな不可解なポインタの使い方はしないな。
しなくてもいいけど読めないならやり直せ
そういう人がC使うと危ない
エンディアン、ウソつかない
LLP64環境でやったらマジ脂肪だな
longは8バイトって但し書きがあるじゃん
こやつめw
質問内容は「予想」なんだけどな
ミドルエンディアンの場合も想定してはじめて満点とか
>>352 だから「この設問の条件では予測不可能」という回答なんだろ
寧ろこっちから「この問題はデキが悪い。0点」と言い放つ。
そうやって逃げてばかりいるから、そんななんだよ
どんなだw
>>346って答えておけばいいんだろ。
これ言われてピンとこなかったら出題者がアホ
「予想せよ」だから、ありそうな順にいくつか答えるって手もあるのかな?
ポインタなんてbrainf*ck使えばわかるよ
超初心者の質問ですが、いいですか?
int v,*po;
po=&v;
*po=300;
のように、ポインタ変数poが指す内容は変数vのアドレスである、ということですが、
char *jk;
jk="jyosikousei";
のように、ポインタの中に文字列を直接入れられるのはどうしてですか?
この場合、ポインタ変数jkは'j'の文字が格納されているアドレスを指しているということでしょうが、なぜそこに文字列"jyosikousei"を直接代入できるんですか?
'j'の文字が格納されているアドレスの先頭、でした
>>362 文字列は代入されてない
"jyosikousei"がchar*型だからcharポインタが代入されてる
>>364 つまり、
jk="jyosikousei";
という文によって、jkに'j'の先頭アドレスが代入されているということでしょうか?
とすると、'j'の先頭1バイトが格納されている変数が宣言されていないのに、jkにアドレスが代入されるというのはおかしくないですか?
int *i;
i=100;
だと、iがどの変数のアドレスを指しているか決定されていないからNGでしょう。
どうしてchar型のポインタ変数にかぎり、直接文字列を代入する文を書けるのでしょうか?
"hogehoge" と書くと、プログラムファイルのどこかにその文字列をコンパイラが置いてくれるので
その先頭のアドレスが帰ってくると思えばよい
100 とかの場合はそうならない(アドレスが存在しない)のでダメ
あと "jyo" というローマ字はヘボン式としても訓令式としても正しくない
>あと "jyo" というローマ字はヘボン式としても訓令式としても正しくない
しかし、一般に流布している。
スレタイに沿うなら、
>>362 に対しては
「なんでそんなことも判らんのか判らん」
で終わりなのに、なんて親切な奴だ。惚れそう。
>>369 私は突っ込みを入れただけだ。>362なんかと一緒にするな。
Cのポインタの難しい(かつ便利)なところは、こんなふうに1個のオブジェクトへのポインタなのか、
オブジェクトの配列へのポインタなのか、区別がつかないところなのだなあ。詠嘆調。
char (*a)[2] ; /* 配列へのポインタ とかいってみる いや、言ってることは解ってるけど*/
>>365 >int *i;
>i=100;
>だと、iがどの変数のアドレスを指しているか決定されていないからNGでしょう
いいえ
どの変数のアドレスを指しているか決定されていないからNGなのは
*i = 〜; であって i = 〜; ではありません
同様に *jk = 〜; はダメですが jk = 〜; は問題ない
int *i;
i=100;
これはポインタ指定だからオK。
int *i;
*i=100;
これは実数指定だが、どこのポインタに? って事でアウト。
って事だぁね
i = (int*)100;
と書いて欲しい
区別がないから初心者には難しいんだよなって言ってるのがわからんのかマヌケ
マヌケはお前だ。
質問は
「区別がつく?」
ではなく
「区別がつく必要ある?」
だろ。
必要性と可能性の違いもわからんのか。
二日も考えてその程度のレスしか出来んとは気の毒なアタマだな(プ
区別をしないというのがC言語の(設計者の)選択。
煽りはともかくとして、結局どういう風に難しいのか一言も言えてないじゃん。
難しいと思うのは本人のセンスのせいで、
ポインタのせいでは無い。
配列名の値がアドレスになるのがわかりにくいというか、誤解の元になってるとは思う。
それが難しいかどうかは知らん。何でそうなるのかぐらいわかれとも思うが。
○記号の問題
*, &, などの変てこな記号が入り乱れ、学習者にとっては「うかつに近づくな」気配がぷんぷんする。
○配列の問題
int* p; としたpが1個のオブジェクトを指しているのか、配列のアドレスを指しているのか区別が無い。
その「区別が無い」という概念を理解することが重要なのに、大抵の教科書には
表面的な「アドレスである」という表記しかないので混乱の元になっている。
○バグりやすい問題
ポインタはオブジェクトを指してこそ意味があるのだが、cでは文法上オブジェクトの範囲外でも
平気でアクセス出来てしまう。例えばchar buf[256];としたbufをサブルーチンに渡し、buf[800] = 'x';
とか出来ちゃう。そしてバグる。こういう「他の(高級)言語では有り得ないバグ」が難しいと思わせる原因。
プログラミングや計算機の初心者には、
うかつに近づかないでほしい。
オブジェクトじゃなくて、メソッドを指してるんじゃね?
387 :
デフォルトの名無しさん:2009/09/08(火) 14:50:07
誤爆?
記号の問題に関しては、初心者は見よう見まねでperlいじったりするみたいだが。
あー、perl自体じゃないよ。スクリプトね
>>384 2項目目の意味がよくわからないな。
ポインタはアドレスを指すだけだろ。
なんだよ「区別」って。
>アドレスを指す
とりあえず動かしたくないポインタは*constにすりゃいいんじゃね
393 :
デフォルトの名無しさん:2010/01/07(木) 19:05:12
どうしてポインタは*を選んだのだろうか
$でも良かったでしょ
ポインタに1足したら、2byteとか4byteとか進む?
ポインタってアドレスなんだろ?
そんなもん1進むに決まってるんじゃないのか?
ポインタには、どこを指してるかと指してるものの型の2つの情報がある。
後者を説明してない解説は結構多い。
>>394 ポインタはアドレスではないかも知れない。
特に、アドレスがバイト単位にふられてない場合は確実に。
今時あるのかどうか知らんが。
>>55 禿しく同意。
ここまでアナルが出てないってどういうことだよな
*
>>394 たとえば、32bit整数型は1byte(8byte)では収まらない。4byte(32bit)必要だよな?だから4byteずつ進むのは間違いではないよ。
あとはハードウェアの都合という面もある。「アドレス パディング」や「アドレス アライメント」で調べるとヒントが得られるかと思うよ。
それでも解らないならオープンソースのコンパイラを解析するしかないんじゃないかと。
もしかして8bit
ポインタがそういう仕様だ、ってだけだろ。
ポインタが指しているのは、アドレスじゃなくオブジェクト
>>399 >たとえば、32bit整数型は1byte(8byte)では収まらない。4byte(32bit)必要だよな?だから4byteずつ進むのは間違いではないよ
うそはいかん。ポインタへのポインタだったら4バイトずつ進むが、型のサイズ分のバイト数がすすむ。
つまり、sizeof 型 だけ進む。 なぜかって?そのほうが都合がいいから。
だから、ポインタが指しているのは、アドレスじゃなくオブジェクト
ポインタを1つ進めるということは、次のオブジェクトを指すというだけの話
アドレスが○○バイト進むというのは、ポインタが次のオブジェクトを指したという結果であって、ポインタの理解としては正しくないと思うよ
>>404 なるほど。たしかにそう考えるとわかりやすいかも。
そもそも配列概念の実装がポインタ演算なんだから
>>406 その言い方だと、Cにとって関数の実装だってポインタじゃん
>>408 HRESULT (WINAPI *func)(HTHEME);
func = (HRESULT (WINAPI *)(HTHEME))::GetProcAddress(m_hLibMod, "CloseThemeData");
if (func) return func(m_hTheme);
return NULL;
って例もあるってことだろ
>>410 そりゃ関数ポインタであって
// 外部リンケージの実装上、間接呼び出しになるものを除いて
通常の関数のどの辺がポインタなのかと問うているんだが。
>>411 配列をポインタだと言うなら、関数も単にアドレスをコールしてるだけの代物だろう
配列概念がポインタだとか言う乱暴な話をすんなってこった
ポインタが難しいというより文法が混乱の元。
ひとつの変数でアドレスと示す値の2つが出てくるからいけない。
int *sex;
static cinco = 072;
sex = &cinco;
cinco = (int)sex;//アドレス
cinco = (int)&sex;//ポインタのポインタ
cinco = *sex;//ポイッタが示す値
ひどいコードだ
それじゃただのオナニーだ
416 :
デフォルトの名無しさん:2010/02/09(火) 14:28:02
いやー、なんだ、その
僕は初めてマックのプログラムを作った時、
ポインタのポインタ、というのがあまりにも便利すぎて衝撃を受けたけどな。
ハンドルか
>>417 WinNT.h(344)
typedef void *HANDLE;
無知哀れ
ハンドルなんて、ポインタの配列のインデックスだったり色々。
実際、昔のMacとか16bitWindowsの頃は、メモリ配置がしょっちゅう動いてたから
ポインタのポインタを使わざるを得なかったな。
x386でCPUがサポートしたからこの概念も意味が薄れたが
char str1[] = "abcde";
char * str2 = "abcde";
上と下は同じでどっちを使ってもいい。
これ、なんか違わなかったけ
>>422 用途によるだろ
ただ表示させるだけならどっちでもいいし
なんか違うじゃなく、全然違う
上は、文字列のポインター
下は、文字列定数のポインター
読めるから書けるわけではない...
初心者には配列とポインタが明示的に区別されるDelphiを使わせるべき
char str1[] = "abcde";
char * str2 = "abcde";
printf("%d,%d\n",sizeof(str1),sizeof(str2)); // 6,4
str1[0]='x';
printf(str1); // xbcde
str2[0]='x'; // 以下、エラー
printf(str2);
>>427 以下エラー、の部分は、処理系によってはエラーにならない。
こっちの方がいい。
str2 = "bcdef";
printf(str2); // bcdef
str1 = "bcdef"; //エラー
printf(str1);
>>428 >以下エラー、の部分は、処理系によってはエラーにならない。
警告ならまだしも、エラーになるような標準から外れた処理系は嫌だな。
>>429 コンパイルエラーじゃなくて実行時エラーのことだろ。
わざわざ以下、エラーって変な言葉で書いてるんだし。
431 :
デフォルトの名無しさん:2010/02/11(木) 10:06:25
コンパイラー通って実行でエラーって 最悪じゃん
str2は、定数へのポインターになっているが、ポインターの定義は定数になっていないからコンパイルエラーは出ねぇよ
だからと言って、プログラマは、str2の示すメモリ領域が自由に読み書きできると期待してはいけない
const char * const str
実行時に例外なりプロセス異常終了なりするのは
あんまり「エラー」とは言わないと思うんだが。まあいいや。
>>431 阿呆ですか?
>>413 そういう文字通りのポインタという意味では難しいところは何もないよ
たとえばわざわざ&でアドレス書いて*で参照するだけなら誰でもわかる
問題は、領域が何指してるのかわからなくなるとか
上に出てた文字定数へのポインタなんか序の口だが
表記的にわかりにくいとかそういう副次的な面
結局C言語の仕様が悪い。
ポインタが難しいというより
ポインタを難しいと脅かしたり、有用な使い道を教えない(教えられない)
クソ本、クソサイトが跋扈していることが理解できない
実際難しいだろ。
newしたポインタをうっかりコピーして、両方でdeleteしたり、
配列の先頭アドレスを渡すと渡した先ではポインタになって、
配列のサイズがわからないからサイズを超えてアクセスしたり、
1個のオブジェクトへのポインタなのか配列へのポインタなのか
区別がつかないからバグの元になったり。
ポインタでなく参照にすれば、いくつかの難しさは取り除けたはずだが、
70年代の言語にそれを求めるのは酷というものだ。
(当時のCPUでの)現実的なコンパイル時間という制約もあるし。
ポインタを理解するためにはオブジェクト指向を理解しないとね
でも、C++を始めるなら、Cでポインタ位は覚えてないと難しいよねwwwwww
>ポインタを理解するためにはオブジェクト指向を理解しないとね
どうして?
簡単なので良いからアセンブラやるのが
遠回りかもしれないけど良いと思うよ。
C。C++でええやん。
なんでわざわざポインタのためだけに他の言語に手をだすのか・
>>441 Brainfuck
>>440 ポインタが指しているものが、アドレスではなくオブジェクトだから
で、オブジェクトって何ぞやってのは、オブジェクト指向を覚えれば分かるよ
オブジェクト指向のオブジェクトと、Cとかでいうオブジェクトを同一視するの?
>>444 どっか、違うの?
違うと言うなら詳細に説明してほしいねぇ
オブジェクト指向のオブジェクトは概念、仕様、実装という3つのレイヤーを含むけど
Cとかでいうオブジェクトは実装レベルのオブジェクトだけを挿す
参考:
デザインパターンとともに学ぶオブジェクト指向のこころ (Software patterns series): アラン・シャロウェイ, ジェームズ・R・トロット, 村上 雅章:
バカがバカに答えるからこうなる。。。
Cのオブジェクトとは、名前付きのメモリ領域のこと。
その定義のソースキボンヌ
thx
ANSI Cの定義(Definitions of terms)を読めば書いてある。
thx
ちょっwwwww
> Cのオブジェクトとは、名前付きのメモリ領域のこと。
って、C++のオブジェクトは?
オブジェクト指向だろうが、そうでなかろうが、オブジェクトってのは
「コンピューター内で有意なデータの集まり」だろ
そのオブジェクトをいかに合理的に使うかという方法論が、構造化プログラミングであり、オブジェクト指向じゃん
>>446 が書いてるけどレイヤが違うんだって。
仕様書は高いからDraftだけど、
The C++ object modelには
> An object is a region of storage
で、ポインタを理解するためにはオブジェクト指向を理解しないといけない理由は?
ポインタが指すものがオブジェクトだから
>>456 .ノ′ } 〕 ,ノ .゙'┬′ .,ノ
ノ } ゙l、 」′ .,/′ .,ノ _,,y
.,v─ーv_ 〕 〕 .| .il゙ 《 ._ .,,l(ノ^ノ
,i(厂 _,,,从vy .,i「 .》;ト-v,|l′ _,ノ゙|.ミ,.゙'=,/┴y/
l ,zll^゙″ ゙ミ .ノ .il|′アll! .>‐〕 \ _><
《 il|′ フーv,_ .,i″ ||}ーvrリ、 ¨'‐.` {
\《 ヽ .゙li ._¨''ーv,,_ .》′ ゙゙ミ| ,r′ }
\ ,゙r_ lア' .゙⌒>-vzト .ミノ′ 〕
.゙'=ミ:┐ .「 ./ .^〃 :、_ リ .}
゙\ア' .-- ,,ノ| 、 ゙ミ} :ト
゙^ー、,,,¨ - ''¨.─ :!., リ ノ
〔^ー-v、,,,_,: i゙「 } .,l゙
l! .´゙フ'ーv .,y ] '゙ミ
| ,/゙ .ミ;.´.‐ .] ミ,
| ノ′ ヽ 〔 ミ
} } ′ } {
.| .ミ .< 〔 〕
.{ \,_ _》、 .{ .}
{ ¨^^¨′¨'ー-v-r《 〔
ポインタが指してるのはデータだぞ。
460 :
デフォルトの名無しさん:2010/02/15(月) 14:57:10
ポインタのポインタのポインタのポインタのポインタのポインタのポインタのポインタのポインタのポインタ
いわゆるひとつのNullable Reader Comonad
ポインタ嫌いになる原因は
*dst++=*src++;
こんなのやるから
それかsignal()のポロトタイプで挫折。
>>462 68030のコンパクトで美しいコードを出力する良いプログラムじゃねえか。
move.l (src)+,(dst)+
C言語が糞だからポインタを難解にしていると何度言えばわかるのかね?
>>464 その理由を相手が納得しない限り
何どいってもわかるわけがないだろ?
馬鹿ですか?
void( *signal( int signum, void ( *handler )(int) ) )(int);
■関数:signal
引数1:int signum
引数2:intを引数とするvoidを返す関数ポインタ handler
戻り値:intを引数とするvoidを返す関数ポインタ
先頭の'void( *' と 末尾の')(int)' で戻り値 :(;゙゚'ω゚')…
>>466 #define OPEN (
#define CLOSE )
typedef int Integar;
typedef void (*TYPE_)(Integar);
TYPE_ signal OPEN Integar, TYPE_ CLOSE;
void( *signal( int signum, void ( *handler )(int) ) )(int){ return handler; }
77BE4FD4: 6A 0C push 0Ch
77BE4FD6: 68 80 28 BC 77 push 77BC2880h
77BE4FDB: E8 40 24 00 00 call 77BE7420
77BE4FE0: 8B 5D 0C mov ebx,dword ptr [ebp+0Ch]
77BE4FE3: 83 FB 04 cmp ebx,4
77BE4FE6: 0F 84 41 01 00 00 je 77BE512D
77BE4FEC: 83 FB 03 cmp ebx,3
77BE4FEF: 0F 84 38 01 00 00 je 77BE512D
77BE4FF5: 8B 75 08 mov esi,dword ptr [ebp+8]
77BE4FF8: 83 FE 02 cmp esi,2
77BE4FFB: 0F 84 B0 00 00 00 je 77BE50B1
77BE5001: 83 FE 15 cmp esi,15h
77BE5004: 0F 84 A7 00 00 00 je 77BE50B1
77BE500A: 83 FE 16 cmp esi,16h
77BE500D: 0F 84 9E 00 00 00 je 77BE50B1
77BE5013: 83 FE 0F cmp esi,0Fh
77BE5016: 0F 84 95 00 00 00 je 77BE50B1
77BE501C: 83 FE 08 cmp esi,8
77BE501F: 74 0E je 77BE502F
77BE5021: 83 FE 04 cmp esi,4
77BE5024: 74 09 je 77BE502F
77BE5026: 83 FE 0B cmp esi,0Bh
77BE5029: 0F 85 FE 00 00 00 jne 77BE512D
77BE502F: E8 F1 4E 00 00 call 77BE9F25
77BE5034: 8B D8 mov ebx,eax
77BE5036: BF 10 F7 C0 77 mov edi,77C0F710h
77BE503B: 39 7B 54 cmp dword ptr [ebx+54h],edi
77BE503E: 75 32 jne 77BE5072
77BE5040: FF 35 90 F7 C0 77 push dword ptr ds:[77C0F790h]
77BE5046: E8 BC 73 FF FF call 77BDC407
77BE504B: 59 pop ecx
77BE504C: 89 43 54 mov dword ptr [ebx+54h],eax
77BE504F: 85 C0 test eax,eax
77BE5051: 0F 84 D6 00 00 00 je 77BE512D
77BE5057: 8B 0D 90 F7 C0 77 mov ecx,dword ptr ds:[77C0F790h]
77BE505D: 8B F7 mov esi,edi
77BE505F: 8B F8 mov edi,eax
77BE5061: 8B C1 mov eax,ecx
77BE5063: C1 E9 02 shr ecx,2
77BE5066: F3 A5 rep movs dword ptr [edi],dword ptr [esi]
77BE5068: 8B C8 mov ecx,eax
77BE506A: 83 E1 03 and ecx,3
77BE506D: F3 A4 rep movs byte ptr [edi],byte ptr [esi]
77BE506F: 8B 75 08 mov esi,dword ptr [ebp+8]
77BE5072: 8B 53 54 mov edx,dword ptr [ebx+54h]
77BE5075: E8 0B FF FF FF call 77BE4F85
77BE507A: 85 C0 test eax,eax
77BE507C: 0F 84 AB 00 00 00 je 77BE512D
77BE5082: 8B 50 08 mov edx,dword ptr [eax+8]
77BE5085: EB 20 jmp 77BE50A7
77BE5087: 8B 4D 0C mov ecx,dword ptr [ebp+0Ch]
77BE508A: 89 48 08 mov dword ptr [eax+8],ecx
77BE508D: 83 C0 0C add eax,0Ch
77BE5090: 8B 0D 94 F7 C0 77 mov ecx,dword ptr ds:[77C0F794h]
77BE5096: 8D 0C 49 lea ecx,[ecx+ecx*2]
77BE5099: 8B 7B 54 mov edi,dword ptr [ebx+54h]
77BE509C: 8D 0C 8F lea ecx,[edi+ecx*4]
77BE509F: 3B C1 cmp eax,ecx
77BE50A1: 0F 83 D4 00 00 00 jae 77BE517B
77BE50A7: 39 70 04 cmp dword ptr [eax+4],esi
77BE50AA: 74 DB je 77BE5087
77BE50AC: E9 CA 00 00 00 jmp 77BE517B
77BE50B1: 33 FF xor edi,edi
77BE50B3: 57 push edi
84 デフォルトの名無しさん [sage] 2010/02/17(水) 01:43:38 ID: Be:
あ〜、「バグっぽいの見つけたけど、報告はここでいいんですかね?」みたいな
いいわけないだろと心の中で突っ込んだが
85 デフォルトの名無しさん [sage] 2010/02/17(水) 01:46:52 ID: Be:
普遍的にバグであるかどうかを確認するためにスレで話題を振る、というのはアリではあるが
ライセンス上、パッチを2chに投稿したら取り込めないのでそこだけは注意
86 デフォルトの名無しさん [sage] 2010/02/17(水) 02:29:47 ID: Be:
ああ、著作権が2chに移っちゃうって話か。確かにそうだわな。
87 デフォルトの名無しさん [sage] 2010/02/17(水) 02:45:42 ID: Be:
まあそのまま取り込まなきゃ回避策はいくらでもある。
オープンソースなんて、どこかのをパクりまくり出し。
著作権は権利が認められれば、その作者が持ってるので放棄出来ないけどな。
著作権法よく読もうぜ。
88 デフォルトの名無しさん [sage] 2010/02/17(水) 02:51:51 ID: Be:
>>87 2chの書き込み規約よく読め
bsearchの戻り値って、その要素へのポインタを返すってあるんだけど。
int *p;
int a[100];
p=(int *)bsearch(....
ポインタを返すっていうよりメモリアドレスを返してない?
nで見つかったとしたら &a[n]のアドレス
ポインタを返すと書いてあるけど メモリアドレスを返すって意味でいいの?
ポインタとメモリアドレスの違いを教えてください。
右辺値だし良いんじゃね?
>>472 『ポインタ』の意味は文脈によって変わる。
ポインタ型変数のことを指す場合もあれば、ポインタ値(=アドレス)を指すこともある。
>>472 ポインタ=オブジェクトの存在するメモリ空間の先頭アドレス
ポインタ変数=値としてポインタを保持する変数
int *pはint型のオブジェクトに対するポインタを保持する変数
としてpを宣言するという意味になる。
>>474 変わるわけ無いだろ、お前が混同してるだけちゃうんかと小一時間(ry
俺は数学科だから事情をよく知らんのだが、
情報科学の分野では用語の整備が出来てないのか?
情報科学の分野における「ポインタ」という言葉の
標準的な定義は何なの?
日本語版&英語版のWikipediaでは、「ポインタ」という言葉は
"アドレス"ではなく"変数"の方で定義してあるようだが、
これが標準的な意味なのか?
明確に分けたければ、ポインタ変数と言えばいい
ポインタ定数(リテラル文字列とかメモリマップトI/Oのアドレス)
というものもあるのでポインタ=変数というのは明確な間違い。
あくまでオブジェクトのタイプとして整数、共用体、クラスなどと
同列の存在として存在する。
int i,j;を定義して整数i,jと表現するのと同様にvoid *p;を定義して
ポインタpと表現することはあるが、あくまでポインタは変数pの
保持するオブジェクトのタイプであり変数そのものではない。
混同するのは概念が理解できてないだけ。
値がアドレスか、アドレス自体かの違い
>>476 >情報科学の分野における「ポインタ」という言葉
一般用語としての「ポインタ」なんてもんはない。
各言語の規格をあたれ。
JavaHouseでポインタの出自が議論になってたのを思い出した
Javaの参照はポインタ
わかってます
( <●><●>)
(U )つ
u u
> 一般用語としての「ポインタ」
あれだろ、猟犬で獲物の方向を見て動かない犬種。
あれが確か「ポインター」
C/C++で、*や&以外で空いている記号は、 @と$くらいか。
char$ argv;
int@ test;
微妙…
486 :
デフォルトの名無しさん:2010/03/25(木) 22:54:34
***** おおっと *****
ポインタのポインタを引数に取ってポインタの値を変える関数を見かけますが
普通にポインタに代入するだけで済むような気がするのですが……
488 :
デフォルトの名無しさん:2010/03/26(金) 02:16:20
マックのツールボックスの事か?
>>487 値渡しをちゃんと理解しよう。
引数が値渡しだから
「引数に与えられた変数の値を書き換えるにはその変数のポインタが必要」
なのが理解できていたら
書き換えようとする変数がポインタの場合は、
「引数に与えられたポインタの値を書き換えるにはそのポインタのポインタが必要」
になるのも理解できるはずだ。
>>489 ありがとうございました
目からうろこがおちました
ポインタを取って逆参照に代入が基礎ですね
勉強になりました
>>485 C++/CLIだと(ポインタの意味ではないけど)^や%が出てくるぞ。int^とかchar%とか。
C++/CLIの変態さは標準化に失敗したレベルだからな
char str[] = "abcde";
と
char * str = "abcde";
が同じなら、上の方がしっくりくるなぁ。
JavaScriptなら
var str = [];(もしくは、var str = new Array();)
str[0] = "abcde";
と同じ事?
Perlだったら、
@str
$str[0] = "abcde";
になるのかな?
多次元配列の一種だと思ってたけど、どう違うん?
char str[] = "abcde"; は配列
char * str = "abcde"; はどこかにある配列を参照するポインタ
全く違う
下は、const static char*なポインタ変数だよね。
どっからconst staticが出てきたんだよ
498 :
497:2010/03/28(日) 08:52:14
× 474
○ 473
じゃあ、JavaScriptなんかでポインタを表現するとどうなる?
PerlやPHPでも可。
その辺は参照(リファレンス)が一番近い概念じゃないのか?
ポインタはCPUが使うポインタ
リファレンスはコンパイラが使うポインタ?
コンパイラというか、処理系?
いいえ。
ポインタや参照の値渡しを参照渡しと呼ぶ奴は素人
ポインタはポインタだし
参照の値渡し?は参照渡しだろ
ポインタの参照渡しはあっても
参照のポインタ渡しはない
ポインタという言葉を適切な日本語に意訳したほうがいい。
>>505 JavaScriptで言うと
function hoge(obj) { obj = {foo:2} }
var tako = {foo:1};
hoge(tako);
alert(tako.foo);
参照渡しなら2と表示されるはずだが実際には1になる
509 :
デフォルトの名無しさん:2011/05/05(木) 04:45:44.69
510 :
デフォルトの名無しさん:2011/06/08(水) 20:26:32.43
ポインタがマジでわかりません。
int * const (*(*funcsMap[FUNCS])())(int * const (*)());
はがしたいのでしょうか?
>>34 今さらで、かなりの遅レスなのは分かってるけどさ。
理論から入る?笑わせんな。この程度の動作を理解できない分際で、何が理論から入るだ。
「こういう動作をする」
そういうサンプルを見れば、本当に理論から入るやつは「こういうものに使えます」なんて
手を差し伸べられる必要もなく理解できるし、自分で使いどころを見つけられるわ。
自分で考える程度の、人間として最低限の能力も足りない分際が、よりによって「俺は理論から入るから、誰かに手とり足とり教授してもらわないと何もできないの。」って
ふざけてんのか?
うん、凄く汚い口調になってしまってすまない。
ただ、こういう「自分が出来ないのはこういう周りが悪い」っていう態度が凄く気に食わなかったんだ。
宣言してるとこじゃなくて、使ってるとこ見ないと
>>510 引数無しでintへのポインタを返す関数へのポインタを引数にintへのポインタを返す関数へのポインタを返す引数無しの関数へのポインタへのポインタの配列
だと思うが携帯からなんであんま自信ない。
さすがにそこまでいくとコンパイルして確かめたい。
>>510 スレチ
スパゲッティなの出してきてgotoがわからないとか言ってるようなもの
515 :
デフォルトの名無しさん:2011/06/09(木) 00:13:35.68
>>514 いや、でも上の文は「ポインタが難しい」と言われる要因の1つを表してると思うよ。
要は「非常に読みにくい」のよ。特に関数ポインタは。
もうちょっと何とかならんかったんかな、あれ。
自分で書いててもtypedefとかですっきりさせたくなるもんな
518 :
デフォルトの名無しさん:2011/06/09(木) 20:04:35.85
>>510 こんなマゾ的なオカルトコード知ってても何の得にもならんよ。
周囲に害悪を垂れ流すのみ。
難しさが理解できないって理解してないからだよ
関数ポインタのテーブルの宣言みたいだけど
521 :
デフォルトの名無しさん:2011/06/10(金) 01:53:53.53
結局、誰も分からないみたいですね
関数ポインタなんて本来そこまで難しい概念じゃないんだぜ?
それが何故あそこまで読みにくいコードになるんだよと思う
ゲームのチートをやっていたからポインタの概念はすぐ理解できた
でもCでの記法はすぐにマスターできなかった
>>510 これが意味ある宣言かどうかはそのうち見てやる
時間が掛かる割りには得られるものが少ないので暇な時にな
多分、記法さえまともなら時間掛けるまでもなく
「ただの長ったらしい宣言」で済んでると思うよ
526 :
デフォルトの名無しさん:2011/06/10(金) 22:11:06.55
int *p;
p= (int*)malloc(80);
として、
pp[1][2] = 2;
とできるには、ppをどの様に宣言すればいいですか?
528 :
デフォルトの名無しさん:2011/06/10(金) 22:47:49.27
>>527 ごめんなさい
書き方がおかしかった。
ppがpの領域を指すようにした後に
pp[1][2] = 2;
を行いたいです。
p[1*N+2]=2;
>>528 int (*pp)[2][3];
代入時にキャストする必要あり
531 :
デフォルトの名無しさん:2011/06/11(土) 07:52:16.08
>>530 できました。
ありがとうございました。
メモリに変数が確保されて、メモリには番地があるってイメージできればポインタなんて難しくない
コンピュータアーキテクチャの基礎みたいなのが足りないからポインタが分からない
それを分かってない講師や著者がいるから混乱をまねく
ポインタやオブジェクト指向ってなんで難しいって言われるんだろう
ポインタは文法の設計ミス
オブジェクト指向は難しくないが、C++は難しい
int a = 10, b = 20;
int> p -> a:
p <= 20;
p <- b;
printf("%d %d", p, =>a);
値と参照がわからないとJavaでも危険
危険?
>>536 でもJavaでそれが原因で混乱することってあんまり無いと思う
「基本型は値、オブジェクトは参照」と固定したお陰で
参照型の表現やデリファレンス専用の構文が要らなくなって
すっきりした、比較的読みやすい記法に纏まってると思うよ
どこかの雑記帳に取り上げられそうだぜ
intとIntegerなんてのがあるのは初学者には分かりやすいとは思えない
ttp://kmaebashi.com/programmer/pointer.html >K&Rによれば、Cの宣言は、「変数が現われ得る式の構文を真似た(P.114)」そうである。
>しかし、本質的に全く異なるものを無理に似せようとしたため、
>結局わけのわからない構文になってしまっている。
># Cの作者Dennis Ritchieが最近開発した新しい言語 Limboは、一見
># C like だが、宣言の構文はしっかりPascal風のものに直してある...
># ずるい(^^;
ポインタが難しいのではなく
ポインタを使ってバグなく作るのが難しい、と、はい
ポインタを難しい
難しいが難しいのではなく
難しいを使ってバグなく作るのが難しい、と、はい
結局、メモリ直アクセスのポインタはハード関係以外では使うなって話
Windowsが仮想アドレス持ってるのは、直アクセスさせちゃうとデバッグが事実上不可能だから、そうしてるわけで
だから、プログラミング上でも、Windowsの仮想アドレスにダイレクトにアクセスするのではなく
さらにプログラム内で仮想アドレスを作ってそこからWindowsの仮想アドレスへアクセスするようにしないと、
プログラムのデバッグは、プログラム内からは、事実上不可能
Windows上で動くデバッガを使って、追う事は可能だけど
そんな事するよりもプログラムソース内で、printして、正しいかどうかを見れたほうが良い
プログラム内仮想アドレスのポインタを駆使して、複雑な構造作る事は、ゴミグラマじゃなければ頻繁にあるはずだし
そこで作る構造は、メモリ直のポインタ触っていたら絶対にバグが取りきれないような複雑さになっているはず
ポインタを使わないわけではなく、デバッグ不可能な直アクセスのポインタがいらない
ポインタをアドレスとか言っちゃううちはまだ使いこなせていない
547 :
uy:2011/06/24(金) 03:25:27.98
言葉にこだわっちゃう奴はただのバカ、というか初心者
言語の限界が理解できてないんですね
言界
幽遊白書なついな
きも
きめえ
きもいから死ねよ
>>510 funcsMapはFUNCS個の配列、要素はポインタA
ポインタAは関数Cを指す
関数Cは引数なし、戻り値はポインタB
ポインタBは関数Dを指す
関数Dは引数がポインタE、戻り値はintポインタ
ポインタEは関数Gを指す
関数Gは引数なし、戻り値はintポインタ
答えられなかった未熟者どもは切腹しろ
555 :
デフォルトの名無しさん:2011/07/15(金) 20:31:56.63
今頃分かったのかよw
おそっ
こういうコード書くヲタは雇いません(キリッ
三項演算子と関数ポインタを組み合わせるバカはマジ死ぬべき
558 :
デフォルトの名無しさん:2011/07/15(金) 22:57:59.19
答えられなかったのにw
560 :
デフォルトの名無しさん:2011/07/15(金) 23:15:49.83
答えられなかったのにw
仕事で現実にあった。
int hoge[NUM][XMAX][YMAX];
として書かれてるコードがあるが、メモリ不足のためhogeを動的に確保するように変更したい。
ただしhogeを使っているコードはあちこちにあるので、それらを無変更のまま動くようにしたい。
おまえらこれくらい出来るだろうな?
int (*hoge)[NUM][XMAX][YMAX];
hoge = malloc(sizeof(*hoge));
でもメモリ不足で静的に確保できないなら動的に確保しても駄目だよね。
わからん。
間違いだバカタレ。
それだと hoge[i][j][k]と書かれたコードを(*hoge)[i][j][k] と書き直さないと動かないだろうが。
あとメモリ不足てのはhogeが居座り続けると不足するから要らない時は解放する必要があるって意味だ。
おっと失礼
int (*hoge)[3][5];
hoge = malloc(sizeof(*hoge) * NUM);
だな。
566 :
564:2011/07/18(月) 00:31:13.35
これって遅くなるけどね。
尤も、仮想三次元としてアクセスできる様に
n * XMAX * YMAX + x * YMAX + y
を計算する関数を用意しておけばわりかし移行も楽でいいね。
# つーか、これの二次元版なら実務でやったw
568 :
564:2011/07/18(月) 08:04:40.31
あぁ、元が固定長なんだから可変長にすることなかったか。
どう考えてもC/C++の文法がポインタの理解を妨げてる最大要因。
Intel記法のアセンブラのほうがわかりやすいな
>>569 では、どうやれば理解を妨げなかった?
パスカルみたいにする? 代わらないと思うが。
PASCALはポインタと配列を別物として扱う分マシかも
573 :
デフォルトの名無しさん:2011/07/24(日) 20:46:04.23
Cでもポインタと配列は別物だが・・・
恐ろしい勘違いをしてるのでは?
初期化メモリ確保以外に違いあるんだっけ?
配列は代入出来ない
配列からポインタへの暗黙変換が無ければ一部の誤解は消えたんだろうがそれはそれで書きづらくなっただろうな
>>576 そうでもないっしょ。
char buf[100];
fgets(& buf[0], sizeof(buf), stdin);
とかになるだけだろうから。
ポインターって コレクションとOOPの為にあるんだよ 知ってた?
579 :
デフォルトの名無しさん:2011/07/26(火) 19:14:47.02
ポインタは間接参照の為にあるんだよ?知ってた?
582 :
デフォルトの名無しさん:2011/08/28(日) 13:06:04.38
大体何でぇ、変数の名前で指定すれば事足りる物をわざわざアドレスを取り出して
それを指定するのか、そこが分らん。
確かに世の中氏名と出席番号有るのは分かるんだが、それがプログラムの世界で
なんで必要なのかがわからんのよ
はいはい
ポインタのスレでアドレスがどうこう言われてもなぁ
>>510 こういうのは可読性考えてない質の悪いfoobar言語 → C言語なソーストランスレータを使うと、
ボコボコ出てくるんだよなあ。逆に言えば、そういうのが吐いたコードを理解できるようになると、
Cのポインタ怖くなくなるかもな(だが、こんなのは書きたくはない)。
Cの書法がもう少し何とかなればそこまで無茶な内容でもなさそうな感じがするんだが
int *p = 0;
*p = 0;
この違いを理解できずに打ちのめされる初心者カワイソス
Cの文法が悪いわけじゃない、使うやつの頭が悪いだけ
単純なことだ。前置と後置の演算子が入り乱れれば、
どんな言語でもクソ文法になる。それだけの話。
後置の演算子は、右へ右へと書き足していくから、後置の演算子は右方向へ読むことになる。
前置の演算子は、左へ左へと書き足していくから、前置の演算子は左方向へ読むことになる。
従って、
・"前置だけ" あるいは "後置だけ" で書かれた文は、単方向に読み進めれば終わる。
・前置と後置が入り乱れている文は、右へ左へ行ったり来たりしなければ読めない。
さらに、演算の結合順位を決定するために、余計なカッコが必要になって奇怪な文になる。
foo((T*)p)
foo(t*p)
この違いを理解できずに打ちのめされる初心者カワイソス
>>582 超でかい領域になんらかの変換をかける処理を考えたときに
ここまでやった!
みたいなのが必要じゃない?
前から何バイト目って覚えておくんでもいいけど
>>582 たとえ話でテキストエディタ作るときウィンドウ間や別のアプリケーション(プラグイン)や
プロセスでデータを共有したいってとき、変数名では共有できやしない。それに、いちいちAPI作って
データをコピーしていたら遅いしメモリの無駄。ポインタなら指すだけ。
Cの暗黒面嫌いなら hoge言語 → Cトランスレーター使って、必要な部分だけCで書くといいよ。
>>581 C#の真似か
まあいいか
お互いに切磋琢磨する事は悪くない
>>591-592 ポインタが難しいのはそんな部分じゃねーよ初心者は黙っとけ
コピーコストを発生させないために先頭アドレスで指し示す手法自体は大して難しくない、どの言語にもある
問題は「Cではポインタの示す先のオブジェクトは1個なのか配列なのか区別されない」ということ
例えば func(int*); に対して
int i;
int array[100];
を
func(&i);
func(array);
func(&array[50]);
のようにどうとでも渡せるという仕様が問題なんだよ
func(array);は無効にして
func(&array);と強制すべきだった
ポインタって可読性悪化させてセキュリティ強化してるんでしょ?
わざわざアドレス指さなくても変数名で指定すりゃいいし、
関数隔てるなら引数と戻り値使えばいい。
高級言語じゃ隠蔽された仕様。
最悪OSに危害加えるしな。
あのおかげで高級アセンブラとして使えるんだよな
可読性や安全性やすべて無視して自由を取ってる
>>594 同意。
でもアセンブラの置き換えとしてはそれで良い。
高級言語やりたいなら他行くしかない。
言語仕様がいい加減だった昔は
2バイト型でポインタの値貰ってキャストして使ったりしてたw
それまでアセンブラでやってた手法を元に
作り手の力量でどうにでも出来るのがCの魅力だった。
組込的な事をやらなければ、ポインタの利用は最小限で済むはず。
出来れば使わないに越した事は無い、今時の強力なコンパイラなら最適化されて
ポインタだから動作が速いとか無いと思うけど。
配列のポインタを得るときでも
ポインタ演算子の使用を強制されるとしたら
どんなデメリットがありますかね?
ポインタはガチな数値計算とかだと最適化の邪魔
c++の参照&なら邪魔されないんじゃねーの?
参照のコンテナみたいなのは小細工がいるし
その小細工が最適化を妨げないという保証はない
C99では restrict という予約語が出来て VCでも __restrict という修飾語が使えて
FORTRANと同等の最適化を期待出来るようになった
気を付けて使わないと危ないけど
C#でint型変数のアドレスを覚えておいて値を出し入れしたいんだけど
マジでどうすればいいの?
606 :
デフォルトの名無しさん:2012/02/02(木) 09:02:24.09
そんなアホなことはしなくても動くプログラムは作れる
>>605 なんでそんな必要があるのか知らんが unsafe でggれ。
MSがなんで.NETにポインタ残したのかも知らんが。
608 :
デフォルトの名無しさん:2012/02/02(木) 22:21:07.52
GCが勝手にオブジェクトを移動させるから、
fixedブロックで一時的に固定した配列かローカル変数以外のアドレスは基本的に取れないし
固定されてる期間を超えて保持してるとアクセス違反で逝く
>>607 あるクラスのインスタンスをdatagrideviewにいれて変更とか表示とかしたいんだ
メンバ変数がたくさんあるからお手軽な方法がないかと思って
610 :
デフォルトの名無しさん:2012/02/02(木) 22:58:43.91
スレ違いだがプロパティ定義してバインドすれば全自動でやってくれるぞ
>>610 表示したいクラスはたくさんあって
そのメンバ変数のint bool stringについてやりたかったんだけど
C#だとできないんだよね
カラムはクラス名 変数名 値の3つにしたくて
C++ならポインタとクラス名、型、変数名だけ覚えておけば
ポインタ通して値の出し入れまでできたんだけど
C#はわからなくて辛い
どうやってインスタンスを特定するんだろう・・・
612 :
デフォルトの名無しさん:2012/02/03(金) 00:32:28.33
リフレクションを使え
インスタンスから全部取ってこれる
どう見ても GetType().GetProperties() の出番。
たまたま出てきたむか〜しの8bitCPUのマニュアルを眺めてみた
あの頃はスタックもヒープも自分でアドレスにラベルつけて管理したなあ
配列もリストもキューも自分で管理したなあ
アドレスをレジスタで計算してPCに転送してジャンプとかやってたなあ
それを思えばポインタなんて簡単もいいとこだ C偉い
…とあらためておもいました。 おわり。
>>613 get field ができませんでした
配列だと勝手が違うのでしょうか?
ポインタ駆使して Hello, world はどうやって表示するんだYO
617 :
デフォルトの名無しさん:2012/02/03(金) 22:51:36.11
619 :
デフォルトの名無しさん:2012/02/04(土) 04:19:24.16
>>587 そのとうり。理解を混乱させてる原因はその文法。
int*
と書けば
int* a = 0;
a = 0;
同じことしてるのが一目瞭然。
int *
などと書くから
int *a = 0;
a = 0;
同じ事してるのに、同じ事してるように見えない。
int* a, b, c
int *a, *b, *c
の問題はその後に知ればいい。
>>619 単に初期化についてちゃんと理解させればいいだけだ
じゃなきゃC++で完全に詰む
とおりを、とうりと書くような痛い人につっこんでも仕方ないのだが
ポインタが理解できない人は抽象的に考える力がないのだろう
端的にいえば数学や国語の得意な人はすぐに理解できるが苦手な人には理解できない
int *p = 0; が紛らわしいとかそういうの次元の問題はではないだろうよ
抽象的ねぇw
もっと端的にいえば「頭が悪いから」ポインタが理解できないんだよ
「説明が悪いから」だと主張してる人は教えたことがないのだろう…
>>623 そうそうポインタ理解するふつうの脳ミソ持ってないやつってたまにいるんだよな
でバカだから自分がプログラミングにどれくらい適性があるかも自己判断できないのな
最初から無理なのがわかんないバカ
では、良サイトを挙げよ。
良サイトっていうか普通に読んでわからなかったらどこ見てもダメだろ
ただ俺はいきなりわかるわからないの話じゃなくて経験だと思うんだよねー
最初は*つけて動いたやwアハハーwでいいと思うよ
そのうち色んな場面をみるたびにそういうの細かく知るようになって
2年もたつ頃にはほぼ完璧になってるって
なんていうのかなぁ
本のしおりみたいな概念と似てるんだけど
厳密に表現するにはちと違うしでまあ表現はしにくいけど
どっかで使ってあるよく機能のうちの一つに過ぎないと思う
アドレッシング
*list→[1,2,3,4,5,NULL]
こういう表現を理解できない子には無理。
矢印が分からないんじゃしょうがない。
まずそろばんを見せて直接参照・間接参照を説明して、
次に配列・多次元配列の扱い方、
Cでの文字列の表現、
関数の引数での参照渡し、
auto 変数への参照が関数を抜けるときに無効になることの説明、
なんだ簡単じゃん
>>625 ポインタ程度でプログラミングの適性語っちゃう奴がいる事のが呆れる
そんなに簡単に教えられるなら
悪書凡書が溢れかえってるわけないだろと
アセンブラやれよ 一発で分かる
>>628が正しい
Cの言語としての機能不足を
ポインタがいかに補っているかを
あわせて説明できないとダメ
抽象概念が理解できないとポインタも理解できないというのは同意。
ベン図を理解できない人間が多いから集合を算数から外したことでも判るように、
抽象概念が苦手な人間にそれを理解させるのは容易じゃない。
>>635 Open Article Writing ってか
新しいな
>>619 > 同じ事してるのに、同じ事してるように見えない。
おなじ事してないんだけどなw
初期化と代入について勉強してからまたおいで。
char a, b,
*s = 0;
まあどうってことないよな
間接キス
>>629 中西正和さんは「LISP入門」の中で二進木を説明するのに10ページを
要している。listですぐピンとくる人なんているのかね。
ポインタ完全にふに落ちるためには、
やっぱり一度アセンブラ経由するのが必須なのかもしれん。
>>642 というよりメモリ内でのデータ構造だな
アセンブラを経由するとローダとかの回り道があってあばばばば
アセンブラと OSの仕組みと コンパイラ・リンカ・プリプロセッサの連携
この3つおさえてやっとCが理解できたわ
K&R前からの歴史もいるな
そういう色んな事を知って初めてCの仕様や長い間続いてるプロジェクトのコードが理不尽なものでないと受け入れられるのだ・・・
>>1 ポインタがわからないと言ってるのはそのレベルじゃないと思うよ
ファンクタが絡んだポインタ使った定義見たら死にそうになるぞw
むしろC#とかポインタがない言語でポインタがある言語と同じことしようとするとハマる
昔泣かされたUNIXのシグナルのプロトタイプ
void (*signal(int signum, void (*handler)(int)))(int);
これをアセンブラレベルで理解できる奴はえらいわ
アセンブラレベルでなら型気にしないからな
>>648 こんな程度で泣いてる奴はC出来ますとか二度と口にするな。
未熟者はjavaかc#でもやってろ。
cはプロ用のプログラミング言語だ。unixのカーネルはjavaでもc#でもc++でもなくcで書かれているだろう。
>>1 簡単な事しかやってないから簡単なんだよ。
100万行のプログラムを書いてみろ。
ポインタほど煩わしいものは無いと感じるから。
そもそも社会に出てポインタの話するやつなんかいねえよw
分かってて当然だから
655 :
デフォルトの名無しさん:2012/02/16(木) 18:16:31.69
「JavaやC#にはポインタが無い」(※JNIやunsafe除く)
って言葉だけだとちゃんと分かってるのか判断出来ないよな
「参照はあるけどCのようなポインタは無い」とか
「ポインタ演算は無い」のような表現なら分かるけど
>>655 >「参照はあるけどCのようなポインタは無い」
言語ごとに「ポインタ」の定義が違うことを
ちゃんと分かってるのか判断出来ないよな
657 :
デフォルトの名無しさん:2012/02/16(木) 20:46:30.17
>>656 >「ポインタ」の定義が違う
Javaやunsafeを除いたC#にポインタの定義というものは無いんだ
ポインタの代替をあえてreferenceという別の言葉で定義していて
説明内のpointerは「Cのようなポインタ」を指している
「Javaの中でのポインタ」というように再定義しなかったのは
言語の設計思想の中で割りと重要な点だったりする
http://java.sun.com/docs/overviews/java/java-overview-1.html > there are no pointers in Java
C#も同様でreferenceとしている
unsafeでのポインタはポインタ演算も可能な、まんまCのようなポインタ
>>657は一体何を考えてこのレスをこのスレに今更書き込んだんだろうか…。
659 :
デフォルトの名無しさん:2012/02/16(木) 21:02:04.23
紛らわしいからJavaやC#でいう参照はオブジェクトハンドルとでも呼べばよかったのに
実体はGCに管理されたハンドルだから単なる演算ができないポインタとも違う
ひとりだけレベルの低い奴おるで。
「コーラを飲んだらね、なんとゲップがでるんだよ!」と大人に教える幼稚園児。
困ったときのレッテル貼り
<原発技術者>東電人材流出やまず 韓国が引き抜き攻勢
毎日新聞 2月16日(木)8時28分配信
東日本大震災からほぼ半年後の昨年夏、東京電力の原子力部門に勤める幹部技術者が、韓国の政府関係者から食事
に招かれた。「給与はどの程度カットされましたか?」「今の待遇に満足ですか?」。幹部技術者と親しい東電幹部
によると、会食の目的は転職の誘いだった。打診された移籍先は国営の韓国企業だったという。
同じころ、東電の別の男性社員も、韓国政府関係者から面会を求められた。待ち合わせ場所に行くと、「力を貸し
てもらえないか」と転職を持ち掛けられた。韓国側からどのような処遇を提示されたかは明らかではない。
関係者によると、2人とも転職の誘いを拒否し「今も原子力部門で働いている」(幹部)というが、東芝や日立製
作所など世界最先端の原発を扱う東電の運用技術を狙った「ヘッドハンティング」の一端が浮かび上がった。
韓国では90年代以降、当時は規模が大きくなかったサムスン電子がソニーやパナソニックなど日本の花形企業の
技術者を「リクルート」して技術力を高め、日本の電機メーカーを「駆逐」し、世界有数の電機メーカーにのし上
がった経緯がある。東電幹部は「今は東電が国内外からの『草刈り場』になっている」と危惧する。
東電は原発事故による経営環境の悪化や民主党政権の「脱原発依存」「東電解体」の動きを受け、人材流出が止ま
らない。東電の内部資料によると、昨年3月の事故後の退職者(定年退職は除く)は約300人と例年の3倍以上の
ペースで増え、年度末を控えて「退職予備軍」も200〜300人にのぼるとみられている。
http://headlines.yahoo.co.jp/hl?a=20120216-00000017-mai-bus_all
退職者は「技術系の若手」や「中堅・若手の優秀層」が中心で、転職先は総合商社や食品大手、外資系金融機関な
ど。海外の原子力企業に転職した例は確認されていないというが、すべての転職先は把握しきれていない。
「引き抜き」攻勢をかける韓国は総発電量の約3割を原子力で賄う。昨年12月には東部・蔚珍(ウルジン)で計
画する原発2基の建設が許可され、李明博(イ・ミョンバク)大統領は「我が国はエネルギー輸入国。原発建設は続
けていく」と原発推進の姿勢を鮮明にしている。李大統領は今月5日、訪問したトルコでエルドアン首相と会談し、
中断していた原発建設交渉の再開で合意。原発事故で交渉が停滞した日本メーカーを横目に韓国企業の逆転受注を
狙っている。
福島原発事故後、ドイツ、イタリア、スイスが新規の原発を建設しない「脱原発」を宣言。一方、急増する電力需
要や地球温暖化対策で米国や中国、東南アジアの新興国などで原発新設が進む。「中国がドイツの原発技術者の獲得
に動いている」との独報道もあり、技術者の争奪戦は国境を超えて激化している。
また、原発技術の流出は、核兵器の拡散防止を目指す核安全保障を揺るがしかねない。東電は原発の使用済み燃料
から取り出したプルトニウムをウランと混合したMOX燃料を再利用するプルサーマルを実施している。核兵器に使
われるプルトニウムを扱う東電の技術は「核兵器を造る能力」(資源エネルギー庁幹部)でもある。
衆院安全保障委員会の理事の一人は「原発の推進国にとって東電の技術は垂涎(すいぜん)の的。安全保障のうえ
でも東電の人材や技術が流出すれば問題だ」と警戒感を強めている。【三沢耕平】
***
概念が分かり辛いという奴はヤバイけど
構文が分かり辛いという奴は分からんでもない
int *p;
int a[];
int* p, v;
型 変数名 になってないのが罠すぎる
ちょっとした*の位置の違いだけで意味が変わるの
シンタックス上は同じでセマンティクス上は少し違う
セマンティクスを優先するとシンタックスが牙を剥く
int* p, v; = int* p; int v;
関ポで詰んだ
>>587 >>619 >>648 >>667 typedefは神
typedef int* int_p;
int_p a=0, b=0; // int_p a; int_p b=0; と同じ
a = 0;
*a = 0;
この子はCを覚えたてなの?
そしてこのマジレスである
関ポのときに typedefにお世話になったな
いまだに素で見てもわからんw
なつかしい
もうちょっと上位概念でいいような
引数が関数ポインタって何がやりたいの?
多段呼び出し?
こーるばっくとか、スレッドの起動とか、ナンボでもあるさ。
virtualができるc++から入ったら意味不明だろうな
cの頃はそんなん無かったから関数ポインタは必須だったが
viatual関係なくね?
引数に単にオブジェクトを渡せるんだから。
で、渡したオブジェクトのメソッドを呼ぶなんてこともまた当たり前すぎて、
コールバックだのなんだのイチイチ言う必要が無くなった。
C++から入っても関数ポインタ取るAPIが普通にあるから関数ポインタ使うよ
ポインタが分からない人は抽象的すぎる説明を信じられないだけ。
これは無条件に信じる(暗記)するかどうかの話にすぎない。
形式を全部暗記すれば理解する必要すらないからである。
暗記力の問題だから、簡単にポインタを受け入れた人は
アセンブラレベルの具体的な話になるとまったく理解できない、それは
アレンブラレベルの何かを暗記していないだけ。
682 :
デフォルトの名無しさん:2012/02/25(土) 02:17:39.40
Cのポインタが分かりにくいのは、いろんな意味を一手に引き受けている
からではなかろうか。
大昔、Cの入門書で読んだ記述。コメント内はその時の心境。
int a;
char *ptr; /*その*はなんだよ!*/
a = 10;
ptr = "Hello"; /*さっきの*はどこいったんだ!*/
printf("%d %s\n", a, ptr);
scanf("%d %s", &a, ptr); /*なんでptrだけprintfとscanfの表現が同じなんだよ!わけわかんね!*/
こんな感じで戸惑ったのを思い出した。
一ページ目がこれじゃ心折れるぞw
>>681 暗記は役に立たないぞ
こういうこと書いてるやつに限って
他の言語に移ったらポインタの動作を記述できなくて迷う
ポインターがないのはクソ言語だとか言い出す奴がマジでいて困る
>>683 >ptr = "Hello";
>scanf("%d %s", &a, ptr);
これはひどい。
>>685 何十年も前の入門書だからよく覚えてない。ゆるせ。
もしかしたら間に
char buffer[1024];
ptr = buffer;
とか入ってたかも。
687 :
デフォルトの名無しさん:2012/02/25(土) 12:49:27.76
int a = 1234
だとして、
&a とすれば、1234が記録されてるメモリー番地(たとえば4567等)が読み取れる。
&記号は 通常の変数に対して使えるのだから、*記号も同様に使えればシンプルで良かった。
*a とすれば、メモリー番地1234にアクセスできる。これで十分じゃないか?
しかし実際はエラーになる。
通常の変数に * は使えない。
ポインター変数である int* a も、結局、実体はただの4byte長の数字を格納してる変数にすぎない。
通常の変数との違いは
適用できる記号が &(記録に使われてるメモリー位置を得る) だけの通常変数と、
&以外に *(記録されてる数字の、メモリー位置から読み書きする)も使えるポインタ変数。この違いだけ。
通常変数も、ポインター変数も無関係で、何にでも & と * を使えるようにすればシンプルで良かった。アセンブラの場合はこれ。
「アセンブラから始めればポインタを理解しやすい」と言われる理由はここにある。
この子はCのお勉強途中なの?
そもそも通常変数とポインタ変数と言う区別をしているからいけない。
その、ポインタ変数と言う代物は只単にポインタ型の変数でしかない。
つまりそれは、通常変数と言う代物と型が違うだけの同じものだ。
>>689 ポインタを実際に使ってない人のコメントにしか見えない
>>690 そう思いたければ思えば。
そう言えば、ポインタ変数なんて風に特別視する奴に限って
ダブルポインタだとかトリプルポインタだとか言い出すよね。
>>689,691
いや、俺はなんとなくその言わんとすることは分かるよ。
ダブルポインタとか聞かされたときに、大いにモヤッとする。
いくつか並べてみても単に、
int型、int *型、int **型、という理解のほうがフラット。
ポインタをちゃんと理解している奴ならダブルポインタとか絶対言わない
リスト型ポインタ
>>691 いや実際使ったことないだろ
>>687を見返せば?
>*a とすれば、メモリー番地1234にアクセスできる
a=a+1で1235
では
*(a+1)はどこを指すんだ?
*(++a)は?
妄想はチラシの裏へどうぞ
まず
>>687は半年ROMってから出直すべきだろうw
>>696 固定観念に嵌まって抜けられなくなっているようだね。
変数の種類が違うんじゃなくて、その変数が扱う型の違いだってことに全く気付いていない。
>>698 他人に難癖つけるならまず
論理的な回答出してから言えよ
700 :
デフォルトの名無しさん:2012/02/25(土) 15:21:55.91
> ダブルポインタだとかトリプルポインタだとか言い出すよね。
この言い回しは、ム板に来てから知ったのだが、それぞれ2段、3段の
間接参照であることを簡潔に表現していて良いと思うのだが。
>>695 私が、最初にC言語を勉強したのは、Visual C++2.0 スーパーテキストという
本なのだが、ポインタ変数 + 1をアドレス値+1と誤解しているという代物だった。
海外ではダブルポインタっていってるけどね
いやぁ、そう表現すること自体は構わないんだが、面接で
「ダブルポインタは理解できていますがトリプルポインタはちょっと自身がありません。」
なんて言われちゃうとどうもね。
シープラプラみたいなもんじゃないか
海外だと笑われる
704 :
デフォルトの名無しさん:2012/02/25(土) 17:06:47.03
>>702 なつかしいな。そういうのあったな。ちょっとってなんだちょっとって。
配列の配列の配列
#include <stdio.h>
static void function(int a)
{
printf("my_function: %d\n", a);
}
static void caller(void (*new_function)(int a), int p)
{
(*new_function)(p);
}
int main(void)
{
caller(function, 10);
return 0;
}
void qsort(
void *base,
size_t num,
size_t width,
int (__cdecl *compare )(const void *, const void *)
);
>>706 >static void caller(void (*new_function)(int a), int p)
これをプロトタイプ宣言すると
static void caller(void(*)(int), int);
となるわけで、初学者には恐怖感あるだろうな。
Cの糞仕様が難解な物にしていると言わざるを得ない
#include <stdio.h>
int main(void)
{
int i=0;
printf("%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d",i);
return 0;
}
711 :
デフォルトの名無しさん:2012/02/29(水) 02:05:46.25
alias gcc='gcc -Wall'
となっているべきだと思うだがなぁ。
gcc 710.c
710.c:7: warning: too few arguments for format
>>708 しちめんどくさい定義を、typedefもせず書く阿呆が
現場にいると困ります。
static void caller( r_typ(*)(a_typ) , int);
static void caller( (r_typ(a_typ))* , int);
色々考えた上で現在の仕様(前者)になってると思うけど
後者のような宣言だと構文解析上の問題とかがあったのかな?
715 :
712:2012/03/01(木) 03:24:06.48
今だかつて、ポインタを完全に気にしないでプログラミングできる言語は無かった。
そして、これからも、無い。
どんな高級言語になろうと、if文のところで、ポインタを気にしなくてはならなくなる。
比較するときに、アドレスの参照先か、アドレスの値そのものを比較するかの判断ぐらいはするでしょ。
ていうかポインタわからない奴なんてホントに少数なのに言語製作者側が過剰に反応しすぎだろ
明らかにあったほうがいいものなのに下手になくしたもんだから余計複雑になってると思う
なくなってはいないんじゃないかな。
Javaのように、暗黙のルールでソースを記述するか、
Cのように、演算子でソースを記述するかの違いだけで。
>>720 おまえもわかってないな。
javaとかがやってるのは「参照」。これは危なさは無い。
cのポインタは「参照」とは違う。
参照は、「配列の途中から渡せない」かわりに「渡された先でも配列のサイズがわかる」。
ポインタはその真逆。だからバッファオーバーフローの危険がある。
まず表記につまづくので、「ポインタの問題=表記の難しさ」と勘違いする奴が後を絶たないが、
ポインタの本当の問題は「参照でない」ということ。
既出だけど違いはポインタ演算の有無じゃね
違いはGCに管理されているかどうか
GCのせいでアドレスは勝手にコロコロ変わる
non-movingなGCに変更すれば…と思ったが解決になってない。
C++11ではnon-movingなGCが実装しやすくなるような仕様が検討されてるね
安全でないキャスト、ポインタ演算、配列への直接(チェック無し)アクセスを
禁止したら参照みたいに扱えそうな気がする
delete済みのポインタの保持の問題があるけど
これはGCやスマートポインタじゃないと無理かな・・・
以前見た、CからJavaへ乗り換える人用の本には、
「Javaのクラスは、全てポインタ型だ!」と書いてあった。
まぁ、参照という用語がC++からの単語だから、飽くまで分かりやすくだろうけど。
>>726 そういう実装を前提にして設計した結果がJavaやC#の参照なんだから実装の問題というわけではないだろ
ポインタとは根本的に違っててGCにオブジェクトを問い合わせるときのハンドル
ポインタはボーナス
731 :
デフォルトの名無しさん:2012/03/05(月) 00:30:34.32
Javaの意味での参照では不十分で、Cの意味でのポインタが必要なのはどんなとき?
外部関数呼び出しインターフェースをつくるときくらいしか思いつかない。
自分でリストをつくるとき、次のをさすポインタが必要
/* namevalu.h */
#define BUFFER_SIZE 128
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct NameValue NameValue;
struct NameValue {
char name[BUFFER_SIZE];
int value;
NameValue *before;/* リストにおいて、前の項目をさすポインタ */
};
NameValue *new_item(char *n, int v) {
NameValue *p;
p = (NameValue *)malloc( sizeof(NameValue) );
if(p != NULL) {
strcpy(p->name, n);
p->value = v;
p->before = NULL;/* 前の項目をさすポインタは、まだどこもさしていない */
}
return p;
}
void free_all(NameValue *p) {
NameValue *before;
while(p != NULL) {
before = p->before;
fputs(p->name, stdout);
free(p);
p = before;
}
}
#include "namevalu.h"
int main(void) {
char c[BUFFER_SIZE];
int i = 0;
NameValue *last_item;
NameValue *p;
last_item = NULL;/* 最後の項目をさすポインタは、どこもさしていない */
while( fgets(c, BUFFER_SIZE, stdin) != NULL ) {
p = new_item(c, ++i);
if(p == NULL) {
exit(EXIT_FAILURE);
}
p->before = last_item;/* 前の項目をさすポインタ */
last_item = p;/* 最後の項目をさすポインタ */
}
free_all(last_item);
return EXIT_SUCCESS;
}
D:\work>namevalu < namevalu.h
それのどこがポインタならではなんだ?
GCハンドルでも当然できるしそれすらなしに配列とインデックスでも代用できるよ
つかアクセス効率で言えばガバッと確保したノード配列の要素を
インデックス(もちろんポインタでもいいが)でつなぐほうがずっと良いはずだし
1ノードずつ動的に確保するにしても、GC言語の方がメモリ効率が良い分まだマシなんじゃないの
Cの救済にあたる弟子たち(プゲラッチョ)
Cの救済にあたる弟子たち(プゲラッチョ)
>>731 思いついたのは、配列(バッファ)内の特定位置を指すエントリが大量に必要で
配列自体も複数ある場合のメモリ効率の向上・・・とか
最高効率にするには必要、というくらいでしかないけど
ポインタが64bitの環境だとして
//java 1要素:(8+4+4)byte
class Et{byte[] trgAry; int trgIdx;}
List<Et> c;
//C# 1要素:(8+4)byte
struct Et{byte[] trgAry; int trgIdx;}
IList<Et> c;
//C++ 1要素:8byte
std::vector<unsigned char*> c;
訂正
//java 1要素:(8+4+8)byte
743 :
デフォルトの名無しさん:2012/03/06(火) 00:34:09.97
>>741 そうか、Javaの参照はプリミティブタイプを指せないんだっけ?
まさか指すためにBoxingするわけにもいかないので、Etのようなものを
定義する必要があるわけですね。
ちなみに、Fortranのポインタは8byteで定義できるが、配列へのポインタ
は定義できても、ポインタの配列は定義できないので、やはり構造体にくるむ
必要がある。
integer, target :: a(200)
type Et
integer, pointer :: trgElmnt
end type
type (Et) :: c(512)
c(1)%trgElmnt => a(11)
区間を指したいときは、
type Rt
integer, pointer, dimension(:) :: trgAry
end type
type (Rt) :: b(23)
b(1)%trgAry => a(1:100:4) ! a(1),a(5),a(9),...
Fortranは裏では配列記述子(開始,終了,要素間隔)で配列を管理しているので、
Rtはすくなくとも8*3=24byteよりも大きく、実際には処理系に依存するいろいろ
な定義があるので通常これよりも長い。
Fortranだったら全部スカラー配列でいいだろ
745 :
デフォルトの名無しさん:2012/03/06(火) 10:59:25.56
for(;P("\n"),R-;P("|"))for(e=C;e-;P("_"+(*u++/8)%2))P("| "+(*u/4)%2);
746 :
741:2012/03/06(火) 16:01:07.25
自己ツッコミになるけど、配列をリスト化して
longの上位32bitと下位をそれぞれインデックスにしていまえば
javaとかでも1要素8byteで事足りた
http://ideone.com/CsWax バッファ長が2G超えるケースは
javaの配列のサイズ限界がint_maxだから扱えないし
ポインタを使えばインチキが出来る
たとえばある変数のバイトオーダーを入れ替える処理を
自分で書けと言われたら?
CとJava両方書いてみれ(別にカキコしなくていい)
type punningすんな
>>747 >たとえばある変数のバイトオーダーを入れ替える処理を
>自分で書けと言われたら?
書かない。
>>747 >自分で書けと言われたら?
ライブラリ使わせろド阿呆、って言い返す。
てか、無理にポインタ使おうとすんな。
DataGridViewでクラスのメンバ変数一覧みたいなのを作って
変数とセル内容を対応させるみたいなの作るときにポインタないと辛い
クラスは参照でいけんだけどint bool floatとか値型?のもんってポインタないから死ねる
上で出てきた人だよね? まだそんなことやってんの?
さすがにポインタ以前の理解力の問題なんじゃないか
上で言われてるようにリフレクション使えば何の苦もないし
値型もObjectに入るはずだけど何が問題なのかわからない
もしかして*(cells[1,2])=4;みたいな感じでメンバ変数を更新したいってこと?
そんなことしなくても変数名分かってんだからリフレクションで書き換えればいいだろ
>>755 >上で言われてるようにリフレクション使えば何の苦もないし
なんの苦もなくは嘘だろ
すげー大変だった
これだったら絶対ポインタあったほうがいいよ
配列かどうかまで判断しないといけないとこも死ねる
実行時型情報はあくまで型だけでインスタンスを特定できるもんじゃないんだよね
つまり、特定するにはどこどこのだれだれの〜って上からたどってこないと死ねる
>>756 ちげーよ
DataGridViewで特定の変数にアクセスしたいって言ってるのになんで別の例を出すんだ
変数名わかってもどこのインスタンスの(配列のN番目という可能性もあり)どのメンバのなかのこのメンバの12番目の要素
とかいうとこまでとってこないといけなくて面倒だろうが
ポインタだったら格納時にアドレスだけ保持って「ハイ、終了」だろが
>>757 ポインタだったら簡単とか言ってるけど
そのポインタの型情報はどのように取得するの?
泥臭く手書きで網羅するの?
デバッグ情報として埋め込むの?
int*とか決め打ち?
リフレクションがどういうものなのか
理解出来ていないのでは?
>>758 リストにこっそり入れときゃいいじゃん
Visible falseで
リフレクションだと俺がやった感じだとあくまで型しか取得できなくて
ポインタっぽいことはできない感じだったな
できる方法があったら教えてくれ
配列なのかそうじゃないのかとか判別して・・・ってやるのすごく面倒だったんだ
>>759 >リストにこっそり入れときゃいいじゃん
めんどくせぇよw
てか、用途が分からん例えでイメージしづらい
> 配列なのかそうじゃないのかとか判別して・・・ってやるのすごく面倒だったんだ
ポインタでも同じでしょ
てか、配列をポインタで管理すると
型情報の他にもしくはNULL終端縛りかlengthまで必要になるよね
>>760 同じじゃないって
リフレクションが持ってるのは型だけなんだって
馬鹿でもわかるように説明すると
void* p = &unko[12];
こういう情報をとれない
>てか、配列をポインタで管理すると
そんな話してない
DataGridViewのセル1つが変数1つに対応してる形だ
こっちが挙げてる例からなんで脱線するようなことをいうんだ
お前、ツカエネー奴だろ
会議でいっつも関係ないことを発言しだす不思議ちゃんだろ
正直、邪魔だからw
頭凝り固まってんな
例えば
abstract class FieldRef {
public abstract object Value { get; set; }
}
とでもしておいてリフレクション使うなり配列の要素使うなり好きに実装したら多態で綺麗に扱えるぞ
ポインタよりずっと柔軟だろ
口だけでうごくプログラムをかけない初心者はダマットレ
>>761 > リフレクションが持ってるのは型だけなんだって
void*で受けたら型すら分からんですよ
型が分かれば十分じゃない?他に何が必要なの?
> void* p = &unko[12];
> こういう情報をとれない
即値な理由もunkoの型も使い所もpの寿命も…
何が言いたいのか分かんない
> >てか、配列をポインタで管理すると
> そんな話してない
>> 配列なのかそうじゃないのかとか判別して・・・ってやるのすごく面倒だったんだ
してるじゃん
> DataGridViewのセル1つが変数1つに対応してる形だ
言ってる意味は分かるよ
型が決め打ちってことはないだろうから
デバッガのGUIフロントエンドにありがちのtreelistではなく
tree + listのツーペインのlist部分みたいな位置づけでしょ?
で、リフレクションありとなしでは手間が違うって言ってるの
バインドや取得
どう考えてもめんどくさいよ
非バインドのDataGridViewはまあ時々使うけども
カラム毎に別の変数てのはちょっと賢くないなあ。
>>764 超馬鹿だなお前
わかりやすい例出してやったのに
型がわかってもunkoの12番目っていう12番目ってところを保存できねーだろが
本当にカスだなお前
ってか、お前がリフレクション使ってなんにもやったことがないのはわかった
768 :
767:2012/03/09(金) 10:20:14.74
ちょっと改善
http://ideone.com/ThC5i class Entry{
public int n;
public int[] na = new int[15];
}
public static void Main(){
{
Entry et = new Entry();
ICell c = Bind(et.na, 12);
c.Set("200");
et.na[12] += 50;
Console.WriteLine(et.na[12] + " " + c.Get() + " " + c.Type()); // "250 250 System.Int32"
}
{
Entry et = new Entry();
ICell c = Bind(et, "n");
c.Set("500");
et.n += 50;
Console.WriteLine(et.n + " " + c.Get() + " " + c.Type()); // "550 550 System.Int32"
}
}
#include<stdio.h>
int main(void)
{
char a[][13]={"前田敦子","大島優子","渡辺麻友"};
int i;
for (i=0; i<3; i++)
printf("%s\n",*(a+i));
return 0;
}
変数名に下品な名前を使っちゃう人間は
例外なくカリカリしており、例外なく喧嘩っ早く、
流暢に煽り文句を並べるのが得意である。
その書き込みから滲み出る雰囲気たるや、
工事現場のヤンキーなDQNと全く変わらない。
さすが、デジタル土方と言われるだけのことはある。
malloc多用
彼は理解してないよ
ゆとり世代はキーワードだけ拾って
思い込みで返答しちゃう奴多い
776 :
767:2012/03/10(土) 18:32:08.71
>>761 >リフレクションが持ってるのは型だけなんだって
型だけでなくどのクラスのどのメンバって情報持ってるよ
>void* p = &unko[12];
>こういう情報をとれない
ICell c = Bind(et.na, 12); で情報を保存出来てるよ
配列でないメンバも同様
ICell c = Bind(et, "n");
構文は関係無いよね?
>>764 >unkoの12番目っていう12番目ってところを保存できねーだろが
同上
>>772 認識は上に書いた通りなんだけど
出来れば具体的に指摘して欲しい
>>776 え?そんな特定の型限定のソース出されて言われても困るんだけど
>>776 出来ないって事でよくね?
もちろん、(unkoさんには)出来ないという意味だが。
>>777 そんなレベルの話?
C/C++でもvoid*のままじゃ読み書き出来ないでしょ
UIとしてString、例としてintの実装だけ書いたけど何も限定されてないよ
それにDataGridView使うなら基本的な型用のUIは揃ってるから
Type渡すだけユーザーが入力した文字列を勝手に変換(int.Parseとか)してくれるよ
>>779 だから上から読めって
思い込みで話しすぎだろお前
現状、日本語でのコミュニケーションは無理だから
unkoの人はcodepadなりideoneで
さっくりコードで示したらいいんじゃないかな?
察してもらう→諭される
この繰り返しは不毛だし
本人もそんな扱いされるのは苦痛じゃない?
>>783 いや、別に回答してくれなんて頼んでないけどw
こっちが知りたい内容はもうわかってるんだし
話題を続けようがないしw
787 :
営利利用に関するLR審議中@詳細は自治スレへ:2012/03/29(木) 17:15:36.87
ポインタのわからないところは、その仕組みを理解する「必要性」だ
forやifは条件を分岐させたり繰り返したりする、これは誰でも理解できるし必要性も分かる
配列や構造体も、それを利用する際に特別な宣言を用いて利用する、これも他と差別化しやすい
ただポインタに関しては「概念」や「内部構造」の話になっている
俺もポインタが全くわからんが、わざわざポインタを利用する「必要性」が無いという事は理解できる
もちろん優良なプログラムを組む上では欠かせない要素ではあるだろうが
昨日今日に、文字の出力や条件分岐を学んだ段階の人間には、まだまだ早すぎる知識
これが理系の悪いところ
物事の必要性や順序をうまく説明できない
説明するとなると、妙に入り組んだ話になったり
別の聞きなれない単語を持ち出したりしてと
話を聞けば聞くほど、こんがらがってくる
かと思えば、抽象的で漠然としたイメージの話をしだしたり
そのイメージも、人それぞれで違っているから更に分かりづらい
ひょっとしたら、どいつもこいつも「分かってるつもり」で「なんとなく使えてる」だけで
その真意には届いていないのではないか?とも思えてしまう
だから重要なのは
「必要性」「重要性」「利便性」
この3つを押さえて、ポインタを利用しなかった場合にどういう手間やデメリットが発生するのか
という具体例も持ち出してくれないと理解に苦しむ
制御文や配列のように、使い方が明確化されていればこんな苦労も無いのだが・・・
変数を指す変数があれば便利な場合がある
そんだけ
配列とかと同じ
必要性とかわりとすぐピンときたけどなw
関数に配列の先頭アドレス渡すのって合理的じゃね?
変数のサイズ、構造体のサイズってのを理解している段階であれば分かるはず。
そんなことぐらい自分で判断しやがれ
ここで聞いても答えはでんだろ
他の人の意見を聞くならまだしも
お前が信じるかどうかなんて知ったことじゃねえ
Cをつかうなら、高速を追求する。ムダをはぶくために、ポインタを活用
BMPみたいな数MB単位の巨大配列とかいじるとき、ポインタなしだとやってられんでしょ
動画だったらこれをさらに数十枚分キャッシュとかが普通なわけで
まあ、せいぜい数KB程度の配列や構造体しか扱ったことのない者には、なかなかありがたみはわからんかもね
793 :
営利利用に関するLR審議中@詳細は自治スレへ:2012/03/30(金) 01:11:00.92
つまり
コインロッカー=実際の変数
封筒=ポインタ変数
週刊少年ジャンプ=実際の変数の中身
ジャンプの号数と、ロッカーのナンバーは相互関係にある
(例 ジャンプ40号は40番のロッカーに入っている)
とした場合
封筒の中に、コインロッカーの番号を書いた紙が入っており
その紙に書いた番号を参照することで、目的の号数のジャンプを手に入れることが出来る
という解釈でいいんだろうか?
コインロッカーだの箱だのといった変に具体的なものよりも、
方眼紙のマス一つが1バイトみたいな感じで抽象的に考えたほうがいいと思う
>>787 必要性もクソも、ポインタを備えた言語は多くの場合
他の言語にあるような「参照」がないんだからさ…
>>792 配列操作はポインタ無い方が最適化しやすいでしょ
>>788 >>789 >>792 おまえらが言ってるのはただの「参照」。
そんなのはjavaやその他の言語にもある。
ていうか配列を丸ごとコピーする実装の言語なんてたぶん無いw
ポインタが難しいのはそこじゃないことを判りもしないで恥ずかしいレスすんな。
>>797 難しいのがどこか言わずにそんなレスしても恥ずかしいだけだぞw
教えて欲しいなら憎まれ口叩くより素直に教えてくださいって言った方が得だよ
800 :
営利利用に関するLR審議中@詳細は自治スレへ:2012/04/01(日) 09:10:11.09
結論 プログラマーは大半が揚げ足取りで、そこで自分の優位性を誇示したがる人種
揚げ足取りの達人なのは必須スキルなので優位性は存在しない
似非ぷろぐらまを排除する性質については認める
揚げ足取りをはじめとした強弁や詭弁の技術を利用した責任回避が本当に食えるスキルというものだからな
えー。C++ではともかく、Cではアドレスとサイズと型を格納する変数って言えばすむだけじゃーん^^
アドレスのn番地を指し、そこからmバイトを型xと看做す。そう教えてくれてるだけー^^
↑すげーな初心者ってw
すごいだろ^^
ポインタを難しく感じるのは頭が悪いからだって結論でてるじゃん
>>797が「ポインタが難しい」って言ってるのは
>>797の頭が悪いからで、
頭悪くない人にはポインタはどこも難しくない。つるっと入ってくる。
>>803 アドレスの格納先は変数だけど、サイズや型情報が送られるのは構文解析器の方じゃね?
>>804 こんなもんだろ
>>799 ポインタのどこが難しいのかどうか教えて下さい。お願いします
スレタイ同様、私には「ポインタを難しいと言う奴が理解できない」ので
>>793 下手に例えるとよくないぞw
ポインタでそんなんだったら、
OOPにおいてはまたワンワンニャーニャーして遠回りしてしまうぞ。
>>808 断片的に何度か書いているが、もっかいまとめてみる。
まず参照だ。コードの例で示してみる。
void func_a() {
OBJ a = new OBJ[10000]; //でっかい配列
func_b(a); //関数内では参照している
//なんかの処理
//ここでaは不要になるので、コンパイラは自動的に解放処理を呼び出す
}
void func_b(OBJ b) {
//なんかの処理
//ここでbは不要になるので、コンパイラは自動的に解放処理を呼び出す
}
こんなコードがあったとする。func_bにはaの参照を渡している。
ここで大事なのはaとbの解放タイミングがわからない点だ。どちらかの処理が済んでないのに、もう片方を解放したら落ちてしまう。
さて、参照とポインタの違いは「参照ならポインタ以外のワークも共有できる」という点だ。この場合ならbに渡す時に、「この変数は2箇所で使われている」という情報を書き込むことが出来る。
それにより、aおよびbの解放時に、じかに解放するのでなく、「使われている回数を1引き、0になったら解放する」という処理に変えることで、安全に解放処理を呼び出すことができる。
ポインタではそうはいかない。func_bに渡されるのはaかもしれないし、&a[1]かもしれない。するとワークは渡せないので、もちろんfunc_bで解放することはできない。すると解放処理をプログラマにやらせるしかない。
だからfree関数が用意されている。しかし上記のケースでは、func_aがfunc_bより先に終わるかもしれないから、安易にfunc_aの末尾でfree(a)などとやったら落ちてしまう。これがポインタの難しいところだ。
↑いけね。書き忘れた。func_bはfunc_aと非同期に動くと思ってくれ。
>>811 それで何が言いたいのか知らんが、スマートポインタって聞いたことないの?
>>811はExceptional C++でも読むべき
>>811 そういうのはポインタどうこうより
ファイルハンドル等でも同様のリソース管理の話じゃないのか?
C++ではRAIIで扱えばいいだろう
>>811 なるほど、「難しい」というだけあってまるで理解していない。
帰れ。
>>811 参照参照つっといて、いわゆるC++の参照/ポインタという関係じゃないのなw
しかも非同期で排他処理の部分を持ち出して何がいいたいのやらw
コメント欄に限りがあるから非同期処理を例に挙げただけなのに、
否定するために読んでる奴らの頭には何を言っても通じないようだな。
そうやって勝手に罵り合ってろよ。
811の翻訳(エスパー)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
void* f(void* a) {
sleep(1);
printf("%d\n", *((int*)a));
}
g() {
int* a = malloc(sizeof(*a));
*a = 123;
pthread_attr_t pta;
pthread_attr_init(&pta);
pthread_attr_setdetachstate(&pta, PTHREAD_CREATE_DETACHED);
pthread_t pt;
pthread_create(&pt, &pta, f, (void*)a);
free(a);
}
main() {
g();
sleep(2);
}
822 :
821:2012/04/04(水) 12:43:36.76
たしかにこの場合f()で問題が起きる
(この手のバグは発見が難しいので重要)
>>821の謎の努力の意図がわからないw
>>811にもかいてあるように、「非同期で」っていう説明で十分だよ。
それで分からないやつはここにはいないだろう。
825 :
821:2012/04/04(水) 15:08:48.17
このスレの住人に限らず、「ポインタが難しい」っていう人は
排他制御やリソース管理、例外安全、等々も難しく感じるかもしれない
スカラ的な頭の良さなのか、それとも向き不向きのようなものか分からないけど
メモリに関してはGCによって凌いだとしても
その先で壁に当たりそう
あと
>>787のレス見て思ったんだけど
>「必要性」「重要性」「利便性」
これを「自分で考えようとするかどうか」がひとつの境界なんじゃないかと
排他とか再帰とかは、上から下というそれまでの法則が乱れるから混乱するんだよw
難しい、というよりは素直に表現すると、単に複雑さの問題だな。
その複雑さを人間の扱える形にする為のプロセス代数や再帰理論です
同様にポインタに関しても分離論理とか使うやり方があるから感覚が無理ならそういう方向から攻めるのも手
100位まで読んでここまで飛ばして書き込んでる馬鹿だけど、
一番単純なポインタは確保された実データが入ってるメモリの位置を示すアドレスが入ってる変数でいいんだよね?
配列なら先頭のアドレスが入ってる。
ポインタaへのポインタbとなると、ポインタbにはポインタaを指すアドレスが入っていて、
結局はポインタaが指すアドレスにあるデータが変わるってだけなのかな??
馬鹿には無理
#include<stdio.h>
int main(void)
{
int x;
int *y = &x;
*y = 10;
printf("%d", x);
return 0;
}
>>830 >一番単純なポインタは確保された実データが入ってるメモリの位置を示すアドレス
一番単純も何も、ただそれだけ。
>が入ってる変数でいいんだよね?
ポインタ変数は変数だけど、ポインタは変数じゃない。定数もありうる。
834 :
デフォルトの名無しさん:2012/04/14(土) 22:02:06.09
>>832 初心者向けに良くある例文コードでだいたいを理解出来たら馬鹿だと思い知らずにすむのですが・・・。
>>833 >>32が解らない方で、
>>57が、もしそのまま実践してくれるのなら凄く親切な講師。
そんな事を思いつつ、試しに聞いてみました。
参照型の一つの種類のようなものだと思うのですが、ポインタaへのポインタbみたいな、
>>832の int *y = &x; もxのアドレスをポインタyに入れて10を代入してそのままxに10が入る。
ショートカット、エイリアス、シンボリックリンクみたいなものとしてそればいいのかなんなのやら。
定数もポインタが示すアドレスにあるものを指す、と言う理解でいいのか・・・。
コード実行結果
http://ideone.com/KoEwp http://ideone.com/KkH5E 配列の基本が理解出来たら大体分かったと思っていい
車で言うとJavaとかはオートマ、C/C++とかはマニュアル
その後にポインタ演算、スタック、ヒープ
Javaの参照との違いとか色々知っていけばいい
(java)
class Main{
static void f(int[] a){ a[0] += 5; }
public static void main (String[] args) {
int[] a = new int[1];
a[0] = 10;
f(a);
System.out.println(a[0]); // 15
}
}
(C++)
#include <iostream>
void f(int* a){ a[0] += 5; }
int main() {
int a[1];
a[0] = 10;
f(a);
std::cout<< a[0] << std::endl; // 15
return 0;
}
それだとJavaの参照と、ってとこがさっぱりわかんなくないか?
ぬるぽ
東電がっ
_
ミ ∠_)
/
/ \\
ウイーン Γ/了 | |
ウイーン |.@| | | ガッガッガッ
| / | . 人
|/ | < >_Λ∩
_/ | //. V`Д´)/
(_フ彡 /
atexit()でつかう
参照とのハッキリとした違いは、演算ができるってところだろうな
そもそも山椒なんてポインタを理解出来ない落ちこぼれが作った後付概念だろ
>>842 どっちかっつーとC言語の悪影響だと思う
単に表記が解りにくいだけだったのを、ポインタそのものの問題にすり替えちゃった
C++の引数で、参照とポインタの使い分けどうしてる?
俺は全てをポインタにしてる。
引数に限らずそもそも参照は、戻り値の時ぐらいしか使わない。
hoge & func(){
hoge *fuga = new Fuga();
fuga->hage();
return *fuga;
}
こうですか?
んで、メンバ関数でもないのに参照を返すと。┐( ・〜・)┌
>>844 ・コピーコンストラクタ(C++11ならmoveコンストラクタも)、operator=は参照。
・swapも参照。
・API等既存のライブラリに合わせる必要があるならそれに合わす。
それ以外は
・void*は参照で代わりが効かないのでポインタ。
・read-onlyで参照が取れるならconst付き参照。
・書き込みがあるならポインタ。
ポインタはスマートポインタを含む。
個人的にC++の参照は、あんまり好きになれないなぁ。
どう形容すべきか分からないんだが、なんかこう、気持ち悪い。
演算子オーバーロードとかにほぼ必須だってのは何となく解るんだけど。
呼び出し側のコードだけでは値渡しか参照渡しか分からない所とか?