ポインタを難しいと言う奴が理解できない at TECH
[2ch|▼Menu]
1:デフォルトの名無しさん
08/07/27 10:47:14
int i = 10;
int * p = &i;//int型ポインタpにiのアドレスを代入する
簡単。
char str1[] = "abcde";
char * str2 = "abcde";
上と下は同じでどっちを使ってもいい。

2:デフォルトの名無しさん
08/07/27 10:52:49
>>1
5ポイント

3:デフォルトの名無しさん
08/07/27 10:52:54
str1 = "別の文字列"; //エラー
str2 = "別の文字列"; //OK

上と下どっちを使うか状況によって異なる。
同じとかいってしまっているお前は、結局何も理解出来ていない。

4:デフォルトの名無しさん
08/07/27 11:03:14
if(sizeof(str1) == sizeof(str2))
  puts(">>1は天才");
else
  puts(">>1は愚か者");


5:デフォルトの名無しさん
08/07/27 11:20:52
>>1
つ、釣られないぞ!

6:デフォルトの名無しさん
08/07/27 11:25:57
* を両方から離して書くのは
かけ算と紛らわしいので嫌い

7:デフォルトの名無しさん
08/07/27 11:28:07
その昔、ポインタの冒険と言うゲームがあってだな

8:デフォルトの名無しさん
08/07/27 11:47:27
code、data、bssの何処に配置されるのかが重要

9:デフォルトの名無しさん
08/07/27 11:54:39
>>1

*(s+5)
s[5] (⇒ Compile時に*(s+5)に変換される)
5[s] (⇒ Compile時に*(s+5)に変換される)

は全部同じ意味だから当たり前だろ。

10:デフォルトの名無しさん
08/07/27 11:59:12
↑はずれ

11:デフォルトの名無しさん
08/07/27 12:04:28
実務で使うようなGUIプログラミング・Windowsプログラミング(CとC++どちらも必須。他言語のGUIは遅すぎる)を学びたいなら、
構造体とポインタの絡みくらいは理解しておく必要がある。
これを理解しておかないとWindowsプログラミングの入門書すら読めない。

しかし今は良書が揃っているので馬鹿でなければ2〜3週間で習得できるだろう。


「C言語 ポインタ完全制覇」
(言わずと知れたポインタのバイブル。これを読めば99.9%の人はポインタが得意になる。Amazonでも2chでも類を見ない程の高評価。)
URLリンク(www.amazon.co.jp)

「C言語ポインタが理解できない理由」
(人によって好き嫌いがあるが、気軽に読める)
URLリンク(www.amazon.co.jp)



12:デフォルトの名無しさん
08/07/27 12:05:52
>>10
はずれはお前の頭だ

13:デフォルトの名無しさん
08/07/27 12:08:34
* と []は同じ

14:デフォルトの名無しさん
08/07/27 12:09:48
とは限らない

15:デフォルトの名無しさん
08/07/27 12:13:01
char str1[] = "abcde";
char *const str2 = "abcde";

これならよかったのに

16:デフォルトの名無しさん
08/07/27 12:17:00
ここはバカのすくつか・・・。

char (*p)[6] = &str1; // OK
char (*p)[6] = &str2; // Error

if (sizeof str1 == sizeof str2) {
 puts("same");
} else {
 puts("different"); // こっちが出力される
}

17:デフォルトの名無しさん
08/07/27 12:19:34
str1[0] = 'A'; // OK
str2[0] = 'A'; // 未定義動作

これもだな。

18:デフォルトの名無しさん
08/07/27 12:24:26
str2はただのアドレスを格納するだけの変数(普通は4byte)
str1は実体を持つ(char*6 = 6byte)
"abcde"は定数でメモリのナンチャラ領域に密かに存在したまま。


19:デフォルトの名無しさん
08/07/27 12:26:53
"abcde"はfree()が必須ですか?

20:デフォルトの名無しさん
08/07/27 12:28:31
お前は一体何を言っているんだ?

21:デフォルトの名無しさん
08/07/27 12:29:48
1.str1は定数で、str2は定数じゃない。(str1++とか出来ない。)
2.str1の指す領域は変更可能で、str2に関しては未定義。
って感じ?

22:デフォルトの名無しさん
08/07/27 14:42:45
あ、いや、その・・・・
ポインタは理解できる。
がしかし、
ポインタのポインタが出てくるともう俺の頭はオーバーヒートしてしまう。
すんませんVBしか触ったことがないもので。

23:デフォルトの名無しさん
08/07/27 15:05:01
こんなテキストベースのコミュニティで聞くより
>>11の本を買って視覚的に学んだほうが早い

24:デフォルトの名無しさん
08/07/27 15:10:21
くだらない本を読んでいる暇があったら、アセンブラをかじればいいだけ。

25:デフォルトの名無しさん
08/07/27 15:44:48
前スレかもしれない

ポインタはどうやって学ぶべきか
スレリンク(tech板)l50

26:デフォルトの名無しさん
08/07/27 17:48:22
>>25
そうでもない

ポインタはどうやって学ぶべきか part2
スレリンク(tech板)

27:デフォルトの名無しさん
08/07/27 20:26:10
ポインタのポインタを理解できないようでは
ポインタが理解できているという言葉も怪しいな。

28:デフォルトの名無しさん
08/07/27 22:12:42
ポインタは理解できたけど、ポインタのポインタが理解できないってのは
大抵ポインタは配列の表現を変えた物と認識している
で、ポインタのポインタ=二次元の配列と考えてしまい混乱する

29:デフォルトの名無しさん
08/07/27 22:47:46
ポインターが理解できないのは
mov eax,esi

mov eax,[esi]
の違いがわからないのと一緒。
この違いがわかればポインターが難しいはずがない。



