42
31 28
2020/04/28(火) 21:25:13 ID: wIv8gWIWxx
>>30
遅くなりましたがありがとうございました。
本来なら int* a, bで両方ともポインタ変数になってほしいところを、といった部分が今日やっと理解できました。
ポインタ型へキャストするところで(int *)などとしているので、なるほどな、と。
変数名に*をつけるものと考えてしまっていたので、宣言時と数式内で動きが逆じゃねえかと何年も拒絶反応を起こしていて覚えられなかったようです。
32 ななしのよっしん
2020/06/22(月) 20:10:41 ID: wIv8gWIWxx
ポインタのポインタに詰まってます。
乱暴に書くと、ポインタ配列(char *str[9] 等)と扱いはまり変わらんとのことですが、今の所うまく脳に馴染んでくれない様子。
main関数の(int argc, char **argv)
というのを見てると、コマンドライン引数などに使うのかな、と理解はできるのですが。
33 32
2020/06/24(水) 18:38:24 ID: wIv8gWIWxx
乱暴に書いた例が乱暴すぎてなんか違うわ、ゴメソ。
リテラルの配列やcharの2次元配列で使うときに、特定の文字を探すときとかに使うでいいのかな。
あと、無理にポインタ演算((**hoge)++ とか)も覚えようとしてしまっているから混乱しているのかもしれないです。今はあまり使わないからあまり気にしなくていいよね?
以下駄文。*でポインタ変数のアドレスを参照するところを、他の記号(@等)にできなかったのだろうかと。今言っても遅いけどw
34 32
2020/06/24(水) 18:44:23 ID: wIv8gWIWxx
(**hoge)++は参照先をインクリメントで
**hoge++が正しいポインタ演算でした。
何度も板汚しスマソ。
35 ななしのよっしん
2020/07/18(土) 08:24:18 ID: Wkdi5Ha6HN
配列と変わらんというのは「ポインタへのポインタ」とはあまり関係ない
Cでは式の中に配列を書くと「配列の先頭要素へのポインタ」に置換されるので、要するに配列は宣言した後はポインタとして使っている…というお話
配列に使っているhoge[3]みたいな[]で中身を見る参照も実はポインタに対する演算子
配列はメモリ領域を確保すると同時にその領域へのポインタを宣言するもので、ポインタとして宣言されたポインタは不定領域を指し示す
そういった区別はあるが、配列宣言によって宣言されたポインタもポインタとして宣言されたポインタも参照に関する限り用途は同一ではある
もちろん、動的メモリ確保した場合は最後に開放するという違いはあるけどな
ということで問題は定義された多次元配列を受け取るときで、externするかポインタとして受け取るかという感じになる
ポインタへのポインタを開発現場で実際見たのは、どっかにマスタデータ構造として定義された構造体の多次元配列をポインタで持ち回してるシステムだった
なんかの本に、どうせポインタも[]で参照できるからもうポインタ演算なんてやめちまおうぜって提唱してる人がいたな
36 32
2020/07/21(火) 20:56:27 ID: wIv8gWIWxx
>>35
ありがとうございます。
とりあえずポインタ完全制覇の本を読んで、シンタックスシュガーという概念を理解できました。ただ、ポインタのポインタの使い所がうまくつかめないので、業務で使わないと身につかなさそうですな。
一応ポインタや関数へのポインタの宣言方法まではなんとかできましたが、そこからまた壁になってるかもしれません。
ポインタ演算から[]への云々は、組み込みじゃない限り今のコンパイラだと最適化されるので、実行速度は変わらんから人間様にわかりやすく書こうぜ、と苦Cに書いてありましたね。
37 ななしのよっしん
2020/07/24(金) 11:08:36 ID: Wkdi5Ha6HN
例えばリンクリストみたいなデータとデータがつながったデータ構造を構築する場合、リンクリスト全体を保持したい時はだいたいが先頭要素へのポインタを保持する感じになるんだ
例えば連絡網というリストがあったとしたら連絡網の最初の人へのポインタとして持ち回す
この場合「連絡網」を引数に受け取る関数は「連絡先へのポインタ」型変数「連絡網」を受け取る事になる
で、リストそのものが複数あって同じ型の場合はまとめて配列で持つ事がある
例えば定時連絡の連絡先リストと緊急障害の連絡先リストが同じ構造体「連絡先」型だったとしたら、その二つを「連絡先へのポインタ」のサイズ2の配列に持って、その配列を「連絡網全体」と呼んだりする
この場合「連絡網全体」の実体は「連絡先」型へのポインタ2個からなるサイズ2の配列となるわけだが、関数に渡すと配列はポインタに化けるので「連絡先へのポインタへのポインタ」として渡される事になる
大体こんな感じで、まず配列ができて配列が関数渡しでポインタに化けて…という流れでポインタへのポインタが多重参照されていく訳だ
まあこの例の場合は「連絡網全体」を構造体にしろよって話だが
38 ななしのよっしん
2020/07/27(月) 20:40:54 ID: c/XWukpYXi
ダブルポインタの使い所は極論すれば2つぐらいかなぁ。
一つは不特定複数のデータを関数に渡したい時。mainの引数はこれね。一つ一つの文字列がそれぞれ別のアドレスにあって、それらを配列に並べてワンセットで総数と一緒に渡すことで、引数がいくつでもそれぞれがどこにあっても対応できるようにしてる。
もう一つは別の関数でアドレスそのものを操作したい時。
Cの関数は値呼びだから引数に渡るのは数値のコピーで、ポインタで渡さないと値の変更が呼び出し元に反映されないというのは入門書に出てくると思うけど、例えば何かのデータをmallocしたいんだけど返り値をエラーステータスに使いたいんでデータは引数経由で返さなければならないなんてことがある。
そういう場合にアドレスを書き込むためのアドレスというのが必要になってくる。
39 ななしのよっしん
2020/08/19(水) 11:18:02 ID: rlCOTjOrcY
ポインタ
概念の理解より構文や人間が管理するのが大変とかの方が厄介な気がする
40 ななしのよっしん
2021/07/03(土) 10:38:57 ID: XsMfXtBySP
「ポインタという概念を理解する」というのはそもそも正確じゃないのよね。
「メモリという概念と、その一部としてのポインタを理解する」というのが正しい。
Cで一般的にメモリと通称されているのはパソコンに刺さってるやつそのものじゃなく、OSとCPUと言語の仕様がしっちゃかめっちゃかに混ざった「メモリ」というプログラム概念だから。
41 ななしのよっしん
2023/02/20(月) 01:48:52 ID: bCMifE42R/
まさに記事にも書いてあることだけど、
文字列、配列、動的メモリ確保、関数の引数みたいな、ポインタが重要な存在の事柄が多いがゆえに
学ぼうとしたら一気に知識がなだれ込んでくるんだよな
42 ななしのよっしん
2025/03/12(水) 17:18:35 ID: wIv8gWIWxx
int *ptr;
この変数名は*ptr そんな風に考えていた時期が俺にもありました
ほめた!
ほめるを取消しました。
ほめるに失敗しました。
ほめるの取消しに失敗しました。