ユーザ「電装工芸」の投稿[864件](40ページ目)
2023年1月 この範囲を時系列順で読む(電装工芸の投稿に限定) この範囲をファイルに出力する
ここ数日は本業で手一杯でした。ライトアップの施工があったのですが、建物の窓を光らせたいとのことで専用の行燈を製作してました。
簡単な作りではあったのですが思った以上に時間がかかり、徹夜して間に合わせたのはいいですが、その余波で心身共にキツイここ数日。
8月のお盆明けからの大連チャンでしたが、この後3月中旬までは緩い日程なので、各種製作や開発を進めて行けそうです。
同時にイロイロ進めますが、とにかくArt-Netエンジンを完成させたい。
Art-Netエンジンとは、Art-Netを受信し、Merge、In-Delay、Patch、Out-Curve、Out-Delayを施し、Art-Netとして送信するデバイスドライバの様なモジュールです。ユーザーインターフェースなどは別途製作ですが、これが完成すれば求めることの半分は完成です。
そのためにC言語を学習しているワケですが、ポインタ、構造体、共有メモリ、マルチプロセスの基本が見えてきましたので、これからしばらくはArt-Netの要であるscoketを試そうと思います。C言語でscoketを扱う情報は高位者による高位者向けの高度な物ばかりですが、幸いPythonでの前例がありますので、これをC言語に置き換える方向で読み解いていこうと思います。
学習を進めれば進める程「ライブラリの使い方はmanとヘッダーファイルを読めば分かるだろ!」という圧を強く感じますが、この感覚が自分にとっても当たり前になるように精進したいものです。
#C言語 #本業 #[Art-Net]
簡単な作りではあったのですが思った以上に時間がかかり、徹夜して間に合わせたのはいいですが、その余波で心身共にキツイここ数日。
8月のお盆明けからの大連チャンでしたが、この後3月中旬までは緩い日程なので、各種製作や開発を進めて行けそうです。
同時にイロイロ進めますが、とにかくArt-Netエンジンを完成させたい。
Art-Netエンジンとは、Art-Netを受信し、Merge、In-Delay、Patch、Out-Curve、Out-Delayを施し、Art-Netとして送信するデバイスドライバの様なモジュールです。ユーザーインターフェースなどは別途製作ですが、これが完成すれば求めることの半分は完成です。
そのためにC言語を学習しているワケですが、ポインタ、構造体、共有メモリ、マルチプロセスの基本が見えてきましたので、これからしばらくはArt-Netの要であるscoketを試そうと思います。C言語でscoketを扱う情報は高位者による高位者向けの高度な物ばかりですが、幸いPythonでの前例がありますので、これをC言語に置き換える方向で読み解いていこうと思います。
学習を進めれば進める程「ライブラリの使い方はmanとヘッダーファイルを読めば分かるだろ!」という圧を強く感じますが、この感覚が自分にとっても当たり前になるように精進したいものです。
#C言語 #本業 #[Art-Net]
C言語の教科書を幾つか読んでいます。
熟知した人でないと書けないことですが、熟知した人は初心者の気持ちを忘れた人たちです。どんなに優しく書こうとしても初心者向けの説明など書けません。部分的に初心者の理解を助けてくれる文章があるので複数読んだ方がいいのです。
お勧めというか、理解しやすかった教科書を2つご紹介します。
「新・明解C言語 入門編」
初心者が挫折しやすい変数の型、ポインタ、構造体を後回しにして書いているのでC言語の全体像が見えやすい。変数の型、ポインタ、構造体で悩みたくないなら他の言語を使うべきですが、冒頭から「変数の型がぁ~」「ポインタがぁ~」と書かれた解説書は挫折率が高い(俺評価)のでよろしくありません。簡単とは言いませんが、これは挫折し難い内容です。
「苦しんで覚えるC言語」
書籍にもなっていますが、webでも読める解説書です。途中息切れを感じるところはありますが、これはこれでわかりやすい。
あと、以前ご紹介した「改訂第3版(5版) ANSI C 対応 はじめてのC」は和文規格書かもしれません。わかりやすい記述も多いのですが、誰もが悩むポインタは触るだけだったりと、誰もが躓くところほど流している傾向があります。すでに習得している人の参考書としてなら悪くありませんケド。
ただ、総じて言えることですが、C言語はこの時代に初めてプログラムを書く人が使う言語ではありません。画面とキーボード、マウスで完結するシステムならPythonなどの高度にマネージされた言語を使うべきです。なぜなら、CPUのレジスタとかフラグ、メモリの概念が体に染み込んでいないと書式の意味を理解することが難しいからです。私の課題は対象がハードウェアですからPythonよりもC言語の方が適切ってだけです。
#C言語
熟知した人でないと書けないことですが、熟知した人は初心者の気持ちを忘れた人たちです。どんなに優しく書こうとしても初心者向けの説明など書けません。部分的に初心者の理解を助けてくれる文章があるので複数読んだ方がいいのです。
お勧めというか、理解しやすかった教科書を2つご紹介します。
「新・明解C言語 入門編」
初心者が挫折しやすい変数の型、ポインタ、構造体を後回しにして書いているのでC言語の全体像が見えやすい。変数の型、ポインタ、構造体で悩みたくないなら他の言語を使うべきですが、冒頭から「変数の型がぁ~」「ポインタがぁ~」と書かれた解説書は挫折率が高い(俺評価)のでよろしくありません。簡単とは言いませんが、これは挫折し難い内容です。
「苦しんで覚えるC言語」
書籍にもなっていますが、webでも読める解説書です。途中息切れを感じるところはありますが、これはこれでわかりやすい。
あと、以前ご紹介した「改訂第3版(5版) ANSI C 対応 はじめてのC」は和文規格書かもしれません。わかりやすい記述も多いのですが、誰もが悩むポインタは触るだけだったりと、誰もが躓くところほど流している傾向があります。すでに習得している人の参考書としてなら悪くありませんケド。
ただ、総じて言えることですが、C言語はこの時代に初めてプログラムを書く人が使う言語ではありません。画面とキーボード、マウスで完結するシステムならPythonなどの高度にマネージされた言語を使うべきです。なぜなら、CPUのレジスタとかフラグ、メモリの概念が体に染み込んでいないと書式の意味を理解することが難しいからです。私の課題は対象がハードウェアですからPythonよりもC言語の方が適切ってだけです。
#C言語
ランチャーに行く前にscoketの基本動作の確認かな?
受信したArt-Netパケットをそのまま送信する実験。
これが求める機能の基本ですから確認せんといかん。
#[Art-Net] #C言語
受信したArt-Netパケットをそのまま送信する実験。
これが求める機能の基本ですから確認せんといかん。
#[Art-Net] #C言語
共有メモリの衝突回避ですが、共有メモリの中にハンドシェイク表すフラグを入れたらそれでいいんじゃないかと。
そのフラグが立っていれば極々わずかな時間sleepを繰り返す処理です。
while(flag1 == 1)
{
sleep(0.001);
}
flag2 = 1;
/* 共有メモリ処理 */
flag2 = 0;
みたいなものです。
別プロセスがフラグを0にすればwhileを抜けます。
簡易的なモノですが、フラグを書き換えられるプロセスを一つにしておけばイイんじゃないかと。最も簡単なセマフォはこういうことですし。
子プロセスの停止制御も同様の考え方が使えます。
動作し続けるってことは繰り返し処理です。単なる繰り返しはwhile(1)とかで無限ループすることが多いので、while(flag==1)とかにすればいい。共有メモリ上のフラグが1ならwhileでループし0になったら抜ければいいのです。抜けたら終了処理をしてプロセスを落とすと。子プロセスが完全に終わったことはスタックしておいたプロセスIDを見ればわかります。
この辺りまで決まれば次はランチャーです。
#C言語
そのフラグが立っていれば極々わずかな時間sleepを繰り返す処理です。
while(flag1 == 1)
{
sleep(0.001);
}
flag2 = 1;
/* 共有メモリ処理 */
flag2 = 0;
みたいなものです。
別プロセスがフラグを0にすればwhileを抜けます。
簡易的なモノですが、フラグを書き換えられるプロセスを一つにしておけばイイんじゃないかと。最も簡単なセマフォはこういうことですし。
子プロセスの停止制御も同様の考え方が使えます。
動作し続けるってことは繰り返し処理です。単なる繰り返しはwhile(1)とかで無限ループすることが多いので、while(flag==1)とかにすればいい。共有メモリ上のフラグが1ならwhileでループし0になったら抜ければいいのです。抜けたら終了処理をしてプロセスを落とすと。子プロセスが完全に終わったことはスタックしておいたプロセスIDを見ればわかります。
この辺りまで決まれば次はランチャーです。
#C言語
共有メモリに構造体を配置してみましたが、割と簡単でした。
構造体のタグ(ひな形)をヘッダーファイルに作り、親プロセスと子プロセスにinclude。共有メモリのサイズは構造体のタグから得て設定。共有メモリ上に置く変数を独立したポインタにするとオフセットをそれぞれ計算して与えないといけませんが、構造体なら一括設定出来て便利です。
構造体をポインタにすると表記が独特になりますが、意味合いが明示的となって読みやすいかもしれません。
この辺りには、本文中に出来るだけ定数を直書きしないという方針にも繋がってきます。
次は共有メモリの衝突回避を調べないといけません。
#C言語
構造体のタグ(ひな形)をヘッダーファイルに作り、親プロセスと子プロセスにinclude。共有メモリのサイズは構造体のタグから得て設定。共有メモリ上に置く変数を独立したポインタにするとオフセットをそれぞれ計算して与えないといけませんが、構造体なら一括設定出来て便利です。
構造体をポインタにすると表記が独特になりますが、意味合いが明示的となって読みやすいかもしれません。
この辺りには、本文中に出来るだけ定数を直書きしないという方針にも繋がってきます。
次は共有メモリの衝突回避を調べないといけません。
#C言語
屋外で開催される成人式関連のイベントで電源出しです。
起動してしまえばやることはありません。
本日の課題は共有メモリのテストです。
次のページにあるソースをそのまま使って挙動を確認です。
プロセス間でのメモリ共有
親プロセス「ShareMemTest1」を起動した後、待機時間(20秒)のうちにコンソールで「ShareMemTest2」に共有メモリのIDを与えて起動するというもの。一貫したプログラムではありませんが、やりたいことはプロセス間でのメモリ共有ですからむしろわかりやすい。
ちなみに、コンソールでプログラムを起動する際、末尾に「&」を付けると新規プロセスで実行します。
ここサンプルを使うなら、
<親プロセスを起動>
$ ./ShareMemTest1 &
<起動後表示>
nShareMemID = 23 /* IDは都度変わります */
process1 : nVar1 = 1, nVar2 = 2
・・・ここで20秒Sleepしてます・・・
<子プロセスを起動>
$ ./ShareMemTest2 23 &
<起動後表示>
nShareMemID = 23
process2 : nVar1 = 1, nVar2 = 2
process2 : nVar1 = 2, nVar2 = 2
・・・子プロセスはここで終了・・・
・・・20秒後、親プロセスが再開・・・
process2 : nVar1 = 2, nVar2 = 2
・・・親プロセスも終了・・・
となります。
正に記述にある通り。
$ ipcs -m
や
$ free
を用いるとSharedメモリの状況がわかります。
実際のテストではgetpid()を用いてプロセスIDも表示しながら確認しましたが、確かに別プロセスでした。
共有メモリの容量は、無意味に8MBくらい設定してみましたが何の問題も無し。
親側の設定は、typedefで構造体を定義し、構造体のポインタ変数を作り、構造体のメモリサイズ(sizeof()で取得)をもとに共有メモリを作り、構造体のポインタ変数に共有メモリを割り当てる、といった流れでしょうか。
子側は、typedefで構造体を定義し、構造体のポインタ変数を作り、親から取得したIDから構造体のポインタ変数に共有メモリを割り当てる、といった流れ?
共有メモリ上に変数(構造体)を構築した後は共有メモリを意識する必要は無いと思います。もちろん、衝突回避は常に考えないといけませんけど。
勘違いしていた点ですが、共有メモリのIDは管理用の通し番号であってポインタに設定するアドレスではないことです。C言語では何かにつけてポインタ渡しなのでこれもそうかと思ってしまいました。
共有メモリに構造体を配置することが次の課題ですが、構造体についてもう少し勉強してからです。
#C言語
起動してしまえばやることはありません。
本日の課題は共有メモリのテストです。
次のページにあるソースをそのまま使って挙動を確認です。
プロセス間でのメモリ共有
親プロセス「ShareMemTest1」を起動した後、待機時間(20秒)のうちにコンソールで「ShareMemTest2」に共有メモリのIDを与えて起動するというもの。一貫したプログラムではありませんが、やりたいことはプロセス間でのメモリ共有ですからむしろわかりやすい。
ちなみに、コンソールでプログラムを起動する際、末尾に「&」を付けると新規プロセスで実行します。
ここサンプルを使うなら、
<親プロセスを起動>
$ ./ShareMemTest1 &
<起動後表示>
nShareMemID = 23 /* IDは都度変わります */
process1 : nVar1 = 1, nVar2 = 2
・・・ここで20秒Sleepしてます・・・
<子プロセスを起動>
$ ./ShareMemTest2 23 &
<起動後表示>
nShareMemID = 23
process2 : nVar1 = 1, nVar2 = 2
process2 : nVar1 = 2, nVar2 = 2
・・・子プロセスはここで終了・・・
・・・20秒後、親プロセスが再開・・・
process2 : nVar1 = 2, nVar2 = 2
・・・親プロセスも終了・・・
となります。
正に記述にある通り。
$ ipcs -m
や
$ free
を用いるとSharedメモリの状況がわかります。
実際のテストではgetpid()を用いてプロセスIDも表示しながら確認しましたが、確かに別プロセスでした。
共有メモリの容量は、無意味に8MBくらい設定してみましたが何の問題も無し。
親側の設定は、typedefで構造体を定義し、構造体のポインタ変数を作り、構造体のメモリサイズ(sizeof()で取得)をもとに共有メモリを作り、構造体のポインタ変数に共有メモリを割り当てる、といった流れでしょうか。
子側は、typedefで構造体を定義し、構造体のポインタ変数を作り、親から取得したIDから構造体のポインタ変数に共有メモリを割り当てる、といった流れ?
共有メモリ上に変数(構造体)を構築した後は共有メモリを意識する必要は無いと思います。もちろん、衝突回避は常に考えないといけませんけど。
勘違いしていた点ですが、共有メモリのIDは管理用の通し番号であってポインタに設定するアドレスではないことです。C言語では何かにつけてポインタ渡しなのでこれもそうかと思ってしまいました。
共有メモリに構造体を配置することが次の課題ですが、構造体についてもう少し勉強してからです。
#C言語
C言語の基本的な書き方は整理がついてきました。
次はライブラリの理解と使い方となるのですが、ネットで検索しても情報があるっちゃあるけどイマイチ感。
基本に立ち戻れば、ライブラリのman(公式のマニュアルファイル)とヘッダーファイルを読めとなります。以前からそうするのが王道とは思ってはいましたが、何が書いてあるのかサッパリでした。
それが少しわかるようになってきました。我ながら大進歩。
manはLinux系のOSなら本体にも必ず入っているものの英文が多いのですが、ネットで検索すると日本語版がすぐに見つかるのでこちらを読んだ方がいいかも。
かといってman読めばいいかと言えばそうでもない。前触れもなく突然出現する用語やパラメータが多い。
ようやくわかったのですが、ライブラリのmanはヘッダーファイルを補足しているに過ぎないらしい。つまり、ライブラリを理解するための主役はmanではなくヘッダーファイルということ。
変数の型定義、構造体の定義、プロトタイプ宣言などが書かれているヘッダーファイルは定義書であり解説書でもありますので、これを読み解けない人がC言語でプログラムを書けるワケないでしょう・・・という熟練者たちのご意見はその通りです。
どこを読むべきか、何を理解するべきかが見えて来ただけでも今日のところはいいんじゃないかと。
早速、socketのライブラリである sys/scoket.h を読んでみようと /usr/include を覗いたのですがありません。
google様に教えてもらい、次のコマンドで在処を検索できました。
$ sudo dpkg --search sys/socket.h
結果は /usr/include/arm-linux-gnueabihf/sys/socket.h とのことでした。
パッと見ではサッパリわかりませんが、半分くらいはわかるので、全体を理解出来る様に頑張ってみましょう。
#C言語
次はライブラリの理解と使い方となるのですが、ネットで検索しても情報があるっちゃあるけどイマイチ感。
基本に立ち戻れば、ライブラリのman(公式のマニュアルファイル)とヘッダーファイルを読めとなります。以前からそうするのが王道とは思ってはいましたが、何が書いてあるのかサッパリでした。
それが少しわかるようになってきました。我ながら大進歩。
manはLinux系のOSなら本体にも必ず入っているものの英文が多いのですが、ネットで検索すると日本語版がすぐに見つかるのでこちらを読んだ方がいいかも。
かといってman読めばいいかと言えばそうでもない。前触れもなく突然出現する用語やパラメータが多い。
ようやくわかったのですが、ライブラリのmanはヘッダーファイルを補足しているに過ぎないらしい。つまり、ライブラリを理解するための主役はmanではなくヘッダーファイルということ。
変数の型定義、構造体の定義、プロトタイプ宣言などが書かれているヘッダーファイルは定義書であり解説書でもありますので、これを読み解けない人がC言語でプログラムを書けるワケないでしょう・・・という熟練者たちのご意見はその通りです。
どこを読むべきか、何を理解するべきかが見えて来ただけでも今日のところはいいんじゃないかと。
早速、socketのライブラリである sys/scoket.h を読んでみようと /usr/include を覗いたのですがありません。
google様に教えてもらい、次のコマンドで在処を検索できました。
$ sudo dpkg --search sys/socket.h
結果は /usr/include/arm-linux-gnueabihf/sys/socket.h とのことでした。
パッと見ではサッパリわかりませんが、半分くらいはわかるので、全体を理解出来る様に頑張ってみましょう。
#C言語
現場が早く終わったので、開発用のRaspberryPiをノートパソコンのVSCodeと繋いでおきました。ここまでしておけば比較的身軽に開発が出来ます。
本格的に開発を進めましょう。
C言語でのsocketについて調べてみましたが、PythonのscoketライブラリはC言語のsocketをほぼそのまま橋渡ししているだけみたいです。引数の書式にわずかな違いはありますが、ほぼ同様に使えそうです。Art-Netを受信してそのまま転送する処理から試しましょう。
#C言語 #[Art-Net]
本格的に開発を進めましょう。
C言語でのsocketについて調べてみましたが、PythonのscoketライブラリはC言語のsocketをほぼそのまま橋渡ししているだけみたいです。引数の書式にわずかな違いはありますが、ほぼ同様に使えそうです。Art-Netを受信してそのまま転送する処理から試しましょう。
#C言語 #[Art-Net]
C言語はプロセスの管理方法を調査中です。
直近の課題はAr-Netパッチです。この機構は大きく分けて、(1)Art-Netエンジン(受信、パッチ、送信)、(2)DMXの状況モニタ表示、(3)ユーザーからのコマンド操作となります。
C言語で書けば主な機能をスレッドに分ければいいような気もしますが、スレッドを分けるのもプロセスを分けるのも手間は大差ないので、プロセスを分けておけばいいかなと。
先日も書きましたが、ランチャー的な親プロセスから各機能を子プロセスとして起動しようと思っています。これなら親プロセスで共有メモリを定義して子プロセスにポインタを渡すことが簡単だからです。また、子プロセスとして起動するなら親プロセスがプロセスIDを確実に把握出来ますので管理上のメリットもあります。
まだわからない調査中のことは、子プロセスの終了のさせ方です。killコマンドでプロセスを消す方法はありますが、後処理(設定の現在値の保存など)をしてから子プロセスを終了したいので、有無言わさずプロセスを消すkillコマンドはよろしくありません。望ましいのは、親プロセスからコマンドを送って子プロセス自身で終了させることです。Python的に考えるなら、親プロセスからの指示で子プロセスに何かしらの例外が発生してwhileをbreakで抜け出すような処理です。共有メモリでコマンドをやり取りするのが現実的だと思いますが、出来るだけシンプルで汎用的な方法を構築したいところです。
いずれにしても、親プロセスから子プロセスを起動し、プロセス間で通信(変数の共有)をし、親プロセスから子プロセスを終了させる方法の定型化です。
もう少し学習が進んでからになりますが、共有メモリの挙動も調査しないといけません。
共有メモリは複数のプロセスから読み書きできるメモリ空間ですが、マネジメントされていませんので衝突(読み書きの処理タイミングが被ること)による不整合が起きる可能性があります。これを回避する手段としてセマフォなどの機能があるのですが、出来るだけシンプルな方法を見つけたいと思っています。
調査したいのは、共有メモリに書き込み出来るプロセスを唯一とし、他のプロセスは読み出しのみとした場合にどうかという点です。機能的に共有メモリの読み書きは頻繁に行われますので出来るだけ手数を少なくしたいのですが、結果的に書き込みのタイミングをマネジメントしなくていいなら手数は最小だし、何かが必要だとしてもどこまでやるのかを知りたいワケです。
#C言語
直近の課題はAr-Netパッチです。この機構は大きく分けて、(1)Art-Netエンジン(受信、パッチ、送信)、(2)DMXの状況モニタ表示、(3)ユーザーからのコマンド操作となります。
C言語で書けば主な機能をスレッドに分ければいいような気もしますが、スレッドを分けるのもプロセスを分けるのも手間は大差ないので、プロセスを分けておけばいいかなと。
先日も書きましたが、ランチャー的な親プロセスから各機能を子プロセスとして起動しようと思っています。これなら親プロセスで共有メモリを定義して子プロセスにポインタを渡すことが簡単だからです。また、子プロセスとして起動するなら親プロセスがプロセスIDを確実に把握出来ますので管理上のメリットもあります。
まだわからない調査中のことは、子プロセスの終了のさせ方です。killコマンドでプロセスを消す方法はありますが、後処理(設定の現在値の保存など)をしてから子プロセスを終了したいので、有無言わさずプロセスを消すkillコマンドはよろしくありません。望ましいのは、親プロセスからコマンドを送って子プロセス自身で終了させることです。Python的に考えるなら、親プロセスからの指示で子プロセスに何かしらの例外が発生してwhileをbreakで抜け出すような処理です。共有メモリでコマンドをやり取りするのが現実的だと思いますが、出来るだけシンプルで汎用的な方法を構築したいところです。
いずれにしても、親プロセスから子プロセスを起動し、プロセス間で通信(変数の共有)をし、親プロセスから子プロセスを終了させる方法の定型化です。
もう少し学習が進んでからになりますが、共有メモリの挙動も調査しないといけません。
共有メモリは複数のプロセスから読み書きできるメモリ空間ですが、マネジメントされていませんので衝突(読み書きの処理タイミングが被ること)による不整合が起きる可能性があります。これを回避する手段としてセマフォなどの機能があるのですが、出来るだけシンプルな方法を見つけたいと思っています。
調査したいのは、共有メモリに書き込み出来るプロセスを唯一とし、他のプロセスは読み出しのみとした場合にどうかという点です。機能的に共有メモリの読み書きは頻繁に行われますので出来るだけ手数を少なくしたいのですが、結果的に書き込みのタイミングをマネジメントしなくていいなら手数は最小だし、何かが必要だとしてもどこまでやるのかを知りたいワケです。
#C言語
VSCodeのSSH環境作りは予想外に簡単でした。
自宅でファイルサーバーになっているRaspberryPiに接続してC言語の実習をしております。
まずは基本であり多用するであろうポインタによる関数の呼び出し方です。ポインタはその昔挫折した要素でありますが、どうも勘違いのままアタマに刷り込まれてしまったようで、わかっているつもりなのに間違った組み立てが浮かんできます。これは正しい組み方を刷り込み直すしかありませんので、自分なりの課題で実験を繰り返すしかありません。
つい先ほど整理出来たのですが、ポインタ変数は定義した直後はnull値であって特定のアドレスは持っていません。int *num では実体の変数は定義されないということがわかったのですが、正にこういった点がその昔の勘違いなんですよね。「ポインタは実体変数の扱いを補助するための機能」という前提がアタマに入ったのでスッキリしました。「実体ではない」ということが明確になっただけでも私の中では大革命です。
あと、インクリメントとデクリメントについてメモ。
C言語では++numと書かないと期待値になりません。雰囲気的にnum++と書いてしまいがちですが、エラーにならんのにインクリメントされんのです。
デクリメントも--numとしないといけません。
計算記号が行頭にあっていいのかって疑問が湧きますが、慣用句として覚えておきましょう。
それにしてもVSCode+SSH+gcc+gdb環境は便利ですねぇ。
コンパイルから実行までの手数や所要時間が画期的に短い。エラーも丁寧に教えてくれるし、メモリがマネージされているからヘタなモノ書いてもシステムが飛ぶこともない。スクリプト言語をチョイチョイ書いているのと大差ありません。
デバッカーのお世話になるレベルになるにはまだまだかかりそうですが、こんなに簡単にC言語が扱えるなんて私の中では画期的過ぎです。25年前と一緒にすんなって話ですけどね。
#C言語
自宅でファイルサーバーになっているRaspberryPiに接続してC言語の実習をしております。
まずは基本であり多用するであろうポインタによる関数の呼び出し方です。ポインタはその昔挫折した要素でありますが、どうも勘違いのままアタマに刷り込まれてしまったようで、わかっているつもりなのに間違った組み立てが浮かんできます。これは正しい組み方を刷り込み直すしかありませんので、自分なりの課題で実験を繰り返すしかありません。
つい先ほど整理出来たのですが、ポインタ変数は定義した直後はnull値であって特定のアドレスは持っていません。int *num では実体の変数は定義されないということがわかったのですが、正にこういった点がその昔の勘違いなんですよね。「ポインタは実体変数の扱いを補助するための機能」という前提がアタマに入ったのでスッキリしました。「実体ではない」ということが明確になっただけでも私の中では大革命です。
あと、インクリメントとデクリメントについてメモ。
C言語では++numと書かないと期待値になりません。雰囲気的にnum++と書いてしまいがちですが、エラーにならんのにインクリメントされんのです。
デクリメントも--numとしないといけません。
計算記号が行頭にあっていいのかって疑問が湧きますが、慣用句として覚えておきましょう。
それにしてもVSCode+SSH+gcc+gdb環境は便利ですねぇ。
コンパイルから実行までの手数や所要時間が画期的に短い。エラーも丁寧に教えてくれるし、メモリがマネージされているからヘタなモノ書いてもシステムが飛ぶこともない。スクリプト言語をチョイチョイ書いているのと大差ありません。
デバッカーのお世話になるレベルになるにはまだまだかかりそうですが、こんなに簡単にC言語が扱えるなんて私の中では画期的過ぎです。25年前と一緒にすんなって話ですけどね。
#C言語