30:デフォルトの名無しさん
08/07/27 22:51:40
文法が曖昧で難しいのであって、ポインタが難しいのではない

31:デフォルトの名無しさん
08/07/27 22:55:39
このスレタイみたいなことを職場でいう奴がいると本当に萎える
ポインタが分かる・分からないという話自体、ど素人が好む話題だから

32:デフォルトの名無しさん
08/07/27 23:48:03
・なぜポインタを使う必要があるのか
・どういう場合にどういう風にポインタを使うべきなのか

この二点を誰も説明してくれないんだよなあ。
山ほど解説書を買ったけど、前者について解説している本は皆無。
後者については、関数の引数を参照渡しして直接更新して返す
サンプルくらいしかない。
これで理解して使えという方が無理だ。

33:デフォルトの名無しさん
08/07/28 00:01:19
> 理解して使えという方が無理
そう、だから理解しないでなんとなくコード書いて、
そのうちなんとなくみんな分かってきた気になるというのが現状。
悩んでいる暇があったらとりあえず何か書いてみ。

34:デフォルトの名無しさん
08/07/28 00:19:34
>>33
いや、俺は理論から入る人間だから
使う必要性を理解してからでないと使いたくないんだ。

ただ一つ、最近の本で「配列とポインタではポインタの方が
実行速度が速い」という記述を読んだ。
これだよこれ。こういうのをなぜ一番に言わないかね。
初心者は、同じことを配列でできるのに、なぜわざわざポインタを
使うのか、そのことで悩んでるんだから。

「配列とポインタはやってることは同じだけどポインタの方が速い」
この一言だけでポインタを使う理由になるじゃないの。

35:デフォルトの名無しさん
08/07/28 00:31:32
>>34
俺も理論から入る人間だからこそ言える。

たぶんそういう考えの俺らはPG/SE/PMには向いてないよ。

36:デフォルトの名無しさん
08/07/28 00:33:24
この業界の出来る人というのは、常に最新の技術を追い続けている。
必要有か無か、流行るか流行らないか、の判断も付かないうちから、最新技術に興味を示す。

37:デフォルトの名無しさん
08/07/28 00:34:15
実は大嘘
配列とポインタでは配列のほうが実行速度が速い

38:デフォルトの名無しさん
08/07/28 00:37:12
>>34
プログラムなんてどんな言語で作られたモノであろうと結局はCPUがメモリのアドレスを行ったり来たりしている。
隠蔽されてないアセンブラ・Cが速いのは当たり前。

勿論、零細企業で小規模システムの開発しかしていない人にとってはJavaどころかVBでも十分

39:デフォルトの名無しさん
08/07/28 00:38:13
速度と省メモリ

40:デフォルトの名無しさん
08/07/28 01:04:18
結論:ポインタを考えた奴は馬鹿

41:デフォルトの名無しさん
08/07/28 01:15:48
C言語の文法が糞
もっと紛れのない文法の高級アセンブラが普及すべきだった

42:デフォルトの名無しさん
08/07/28 01:28:28
ポインタの必要性くらい書いてある本はある。
書いてないようなら捨ててしまえ。

43:デフォルトの名無しさん
08/07/28 02:17:17
>>40
>>41もいってるが文法がクソなだけ。
先にポインタの概念を取得してからCに入れば
表現の違いでしかないんだけどな。

44:デフォルトの名無しさん
08/07/28 02:25:06
>>32
やっぱプログラミングの入門書には
データ構造の話とかも書くべきだよな。




>>34
ちょwwwwwwwwwwそんな理由www

45:デフォルトの名無しさん
08/07/28 04:56:20
>>34
それが事実じゃないからさ
ポインタと配列は別物であり、使える場所も変わってくる
例えば関数の引数として使えるのはポインタだけで
配列使ってるように見えるのは見せ掛けで実はポインタ使ってるとか
そういう細かい事実があるわけ
今の処理系じゃポインタの方が速いなんてことも別にないし

46:デフォルトの名無しさん
08/07/28 07:36:31
>>37
ハァ?
メモリ上の配列とポインタの事言ってんだったら変わらねーよ。
例え配列がスタックで、ポインタの方をヒープのつもりで発言してても、
確保に時間が掛かるだけで、アクセス速度は変わらん。


47:デフォルトの名無しさん
08/07/28 07:57:28
特定のコンパイラの実装・最適化の話とか?
まー配列の方が当たりをつけやすい場面が多いとはおもうけど
それをもって速いってのもなぁ。

48:デフォルトの名無しさん
08/07/28 08:01:37
ポインタ判らないとかいってるやつはクローじゃ、ラムダ指揮、公開関数(なぜか変換できない)理解できるのか?

49:デフォルトの名無しさん
08/07/28 08:02:33
訂正
→できないのかな?

50:デフォルトの名無しさん
08/07/28 08:18:57
Cのポインタは参照・束縛の概念だけじゃなく
メモリアドレスを意識できなくちゃいけないしな。
ポインタ自体の演算や型キャストもできるわけだし
高級言語にくらべたら無法に近い。

>>48
一見関係ないように思えるけど……。

51:デフォルトの名無しさん
08/07/28 08:21:03
Cでポインタを使わなくてはならないケースは
malloc関数で動的にメモリを確保して使う場合と
scanf関数の引数だろ。
これ以外でポインタを使う香具師はDQN。

52:デフォルトの名無しさん
08/07/28 09:20:26
>>46-47
機械語レベルの話だから別にいいよ
説明する気もないし

53:デフォルトの名無しさん
08/07/28 09:34:29
リンカのことを考えれば
>>29にたどり着く。

54:デフォルトの名無しさん
08/07/28 10:04:59
>>51
  |   |  | |   |    |  | |   |   |   || | |
  |   |  | レ  |    |  | |   |  J   || | |
  |   |  |     J    |  | |  し     || | |
  |   レ |      |  レ|       || J |
 J      し         |     |       ||   J
             |    し         J|
             J                レ
     /V\
    /◎;;;,;,,,,ヽ
 _ ム::::(l|l゚Д゚)| …うわぁ
ヽツ.(ノ::::::::::.:::::.:..|)
  ヾソ:::::::::::::::::.:ノ
   ` ー U'"U'

55:デフォルトの名無しさん
08/07/28 10:17:48
後半は釣りだが、それまでmallocの話が出てこなかったのは異常。

56:デフォルトの名無しさん
08/07/28 10:27:07
>>52
× 説明する気もないし
○ 説明する能力もないし

57:デフォルトの名無しさん
08/07/28 10:32:51
1. 配列を関数に渡す際にどうしても必要
2. 構造体を関数にコピーレスで渡したい際にどうしても必要
3. 別関数内の変数の値を変更したい際にどうしても必要
4. メモリを動的に確保する際にどうしても必要
5. 特殊なデータ構造を実現する際にどうしても必要

ポインタがどうしても必要になるケースは、普通はこのくらいかね。
他にも使う状況はなくはないと思うが。

58:デフォルトの名無しさん
08/07/28 11:07:44
>>56
煽っても何もでないよ

59:コピペ
08/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と書かれた紙が表示されるのであっためでたしめでたし」

60:デフォルトの名無しさん
08/07/28 11:27:13
void func(char *c){
c = 'z';
}
int main(){
char subarac = 'a';
func(subarac);
printf("%c",subarac);
}

この場合を教えてくれ




61:デフォルトの名無しさん
08/07/28 11:29:54
>>60
ひと目で間違いに気づかないとか、もうね…

62:60
08/07/28 11:43:47
>>61
わざとやってるんだが

63:デフォルトの名無しさん
08/07/28 11:48:37
ポインターはどこでもドア。
好きなところに移動してデータを置ける。
開けた先がお風呂だと大変なことになる。

64:デフォルトの名無しさん
08/07/28 12:12:38
>>63
お風呂が溢れちゃいますね。

65:,,・´∀`・,,)っ
08/07/28 12:20:57
>>60
コンパイルエラー

66:60
08/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


67:デフォルトの名無しさん
08/07/28 13:17:34
>>57
おお、いいね。
これを五つの章構成にして
実例とともに詳細解説を加えれば
画期的なポインタの解説書になるよ。
たぶん、今までこういう本はなかったよ。
本を出したら俺は印税の一割でいいよ。

68:デフォルトの名無しさん
08/07/28 13:24:02
1. 配列を関数に渡す際にどうしても必要

可変個引数で渡せる

69:デフォルトの名無しさん
08/07/28 13:33:44
そもそも、配列を使うためにはポインタ演算が必ず行なわれているわけだが。
p[i]というのは*(p+i)でしかないのだから。
# だからこそi[p]という書き方もできるわけで、3["abcd"]なんてこともできると。

70:デフォルトの名無しさん
08/07/28 13:34:48
仮引数を [] で受けてたら、ポインタを使っていることに
気づかない奴もいるかも知れない。

71:デフォルトの名無しさん
08/07/28 13:38:56
そこをきちんと説明しないから理解できないのではないかと思う。

72:デフォルトの名無しさん
08/07/28 13:41:34
scanfを教えるときに&を{おまじない}として教えるのも良くないと思う

73:デフォルトの名無しさん
08/07/28 13:49:32
ポインタの使いどころを書いてる本がないってことはないと思うんだが。

74:デフォルトの名無しさん
08/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

75:デフォルトの名無しさん
08/07/28 13:57:23
char str1[] = "abcde";
だと長さが5の配列の実体が出来ると思ってたんだけど違うのか?
char *str2 = "abcde";
だとリテラル"abcde"のアドレスをstr2に代入すると思ってたんだけど違うのか?

76:デフォルトの名無しさん
08/07/28 13:58:47
>char str1[] = "abcde";
>だと長さが5の配列の実体が出来ると思ってたんだけど違うのか?
違う。長さは6。

>char *str2 = "abcde";
>だとリテラル"abcde"のアドレスをstr2に代入すると思ってたんだけど違うのか?
あってる。

77:,,・´∀`・,,)っ
08/07/28 13:59:35
>>69
いいや
配列p[]を *(p+i)でアクセスするのは無理だろ

78:デフォルトの名無しさん
08/07/28 14:08:47
>>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;
}

79:デフォルトの名無しさん
08/07/28 14:12:55
>char str1[] = "abcde";
なんで長さが5なの?

80:デフォルトの名無しさん
08/07/28 14:25:11
\0を忘れていました。

81:デフォルトの名無しさん
08/07/28 14:30:49
char str1 = {'a','3','-','o','ω'};

82:デフォルトの名無しさん
08/07/28 14:52:49
アドレス空間の概念が理解できてないとポインタが理解できないんじゃない?
あと、できればスタックとヒープの違いぐらいは理解して欲しいけど。

そもそもC言語の場合、スタックにたくさん積みたくない→ポインタの概念導入、っていう流れの気がする。

83:,,・´∀`・,,)っ
08/07/28 15:11:47
>>78
すまぬ

だがこういうのよく使わないかな?
sizeof (a) /sizeof (a[0])
ポインタと配列混同すると痛い目にあう例だが

84:デフォルトの名無しさん
08/07/28 15:24:41
だが

のつながりがよくわからないです

85:デフォルトの名無しさん
08/07/28 15:31:52
>>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;
}

86:デフォルトの名無しさん
08/07/28 15:44:43
きっと配列へのポインタも理解できてないんだろうなあ。

  short (*pa)[3] = a;

87:デフォルトの名無しさん
08/07/28 20:14:21
C言語でint[100000000000000]とかにしちゃうとエラーになるんですけど
(コンパイラだかリンカだかの制約でスタックには○○MBしか積めないルール)

他の言語でも同じなんですか??
Java,VB,Ruby

88:デフォルトの名無しさん
08/07/28 20:18:51
>>86
そんな危険な宣言すんなよ。

89:デフォルトの名無しさん
08/07/28 20:20:33
>>87
仮想メモリとして扱う処理系もあるし、そのエラーと言うのは全部の処理系で確認した?

90:デフォルトの名無しさん
08/07/28 20:21:29
>>87
>C言語でint[100000000000000]とかにしちゃうとエラーになるんですけど
sizeof(int) が4だとして、300テラバイトを超えるメモリを割り当てられる処理系が思いつかない。

91:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/07/28 20:22:49
配列へのポインタ

ポインタの配列
の違いと宣言文法が分からない。

93:デフォルトの名無しさん
08/07/28 20:24:31
訂正

>aを使わずにqが指すshort配列の大きさを調べることはできないの?

aを使わずにpontaが指すshort配列の大きさを調べることはできないの?

94:デフォルトの名無しさん
08/07/28 20:26:41
BCCでもGCCでも
int[200万]あたりでエラーになる。メモリは6GB積んでるのに

95:デフォルトの名無しさん
08/07/28 20:28:44
>>86
アホか
それはポインタの配列だろ

96:デフォルトの名無しさん
08/07/28 20:37:57
>>92
short (*p2a)[X]; // p2aは short[X] を指すポインタ
short *(p2a[X]); // p2a[X] は short を指すポインタ
short *p2a[X];  // 同上

>>93
不可能。

>>94
その配列が静的か動的かによって違う。
つか、6GB積んでたって全部1プロセスで使えるとも限らん。

>>95
1から勉強し直せ。

97:デフォルトの名無しさん
08/07/28 21:15:46
>>96
結局ポインタの配列ってのは?

98:デフォルトの名無しさん
08/07/28 21:31:54
・ポインタの配列

[アドレス][アドレス][アドレス][アドレス]・・・

と言う風にアドレス空間にポインタの配列が確保されていて、アドレスが入っている。

・配列のアドレス

アドレス
 ↓
[データ][データ][データ][データ][データ]・・・

配列の先頭アドレス。インクリメント時にサイズだけインクリメントされる。

・配列のアドレスを保持するポインタ

ポインタ
 ↓
[アドレス]
 ↓
[データ][データ][データ][データ][データ]・・・

これが

(*p)[i];

だと思う。「配列のアドレス」を略して「配列」って呼ぶのはちょっとどうかなと思う。
わかりにくい。


99:デフォルトの名無しさん
08/07/28 21:33:21
ちなみに俺は

int i, *p, *a;
・・・
p = a + i;

って書き方はしないようにしてる。

int i, *p, *a;
・・・
p = &a[i];

って書くようにしてる。
理由は俺がアホで理解しにくいから、

100:デフォルトの名無しさん
08/07/28 21:34:04
変数は配列を考えることができますね。たとえば、次の例ではchar型変数10個の配列を宣言しています。

char charray[10];
ポインタといっても変数なので、他の型と同じように配列を宣言して使うことができます。

char *chr_ptr[10];  (char* chr_ptr[10];でもいい)



2次元配列のことをポインタの配列だという人がたまにいますが、ちょっと違います。
ポインタの配列は2次元配列などではなくあくまでもポインタ変数の配列で、上のように宣言したものは1次元配列です。
メモリの確保のされ方からいって、2次元配列とポインタ配列は全く違うものです。


101:デフォルトの名無しさん
08/07/28 21:35:58
別に、char型の2次元配列と思っていいんじゃないの?


102:デフォルトの名無しさん
08/07/28 21:37:33
ポインタは完璧!だと思ってたのにこのスレ見たら自信なくなってきた

103:デフォルトの名無しさん
08/07/28 21:41:12
お、おれも!

104:デフォルトの名無しさん
08/07/28 21:45:46
これらのスレ>>1から読めばちょっとは力付くよ・・・余計混乱するかもだけどw

ポインタはどうやって学ぶべきか
スレリンク(tech板)l50
ポインタはどうやって学ぶべきか part2
スレリンク(tech板)l50
ポインタ死ねよ。
スレリンク(tech板)l50

105:デフォルトの名無しさん
08/07/28 21:46:07
俺はアホばっか見てて自惚れそうで怖くなってきた。

106:デフォルトの名無しさん
08/07/28 21:48:53
**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:デフォルトの名無しさん
08/07/28 21:51:27
これでFA


(intへのポインタ)の配列
int* ponta[10];


(int配列)へのポインタ
int(* ponta)[10];



108:デフォルトの名無しさん
08/07/28 21:52:51
(int)へのポインタ
int* ponta;


??
int(* ponta);

109:デフォルトの名無しさん
08/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) に自動変換が効くのは一般の配列の場合と同様。

110:デフォルトの名無しさん
08/07/28 21:58:34
>>106
**argv は文字列配列の先頭アドレスが確保されている配列の先頭アドレスのポインタ。

言い換えると文字列群の各文字列の先頭へのアドレスが配列で保持されていて、その配列の先頭アドレス。

"test"
"yaruo"
"bararaika"

と文字列があったら、 "test"の "t" のアドレス、"yaruo" の "y" のアドレス、 "baranaio" の "b" のアドレス


[アドレス][アドレス][アドレス]

と言う風に格納されていて、その一番最初のアドレスが argv。

要するに、

argv が指すアドレス
 ↓
[アドレス][アドレス][アドレス]
 ↓    ↓    ↓
"test"  "yaruo"  "bararaika"

ってなってる。


111:デフォルトの名無しさん
08/07/28 21:59:02
>>109
里佳石井素股

112:デフォルトの名無しさん
08/07/28 22:14:16
>>110
>**argv は文字列配列の先頭アドレスが確保されている配列の先頭アドレスのポインタ。
文字列配列じゃなくて、文字列または文字配列じゃね?
「文字列群」が文字列配列であるかはどうかは**argvには関係ねぃし。

113:デフォルトの名無しさん
08/07/28 22:21:44
**argvは、機能的にはどう見ても
ポインタの配列なのだが、
星が二つついてるのだからあくまで
ポインタのポインタと理解しなければならない。

114:デフォルトの名無しさん
08/07/28 23:15:58
*argv[]
この書き方が好きだ

115:デフォルトの名無しさん
08/07/28 23:25:43
要するに、c では「配列」の実体だけを書くことができないんだよ。(anonymous 配列を書くシンタクスがない)
書けるのは「配列の名前」で、それは配列の実体へのポインタをそう呼んでいるだけ。
char a[128]; というときの a 自体は配列ではない。a は「配列の名前」で、それは [128] という配列実体へのポインタ。
その a へのポインタは、char (*a)[128];

116:デフォルトの名無しさん
08/07/29 01:27:34
日本語でおk

117:デフォルトの名無しさん
08/07/29 01:56:11
[]演算子が混乱の元だ。
シンタクス・シュガーではなく、
シンタクス・ビターになっとる。

118:デフォルトの名無しさん
08/07/29 01:59:28
うまくない

119:デフォルトの名無しさん
08/07/29 01:59:30
わざと分かり辛く書いてんだろ。
[]も*も同じだと思えばいいんだよ。そのうち違いが分かってくるさ。

120:デフォルトの名無しさん
08/07/29 06:53:10
>>105
俺は改めてコの業界の糞さを思い知らされた。

>>115
自慢げに適当な嘘並べるな。
オブジェクト「a」そのものは配列であり、その右辺値が「配列の先頭を指すポインタ」になるだけだ。

121:デフォルトの名無しさん
08/07/29 07:17:11
>>120
2ちゃんに書き込む人間はみんな糞ですがなにか?
オレモナー

122:デフォルトの名無しさん
08/07/29 12:06:30
>char * str2 = "abcde";
いまだにここが分からない
ポインタに何故文字列を代入できるの?

123:デフォルトの名無しさん
08/07/29 12:09:35
>>122
"abcde"はconstな文字列(≒char配列)ですが、右辺値はconstな文字列へのポインタになります。従って、代入できるわけです。
char foo[] = "abcde"した後、char * p = fooと言うように代入できるのと同じことです。

124:デフォルトの名無しさん
08/07/29 12:41:40
>>122

それは文字列の書かれてる場所を教えてるだけ。
文字列自体は別にある。

だからその後に str2 = NULL; なんてやったら、"abcde" のありかは永久に失われる。


125:デフォルトの名無しさん
08/07/29 12:50:00
char * str2 = "abcde";
の"abcde"はstaticな感じって言えばいいのかな?
constな無名変数とでも言うか

126:デフォルトの名無しさん
08/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:デフォルトの名無しさん
08/07/29 13:44:37
115は良くある間違いで、(わかってて書いてたらスマン)120の言うとおりCの配列とポインタは明確に別物
どちらで宣言するかで、動作が変わる
具体的に言うと、sizeof()の動作が、ポインタの場合はポインタのサイズ(通常は4)を返すが、
配列の場合は使用バイト数を返す

混乱のもとは、[]記号が、宣言、右辺値、左辺値、それぞれのケースで意味が微妙に違うところ
整理してないと、すぐわからなくなる

128:デフォルトの名無しさん
08/07/29 13:50:45
>>126
一言で言い表せないよねなかなか

129:デフォルトの名無しさん
08/07/29 16:30:04
>char (*a)[128];

こういう表現って普通に使います?
おいら使ったことないんだけど。

130:デフォルトの名無しさん
08/07/29 16:33:52
泉源寺に()つけちゃって大丈夫なんだっけ

131:デフォルトの名無しさん
08/07/29 16:37:36
配列へのポインタ(≠ポインタのポインタ)が必要なときはそうせざるを得ないね。

132:デフォルトの名無しさん
08/07/29 16:39:59
そんな宣言はしない
使う時にキャストするから。

133:デフォルトの名無しさん
08/07/29 17:47:59
>>129
横WIDTH個、縦HEIGHT個の長方形のchar配列を動的に確保したい時、
char (*tbl)[WIDTH] = malloc(sizeof(char)*WIDTH*HEIGHT);
とかやる。
tbl[y][x] = data;
とかいうふうにアクセスする。
>>130
論外
>>132
おまえだけ


134:デフォルトの名無しさん
08/07/29 17:53:27
私は
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と言う風にアクセスするかな。

135:デフォルトの名無しさん
08/07/29 19:18:00
>>133
なるほどそういうことですか。ようやく意味がわかりました。

136:デフォルトの名無しさん
08/07/29 19:19:31
サンプルのためのサンプルじゃなくて、実際的なシチュエーションが思いつかん。
まったく無責任な想像だが、メッセージ通信処理とかで使えそうかなぁ。
1個のチャンクが固定長でうんちゃらかんちゃらとか。まーよー知らんけど。

137:デフォルトの名無しさん
08/07/29 19:30:18
メッセージ通信でポインタ使う奴の気が知れない。

138:デフォルトの名無しさん
08/07/29 20:08:03
リストとツリーをC言語で自力で実装できるぐらいポインタを理解しておけば、
現実問題としてポインタ周りで困ることはあんまりないな。



139:デフォルトの名無しさん
08/07/29 21:49:47
char (*p)[4];
って有ったとき、p++てやると、
pは4バイト移動するって考えると分かりやすいな。

140:デフォルトの名無しさん
08/07/30 09:42:39
>>139
で、実際はそうはならないので混乱する、と。

でも混乱するのは理解が足りない所為だよ。

141:デフォルトの名無しさん
08/07/30 10:18:13
>>136
処理を順次実行したい場合の関数ポインタの配列とか。
後は可読性を捨ててでも処理速度を稼ぎたい時とかかなぁ。

使わない方がコード的に遅くて長くても安全って場合の方が多いよなぁ。
特に複数人でコードを書く場合は。

142:デフォルトの名無しさん
08/07/30 13:05:37
ぱっと見で動きの想像しにくいポインタの使い方はちょっとなあ。
2次元以上だったら最大値規定して最初から配列取るわ。

143:デフォルトの名無しさん
08/07/30 13:24:17
>>133
それC99じゃないとWIDTHを変数にできないから困る。
できればやりたいんだけどね。

144:デフォルトの名無しさん
08/07/30 14:20:47
define

145:デフォルトの名無しさん
08/07/30 14:42:36
#define PTA(sex) *(sex)
#define TRF(sex) &sex



main(int itn, char PTA PTA)
{
int itn;
scanf("%d", TRF(itn));
write(itn, 4);
}

146:デフォルトの名無しさん
08/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++ ){


147:デフォルトの名無しさん
08/08/01 20:54:15
>>146
すいません。誤爆しました

148:デフォルトの名無しさん
08/08/01 21:24:47

int *********************************a;


149:デフォルトの名無しさん
08/08/02 03:41:14
a.next->next->prev->next->next->name = "shine>>148";

150:デフォルトの名無しさん
08/08/02 03:59:13
輝け148

151:デフォルトの名無しさん
08/08/02 09:25:34
昔、トリプルポインタを使っているコードを業務で見た。
それ自体はよくできているプログラムだし、公開されているインタフェースも
ちゃんとしていた。しかしまぁ、これを作った人(ベテランプログラマー)は
よく自分で理解できるもんだ、と素直に関心した。

152:デフォルトの名無しさん
08/08/02 11:03:57
終始ビット演算を使われるよりまし


153:デフォルトの名無しさん
08/08/03 00:55:51
むしろ何で理解できないかが理解できない

154:デフォルトの名無しさん
08/08/03 06:29:00
そういうこと言う奴は理解してない

155:デフォルトの名無しさん
08/08/04 12:13:42
5次元配列をいくつか使っているソースみて爆死した。
書いた本人はリタイアして該当コードは最初から書き直しになった。

156:デフォルトの名無しさん
08/08/04 12:50:32
多次元配列を扱う部分だけLispのコードから生成するとかはやるよ
ルールが決まってて単純にそのルールを繰替えし適用するだけだから
機械にやらせた方が絶対安全

157:デフォルトの名無しさん
08/08/05 01:41:35
配列なんて、マトリックス構成する要素が幾つにでもなるから
何次元だろうとどうでもいいじゃん。


158:デフォルトの名無しさん
08/08/05 01:50:07
量子化学計算やるには5次元配列が普通に必要になるよ。
小原積分計算する時に。

159:デフォルトの名無しさん
08/08/05 01:51:39
といいつつ、まあ実際には普通の配列にはしないんだけどな・・・。

160:デフォルトの名無しさん
08/08/05 11:32:01
>>151
ポインタにダブルだとかトリプルだとか属性があるような解釈の仕方をするから理解できないんじゃないの?
アスタリスクが並ぶのがいやならtypedefすればいいだけの話だし、そうしてしまえばただのポインタと同じことじゃないか。

161:デフォルトの名無しさん
08/08/17 11:40:50
関数ポインタを引数に取る関数ポインタの二次元配列とか
そういうのになってくると泣ける程複雑になる
こういうのってtypedef使ってもいいんだよね?
よくポインタの理解度を試すようなクイズで「typedefを使わずに」とかあるけど、
日常的に使っててもできる気がしないわ

162:デフォルトの名無しさん
08/08/17 11:45:54
人間がコンパイラになる必要は無いんだから
そういうクイズは無視でおkだと思う

163:デフォルトの名無しさん
08/08/18 10:52:16
void (*fnc[YLEN][XLEN])(int(*)(int));

Cエキスパート:出来るけど見にくいからtypedef
なんちゃってプログラマ:出来ないからtypedef、人間コンパイラになる必要はないと言い訳


164:デフォルトの名無しさん
08/08/18 11:50:21
typedefは見やすくするためにあるんじゃなくて、
型を抽象化するために使うべきだと思う。

165:デフォルトの名無しさん
08/08/18 23:01:11
関数ポインタは積極的に typedef しとけ。他は必要なし。

166:デフォルトの名無しさん
08/08/20 12:54:58
そういうのが直ぐできるようになるにはどうすりゃいいんだろうな
規格からルールを理解すれば少しは楽になるんだろうかね?

167:デフォルトの名無しさん
08/08/20 13:03:32
簡単にエキスパートになる方法を教えろと言ってるんですね、わかりません

168:デフォルトの名無しさん
08/08/20 13:13:53
GCCのソース読むのが近道
読めなければそれが読めるようになるまで簡単な物から読んだり
パッチ作ったりしてオープンソースコミュニティに貢献してりゃ10年もすりゃ
今君が想像してる程度のエキスパートには楽になれる

って以前言われたことがある

169:デフォルトの名無しさん
08/08/20 20:50:49
10年かあ・・・
確かに俺がブラインドタッチできるように
なったのは、毎日PCをさわるようになって
10年くらい経ってからのような気がする。
人間、何事も10年は精進が必要なんだね。

170:デフォルトの名無しさん
08/08/20 20:51:55
GCCってそんないいソースか?

171:デフォルトの名無しさん
08/08/20 21:00:02
ブラインドタッチに10年って・・・・身体障害者の方ですか

172:デフォルトの名無しさん
08/08/20 21:09:59
>>171
いや、10年くらいかかっても不思議じゃないと思うぜ。
人さし指タイピングから始めた俺は、タッチタイピングに切替えるだけでかなりの年月を費したが。
それでもまだブラインドタッチにはたどり着けない。
英語キーボードと日本語キーボードを行ったり来たりした日にはもう大変。

173:デフォルトの名無しさん
08/08/20 21:11:17
gaucheの作者も昔HPで
どんな言語でも10年は使わなきゃほげほげって書いてたからだいたいあってると思う

174:デフォルトの名無しさん
08/08/21 15:14:41
タイピングなんて我流でいいよ
どうせ出力見ただけじゃ経過は見えないんだから

175:デフォルトの名無しさん
08/08/23 03:19:03
出力だけ要求されるならそれでもいいが
運指が偏ってると年食ってからバネ指とか悪影響もあるから気をつけろ

176:デフォルトの名無しさん
08/08/23 10:16:24
年とると管理業務になるので問題ないです

177:デフォルトの名無しさん
08/08/24 02:44:08
>>166
無理に使わなくていいと思うぞ。それを必要と感じる時が来たらそうすればいいんじゃないか。

178:デフォルトの名無しさん
08/08/26 11:35:40
#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);

}

179:デフォルトの名無しさん
08/09/07 07:05:32
ポインタ?あれはショートカットだショートカット

っていうセンパイの言葉でわかった

180:デフォルトの名無しさん
08/09/07 10:13:02
たとえ話は、ポインタの理解の役には立たない。

これ定説。

181:デフォルトの名無しさん
08/09/07 15:10:11
使って覚えろ
これが基本ですね、マクロしかりテンプレートしかり各種ライブラリしかり

182:デフォルトの名無しさん
08/09/07 15:54:49
アドレスとデータの区別がつけば、あとは簡単。

183:デフォルトの名無しさん
08/09/07 18:37:35
矢印と箱の差。
図を描いてみればアホでもわかるだろ。描こうともしないでわからないとかほざく無能は氏ね。
構造を把握したうえで、「たぐりよせる」操作と「矢印を作る」操作がわかればあとは簡単。

184:デフォルトの名無しさん
08/09/07 20:09:49
たとえ話で説明するやつの理解はけっこアヤシイ。

ところで、ポインタには型がある事をお忘れなく。

185:デフォルトの名無しさん
08/09/08 14:20:46
>>184
例えを用いずに話して相手が理解出来るなら最初っから躓いてないだろ。

186:デフォルトの名無しさん
08/09/08 14:26:31
例えを用いずにうまく説明できないところがアヤシイw

187:デフォルトの名無しさん
08/09/08 14:39:55
本当にわかっている人は例えなんか使わない。
実際にPGを組ませてビシビシしごく。
ついてこれない香具師は見捨てる。

188:デフォルトの名無しさん
08/09/08 16:52:47
>>185-186
喩え話ってのはどーしたって誤謬があるわけで
「理解“した気に”させる」効果しかない。

189:デフォルトの名無しさん
08/09/08 21:50:34
メモリ上にデータが配置されるイメージさえつかめば
ポインタ使ったプログラムの動きは見えてくるんだよな。

そんな低レベルなことまで意識しなきゃならないというのは、
教える側にするとちょっと面倒でもある。

190:デフォルトの名無しさん
08/09/08 21:52:10
ポインタ自体が低レベルな操作のためにあるもんだし

191:デフォルトの名無しさん
08/09/08 22:12:10
なんかもー面倒くさいからポインタ禁止にしてこんな感じのクラス使おうよw

template<classT>
class Shortcut
{
 T *pTarget;

 // ショートカットを設定
 void SetShortcut( T &target ) { pTarget = ⌖ }

 // ショートカット先にデータを設定
 void SetData( T data ) { *pTarget = data; }
};

名前は>>179から頂きますた。

192:デフォルトの名無しさん
08/09/08 22:15:31
そしてスマポへ…

193:デフォルトの名無しさん
08/09/08 22:18:25
それoperator=とかoperator*とかoperator->とか実装すると便利だよきっとたぶんおそらく

194:デフォルトの名無しさん
08/09/08 22:22:03
C++使ってるとポインタ演算をしなくなるな

195:デフォルトの名無しさん
08/09/08 22:23:43
STLは使わんの?



196:デフォルトの名無しさん
08/09/08 22:25:11
アレは見た目が似てるだけか。スマソ。


197:デフォルトの名無しさん
08/09/08 23:14:41
mplの
metafunc<type>もポインタっぽく思える
metafunc<type>::valueとかで参照できたりするし

198:デフォルトの名無しさん
08/09/08 23:22:20
>>193
+とか-とかも定義しようぜ

199:デフォルトの名無しさん
08/09/08 23:44:12
Cのポインタ演算子*が悪い。かけ算記号と同じなんだもの。
この点だけは、リッチー先生を殴る権利が俺たちにあると思うよ。
俺が言語設計者なら、Data_Pointed_by(ポインタ変数)にする。
あとポインタ変数の型をなくし、すべて1バイトを示すものとする。
ポインタ変数のインクリメント・デクリメントも1バイト単位。

200:デフォルトの名無しさん
08/09/08 23:47:01
>>199
どうしてもポインタをモノにできなかった奴の定番台詞ですな

201:デフォルトの名無しさん
08/09/08 23:57:39
>>199
それなんてCのご先祖様BCPL、特に後半。

202:デフォルトの名無しさん
08/09/08 23:57:44
>>199
そんな糞設計の言語を誰が使うんだよw

203:デフォルトの名無しさん
08/09/08 23:58:41
ポインタの概念を図で説明するときにアドレスの存在を明示しないやつがたまにいるんだよな。
四角から四角へ矢印を引いた図は書けるんだけど、アドレスの存在が意識されにくい図になってる。
つまりこんな図。

□→□

int aという変数にはaという値と&aという値があり、
int *pという変数にはpという値と&pという値と*pという値がある。

これらの5つの要素を図中に明示しないと上手な説明とはいえないね。




204:デフォルトの名無しさん
08/09/09 02:04:43
初心者ですが教えてください。
ポインタ演算で型に応じてポインタが進むのは知っているのですが、
その「どの型ならいくつ進む」という情報は実行ファイル中にどういうふうに保存されているのでしょう?

205:デフォルトの名無しさん
08/09/09 03:02:00
>>204
静的に決まる型を解釈して、そういう言うアセンブラコードに変換されてるんだよ
坊や。


206:デフォルトの名無しさん
08/09/09 03:08:51
動的に決定する型はどうやって決定されるんだろうね。
ああ、CやC++じゃそんな芸当出来ないかw

207:デフォルトの名無しさん
08/09/09 08:44:30
>>204
コンパイラが吐いたasm読めば分かるよ。
よく分からなかったら、型を変えて見比べてみる。

208:デフォルトの名無しさん
08/09/09 09:41:45
>>203 ポインタの俺解釈いいかげんおなかいっぱい

209:デフォルトの名無しさん
08/09/09 10:20:57
>>206
Cは兎も角、C++にはRTTIってもんがあるわけだが。

210:デフォルトの名無しさん
08/09/09 10:53:06
C++のRTTIはデバッグ用途以外では要らない子

211:デフォルトの名無しさん
08/09/09 23:25:55
>>210
いやいやdynamic_castはデバッグ用途ではないだろ。
しょっちゅう使うものでもないけれど。

212:デフォルトの名無しさん
08/09/10 00:42:46
×dynamic_castでオブジェクトの型を判別し、そのオブジェクトのメンバ関数を呼び分ける
→わざわざ多態性のメリットを殺さずに、仮想関数で解決すべき。

○dynamic_castでオブジェクトの型を判別し、判別している側の振る舞いを変える
→これはあり得る。けど委譲で解決したいかな。



213:デフォルトの名無しさん
08/09/10 01:52:31
それは、動的に判定されるというより、
予め考えられる型を全部網羅してコーディングしてるだけだしなぁ。
新たに組み込んだhogehogeクラスのポインタとか実装が無いと動かんだろ?
あ、仮想関数で呼んでもらえば自前で用意しておくだけで追加が簡単か/

214:デフォルトの名無しさん
08/09/11 00:05:54
JavaやC#でこういう感じのコードに時々出食わす。
setObject(new Hoge);
//別のところ
Hoge h = (Hoge)getObject(); //戻り値の型はObject型
帰ってくるオブジェクトは絶対さっきsetObjectしたときの引数という場合。
もしこれがC++だったらboost::polymorphic_downcastの出番だな。

215:デフォルトの名無しさん
08/09/11 14:58:51
>>214
インターフェースを利用できない理由があるの?

216:デフォルトの名無しさん
08/09/11 20:59:10
C言語には文字列がないので文字列ポインタ作っちゃいました的ナ

217:デフォルトの名無しさん
08/09/11 23:36:59
>>215
setObjectやgetObjectは既存のライブラリで、しかも標準だったり有名だったりして
自分が手を加えられるような存在ではないんだ。

218:デフォルトの名無しさん
08/09/12 01:27:35
Cの文字列型は廃止の方向で…

219:デフォルトの名無しさん
08/09/12 03:01:53
メモリモデルよくわからない

220:デフォルトの名無しさん
08/09/12 03:16:36
プログラマにメモリを意識させる言語は糞。
Javaが理想に近いが、記述が冗長すぎてこれも結局は糞。
これからはロジック書きのみに集中できてシンプルな
記述で済む言語がトレンドになる。

221:デフォルトの名無しさん
08/09/12 08:40:39
スクリプト系?

222:デフォルトの名無しさん
08/09/12 09:00:57
ML系やLispのようなLL言語ですね
ロジックといえばprologやマイナーですがCoq, ETIも見逃せません

223:デフォルトの名無しさん
08/09/12 11:33:37
>>220
バターナイフ振り回して「包丁は危険だから糞」って言ってる訳ですね、わかります

224:デフォルトの名無しさん
08/09/12 11:53:19
プロセス空間とかよくわかんない

225:デフォルトの名無しさん
08/09/12 12:06:38
糞かどうかはともかく、誰にでも向くものではないのは確かだね。
まあJavaでも十分メモリを意識すると思うが。

>>219
メモリモデルはポインタとかより遙かに悩ましいね。

226:デフォルトの名無しさん
08/09/12 12:32:18
>>218
「文字列」などという型はありません。

227:デフォルトの名無しさん
08/09/12 12:33:06
>>220
つ[COBOL]


次ページ
最新レス表示
スレッドの検索
類似スレ一覧
話題のニュース
おまかせリスト
▼オプションを表示
暇つぶし2ch

5383日前に更新/60 KB
担当:undef