【C言語】研究 ループカウンタを改変出来なくする

 C言語のfor文では通常 i がカウンターとされます。そのときに i をループ中で改変出来るとバグが多く発生する原因になります。また、カウンタを改変する意図がなくても行ってしまう可能性もあります。 今回はこの解決策について考えてみます。

ループ開始時にconstにする

  1. #include<stdio.h>
  2. main(){
  3.     for(int i=0;i<10;i++){
  4.         const auto x = i;    //ループカウンターを定数として代入
  5.         {
  6.             const int i =0;    //生のループカウンター iにアクセス出来ないようにこれで封印
  7.             printf("%d ",x);
  8.         }
  9.     }
  10.     
  11. }

6行目で const auto x=i; としています。これは i の内容を定数として x に代入しています。変化する値なのに定数というのは変ですが、ここでの意味は 変化する値 i を使いこれ以降のxを定数とすることです。

これにより x の値は変更できません。 x++ などの変更するコードを記述するとコンパイルエラーが出るのでループカウンターの値を変更するバグを防げます。

更に i も改変不可にする

これでも、直接 i を変更可能です。 今回はこれを防ぐために、ブロックを一つ追加しています。 7と10行目の括弧囲んだ部分が追加したブロックです

このブロックの中の 8 行目で const int i = 0; としています。これによりループ変数としての i にアクセスできなくなります。 さらに i++ など変更を加えようとするとエラーが出ます。 難点としては i を参照すると この場合は0が取得できるところです。

仕様として error 型でも作って 参照したら即エラーになるような型でもあれば良いのですけど。

【C言語】プログラミング言語C++ は必読書です

 私が経験した周りだけのことかもしれませんが、IT業界の人ほど新しい物事を基礎的に習っていない傾向にあると考えます。 例えば、プログラミング言語は最初だけ入門し、後からはいわゆる「地頭力」的な力で覚えていると考えます。


地頭力は危険

プログラミングじゃない分野で地頭力は行動指針を決める参考程度にしかならないと言いました。 他人への助言に地頭力は使ってはいけません。 それと同様に新しい言語を習うときに完全な地頭力を使うと大きな失敗をします。

確かに変数の宣言、代入、ループなどは大きく違わないので地頭力でコードを読み続けることが出来ます。 しかし、地頭力による理解では全く新しいコンセプトは理解できないと考えます。

C++とConst

実は私は仕事でC言語やC++を使っていました。今でもどこかで私が書いたサービスが動いているのではないかと考えます。 しかし、最近C++の解説書であるプログラミング言語C++を読んで衝撃を覚えました。

実は新しい言語を古いスタイルで使っていたと言うところです。私はC++を「構造体に関数を書くことが出来る便利な言語」と言う程度でしか考えていませんでした。

知らなかったことの一例をあげると const です。 もちろん、const は定数の宣言であることは知っています。

const float g = 9.8;

って書けば浮動小数点型でgという変数が定数として宣言される。そしてプログラム内部で書き換えようとするとコンパイルエラーとなると言う事は知っていました。

しかし、これはどうでしょうか?

  1.     int x;
  2.     scanf("%d",&x);
  3.     const int y=x;
  4.     
  5.     for(int i=0;i<x;i++) printf("*");

えっ、constなのにプログラム中で変化する数字を代入しているの? って疑問です。

constの真の意味

上記のコードでは2行目で入力した値をxに代入しています。そして、そのxを定数型のyに代入しています。 当然xは入力される値で不定です。だったら、y=x; としているからconst 定数じゃないだろ?

ここではそういう意味ではなく、4行目では変化するxを今から定数にすると言う意味で使っています。

このため、4行以降で y=3; とするとコンパイルエラーになります。

変数の自動宣言

そう言われてみれば auto という宣言が有ったと思いますが、その真意は知らないままだと思います。

  1. #include<stdio.h>
  2. int f(int a){
  3.     return a*a;
  4. }
  5. main(){
  6.     int x;
  7.     
  8.     scanf("%d",&x);
  9.     const auto y=f(x);
  10.     
  11.     printf("%d\n",y);
  12. }

このコードの12行目で const auto y=f(x); としています。 この宣言をすることでyは関数f()の戻り値で型式を宣言されます。

これにより、一箇所のintの定義によりそれに関連する場所全てが int で宣言されます。 また、const により関数f()の戻り値が代入されたyはこの後書き換わることが無いということも明示されています。

余談ですが、このコードを見ると古株から

「変数は関数の開始時に定義するように」

と言われそうです。しかし、C++の解説書では代入間違えをしないという意味で、途中で宣言することに意味があるとしています。

今回のyもmain関数の先頭で宣言するより、途中で明確に const であるとしたほうがわかりやすく意図しない変更防止が出来るとしています。

最後に

ITエンジニアってMicrosoft Office の入門書って読んだことが無いのではと考えます。私もそうでした。ただ、最新のOfficeの入門書を読むと昔とはコンセプトが違うことに気が付きます。 それと同じように、新しい言語も古い言語には無いコンセプトがあります。

もちろん、言語なので昔のコンセプトで組むことも出来ますが、それでは新しい言語を使っても楽は出来ません。 新しいツールには確実に楽に出来る機能が追加されています。

ですので、C言語からC++を覚えた人や、C++はクラスが追加されただけと思っている人は是非入門書や解説書を読んでみて下さい。

プログラミング言語C++
をAmazonで確認する

【防衛術】安全では有りません!とサイトに表示される意味

 ブラウザでウェブを表示するときに「安全ではありません」と表示されることが有りました。皆さん、この意味は分かりますか?

安全では有りません!の勘違い

あるものが「安全では有りません」と言われた場合他のものは「安全」。 これは間違えです。単にあるものが「安全じゃない」というだけです。それ以外については言及していません。

安全じゃないサイトの意味

安全ではないという意味は、そのサイトが誰のものか保証されていないと言う意味です。なので、その表示が無いサイトは「誰のサイトか保証されている」という程度の意味です。

一方で、安全じゃないと表示されていないサイトは単に「誰のサイトか保証されている」というだけです。なので無条件で信用出来るわけでは無いですが、詐欺グループの特定などがしやすいです。そのため、安全じゃないサイトと比べると詐欺に使われる率が低めです。

安全じゃないサイトは見てはいけない?

そんな事は無いです。特に見るだけでは何も問題は有りません。ググった結果「安全じゃないサイト」がヒットした場合でも見て構いません。しかし、安全じゃないサイトのリンクをクリックして、その先で個人情報やクレジットカード情報を入力することは避けて下さい。

http://t.kink.jp/unsafe/ このURLは私が作成した「安全じゃない」と表示されるサイトです。しかし、見るだけなら問題は全く有りません。

いつもの通販サイトに「安全じゃない」と出ている場合

フィッシング詐欺の可能性があります。現在の買い物は中止してブラウザを閉じて下さい。再度、正しいアドレスを入力して買い物をやり直して下さい。

まとめ

  • 安全じゃないサイトを閲覧するだけなら問題ない
  • 安全じゃないサイトの掲示板に匿名で書くことは問題ない
  • 安全じゃないサイトで個人情報や決済情報を入れるのは問題ある
  • いつもの通販サイトに安全じゃないと表示された場合はブラウザを閉じる

です。

Amazonでネットセキュリティについてチェックする


【節約術】固定ネットを入れるべきかの判断

 「固定ネットを使うとWi-Fiでパケ代節約」 自宅の固定ネットの宣伝でよくあります。確かに固定ネットでパケ代は節約出来るのは間違えは有りません。しかし、多くの場合は損していることが多いです。

一人暮らしで出先でも利用する人

「動画投稿とかライブ配信をしまくっている人」という極端な例を除き、一般的な利用方法であればスマホのプランを『ギガモンスター』などにして単体運用したほうが安いです。

  • 固定5000円+携帯6650円(ドコモ、ギガプレミア)
  • 固定5000円+携帯3000円(楽天モバイル最大利用)
  • 固定なし+携帯6650円(ドコモ、ギガプレミア)
  • 固定なし+携帯3000円(楽天モバイル最大利用)

結局、外でパケットを使ってしまうので自宅でWi-Fi節約してもコスト的に意味は有りません。

一人暮らしで自宅にこもる人

リモートワークや個人事業主でほとんど自宅から出ないと言う場合は

  • 固定5000円+携帯1500円(ドコモ、ギガプレミア)
  • 固定5000円+携帯0円(楽天モバイル最小利用)
  • 固定なし+携帯6650円(ドコモ、ギガプレミア)
  • 固定なし+携帯3000円(楽天モバイル最大利用)

と、3大キャリアなら同じ、格安キャリアでも固定回線の利点を活かせません。どちらにしても一人暮らしなら固定回線は不要ではと考えます。

家族の場合

4人家族で全員スマホを持っている場合を考えます。煩雑になるので固定回線と楽天モバイルで考えてみます。

  • 固定なし 携帯12000円(楽天モバイル最大利用) 
  • 全員が出先利用 固定5000円+携帯12000円(楽天M最大利用)
  • 一人が自宅利用 固定5000円+携帯9000円
  • 二人が自宅利用 固定5000円+携帯6000円
  • 三人が自宅利用 固定5000円+携帯3000円
  • 四人が自宅利用 固定5000円+携帯0円

と自宅利用が3人以上なら固定ネットの導入がお得です。

家電がネットに接続されている

家電がネットに接続されているから固定ネットが必要? 体重計やロボット掃除機、スマートリモコンの利用であればIoTプランを考えて下さい。IoTとは「モノのインターネット」という意味で、スマートスピーカーやリモコン、ロボット掃除機など小容量のパケットを低速で接続するプランです。このプランであればロケットモバイルの神プランなど月額数百円もの物があります。

テレビはテザリングする

IoTプランは低速なのでネットフリックスやフールーなどの動画を見ることは出来ません。その場合はそれぞれの見る人がスマホをテザリングして下さい。

四人家族で自宅利用が3人以上なら固定ネット

結構、衝撃的です。4人家族で3人も家にこもっている家庭は少ないと思います。ということは、多くの家庭では光ネットなどの固定ネットは不要なのではと考えます。

一ヶ月5000円。それを20年間5%の複利で積み立てたとすると。

2,055,168円

です。金融庁のサイトで計算できます。二十年間で200万円近い貯蓄が出来ます。これは非常に大きいですので考えてみて下さい。

毎月5000円を20年間5%の複利で積立運用した場合

  • 一人暮らしの場合は固定回線は損
  • 四人家族で二人以上は出先の人は固定回線不要
  • テレビは見る人の端末でテザリングする
  • スマート家電は月々数百円のIoTプランを考える

【嘘】収納できるからノートパソコンを選ぶ

 自宅でパソコンを買う人の多くは「ノートパソコン」を選んでいます。理由の一つとして「使わないときに収納できる」です。しかし、私が見た感じ衝撃的な事実があります。

ノートパソコンを収納する人などいない

アンケートとか査読論文の類じゃないのですが、私が見たところほぼ全ての家庭ではノートパソコンは机に上に出しっぱなしです。あと、開きっぱなしでキーボードにはカバーするための布がかぶさっている家もありました。

企業でもノートパソコンの活用が多いですが、多くの会社は出しっぱなしです。

結局デスクトップで良くないか?

ノートパソコンって同一性能のデスクトップパソコンより高価です。更にゲーミングや高性能なノートほど割高にです。ノートを買っても机に出しっぱなしであればデスクトップPCで良いのではと考えます。

デスクだってスッキリできる

ディスプレイを固定し、配線を隠匿すればデスクトップPCもスッキリさせられます。本体はデスクの下に置いたり、近くにクローゼットがあればその中に入れてしまうことも出来ます。キーボードやマウスはワイヤレスで接続すればスッキリです。

壁に設置するとスッキリ

机の上に置くのではなく壁にモニターを設置し、本体をクローゼットや棚に入れることで更にスッキリさせることが出来ます。机は移動式にして、パソコン作業をするときはディスプレイの前に移動させて下さい。

パソコンを使わないときは机を部屋の中央に持っていけば食事や読書などがしやすい環境を作ることが出来ます。

リビングのテレビ裏

パソコンは必要だが、時々しか使わない人は、リビングのテレビに接続することをおすすめします。 パソコンはテレビの裏やテレビ台の中に入れて下さい。キーボードとマウスはワイヤレスです。これなら、常にパソコンが見えていないので更にスッキリです。

ディスプレイはテレビと兼用しているので新たに買う必要もなく経済的です。

結論、持ち運ばないのならノート不要

単にスッキリとさせたいだけなら、ノートパソコンにこだわる必要はありません。ただ、いろいろな部屋でパソコンを使いたいとか、出先で作業することが多い人はノートが必須です。

パソコンを一箇所でしか使わない場合はノートではなくデスクトップをスッキリと設置することをおすすめします。

AmazonでデスクトップPCを探す

【嘘】裏紙利用は失うものが多い

 一時期、コストダウンや環境に優しいという理由で、コピー機やプリンタでの裏紙利用が推奨されたことが有りました。その後、熱は冷めましたがこの間違った考え方が一部では残っています。


裏紙や両面は高く付く

結論を言ってしまいましたが、裏紙利用や両面印字で節約できるのは紙代です。Amazonで確認してみたら一箱2080円でした。枚数は2500枚なので割り算すると一枚あたりの価格が0.832円です。

極端なプリントボリュームで考えて、一日一箱を消費する組織で考えると、

12ヶ月×20日×2080円=49万円

なので、裏紙を使った場合約24万円の節約が可能です。ただ、年間24万円の節約は大きいだろと考えるのは間違えです。

まず、裏紙とは一度使われた用紙です。そのため、色々なゴミが付着しています。消しゴムカス、埃などです。それらを再びプリンタやコピー機に入れるので故障の原因になります。

更に、クリップや付箋紙などの異物の混入も考えられます。また、紙の種類によってはプリンタを一撃で破壊する物があります。インクジェットの発色が良くなる「スーパーファイン用紙」と呼ばれる紙をレーザプリンタに入れると一発で故障です。

ドラムユニットとかドラムセットと呼ばれる非常に高い部品を全て交換する必要があります。

年に二回誰かが間違えを起こした場合

ドラムユニットのスポット修理の費用をググってみたら20万円とのことです。それが二回と考えると40万円。 一日に2500枚プリントするハイボリュームな例でも割に合いません。

だから、これだけでも裏紙利用は止めたほうが良いと考えることが出来ます。

他にも悪いこと

印字ミスして白紙のままコピー機から紙が出てきたときも、もったいないと思って戻す人がいます。良いことより悪い事のほうが多いのでその紙は捨てて下さい。一度プリンタから出てきた紙は曲がっていたり、触ったことで汚れが付いています。

あと、古紙として捨てればリサイクルされるので罪悪は無いと考えます。

家のプリンタでも

同じです。裏紙や汚れた紙を入れると故障の原因になります。だから、失敗してまだ、空白が多い紙も再利用は考えずに捨てて下さい。あと、家庭用のプリンタの場合は壊れた場合は修理が出来ずに破棄の可能性があります。

保証期間内でも中からクリップや付箋紙などの異物が発見された場合は無料保証はされないと考えて下さい。

Amazonでコピー用紙を確認してみる

【過剰】セキュリティが甘いデバイスは使用厳禁なのか?

 工場の生産ラインでよく使われるPLCというコンピュータがあります。一昔前だと「シーケンサ」と呼ばれていましたが、今ではあまり聞かないです。そのPLCにもEthernet端子つまりLAN端子が搭載され遠隔から制御したり、PLC同士が通信して連携しています。

非常に便利にはなったのだが、あるときにPLCがインターネット側から攻撃されたと言う話があります。 ただ、報道の論点はPLCにセキュリティ概念が無かったので悪いという部分になっています。

これに関して私の見解を書きます。


悪いのは現場でのネットアクセス

かつては会社のLANはインターネットに接続されていませんでした。社内の文書のシェア、ローカルメール、印字などとともに生産ラインのPLCが接続されていました。ただ、PLCの接続にはセキュリティなど無く、設定すれば誰でもアクセス出来る状態にありました。

ただ、社内LANなど皆さんは仕事で使っているだけで、それ以外の用途では使われることは有りませんでした。

しかし、インターネットが普及したときに取った手は、社内のLANにインターネットのトラフィックを流すと言う事をはじめました。 まあ、既存のLANもあるし通信方式も同じだから使わない手は無いと考えたのでしょう。

最初は社員が喜ぶ程度の娯楽を提供していた程度だが、外部の悪者が社内の情報を盗んだり破壊するための経路としても使われるようになりました。

ざっくり社内のPLCなどが攻撃される方法としては

  1. 誰かが悪意ある実行ファイルをダウンロードする。またはメール送付される
  2. 実行してLAN内部のコンピュータが荒らされる。
  3. PLCと通信し、誤動作する情報を設定される。機械が暴走したり、液体が溢れたりする。PLCじゃないがプリンタの紙が無くなるまでジョブを入れることなども出来る

こんな流れでPLCが攻撃されます。

そもそもの悪は無意味なネットアクセス

冷静に考えれば、社内にパソコンやLANがあるからとネットアクセスが出来る状態にする必要は有りませんでした。しかも、業務上理由は有りません。

さらに、会社が社内資源を使って社員に娯楽を提供したことってインターネットアクセスが初めてだったのでは無いでしょうか? ラジオやテレビは一部の事業所では勤務時間中に楽しむことが出来たと言われているが、インターネットアクセスはパソコンが仕事場に有る職場では全て出来るようになったのではと考えます。

再びPLCは悪くない

悪いのはセキュリティが低いPLCでは無く、無意味なインターネットアクセスです。なので、必要の無いLANにはインターネットへの接続を行わないという方針を立てるべきでした。

製品としてセキュリティが甘い機器を業務で使っている場合は、そのLANにインターネットなどの外部アクセスを許すのが悪です。 あと、社内のセキュリティって

「部外者が入ることが出来ない上で成り立っている」

と考えられます。施錠しないロッカー、自由に使えるコピー機、ログイン不要の端末、トイレ……これらは単体のセキュリティで守られているのではなく、敷地に入る守衛によって守られています。

なので、PLCも自分自身でガードするのではなく、守衛に相当するもので守られるべきです。

なので、悪いのは

「インターネットという部外者を入れてしまった」

ということです。セキュリティが甘いデバイスは適切にガードして運用すればよいだけです。

余談、クルマのCAN通信悪用

最近のクルマにはCANと言う通信が入っています。昔は多くのハーネスでウインカーやスイッチ、ヘッドライト、エンジンなどが接続されていました。それが、パソコンで言うとLANに相当するCANと言うネットワークで接続されています。

そのCANを悪用して外部からロックを解除しエンジンを始動して走り去ることが出来てしまいます。方法はバカバカしく簡単で

  1. ウインカーなど一番外側のCAN通信の配線を取り出す
  2. そこにコンピュータを割り込ませる
  3. 解錠信号を送ると、ロックアクチュエーターが動作し、ドアが開く。
  4. エンジン始動信号を流すとエンジンが始動

って流れです。私はまさかと思いましたが、ウインカーやライトなど外部とエンジンコントロールやセキュリティに係る内部のバスと分けられていなかったということです。

先程の社内LANとインターネットと同様だと考えます。

これは絶対に無いと思うのだが、航空機のエンタテインメントシステムとエンジンコントロールは同じバスにぶら下がっているのだろうか? こんなありえないことをクルマのバスや社内LANにインターネットアクセスに対しては行っていたということです。怖いです。

CAN通信についてAmazonで見る

【詐欺】未だにサイト量産システムとか情報商材がある

 ネットで楽して稼ぐことが出来る! と広告が時々入ります。「独自のプログラム」でコンテンツを量産し不労所得みたいなものです。まあ、冷静に考えれば売っている本人が使えよ! ということになることで詐欺だと分かります。

仮に私が、仕掛けておくだけで不労所得を得るサイトシステムを持っていたら人に営業せずに自分で使います。もっと極端な話、伝説の打ち出の小槌(振るだけで金が出てくる槌)を手に入れたとしても苦労して他人に売ろうとはしません。絶対に自分で使います。

と考えれば冷静になるのでは。


サイト量産システムとは?

名前の通りページを大量に作るシステムです。名前のとおりです。では何故大量に作ると嬉しいのか? とりあえずググればヒットし、そのページの広告を踏んでくれれば収益が入るという仕組みです。

うん、話だけ聞くと別に詐欺でもなく他人に影響がなさそう?

大きな影響があります

「風が吹けば桶屋が儲かる」「北京でチョウが羽ばたくと、ニューヨークで嵐が起こる」って感じで一般人が食らいます。

まず、誰かが量産サイトを作り広告収益を得るとします。そうすると、一般ユーザが検索した場合に必要ないものを過剰に見ることになります。ただ、そんな流れで広告を見ても物品の購入に至りません。

これが繰り返されると

  • 広告主は宣伝費の割に物品が売れない
  • 一般ユーザは検索しても役立たない情報ばかり
  • コンテンツ制作者は収益を奪われる

という流れになり、そのプラットフォームを運営しているGoogle社は全てのユーザから見放されることになります。

ということで、Googleはゴミコンテンツを検索結果や宣伝ページから排除することで利用者に役立つシステムを提供しています。

YouTubeのスクロール動画

2ちゃんねるのネタを文字にしてスクロールさせる動画が大量に発生したことを覚えていないでしょうか? Googleはそれに対し、システムで量産した価値のないコンテンツと判断しました。

そして、広告を外し、検索の順位も低く設定しました。 まあ、あのスクロール動画に関しては結構なユーザーが好きで見ていたと言う報告もあるので、100%ゴミだとは言えませんがGoogleとしては価値はないと判断しています。

最近だと統計データを時系列でグラフにする動画が現れていますが、次なるスクロール動画系として広告が付かなくなるのではと予測しています。

結局喜ばれるのは人の手で作られたコンテンツ

YouTube動画にしても、ブログにしても自分のアイデアで作ったものはそこそこ検索され、広告も付きます。

なので、高価でGoogleから嫌われる量産系ツールなどを買うのは止めて下さい。それより、動画編集ソフト、カメラ、素材集などのソフト・ハード、動画の撮影方法やブログの書き方、写真撮影の方法が書かれた本を読んだりして良質のコンテンツをネットに公開するようにして下さい。

Adsense審査は厳しい

昔は一度通ってしまえば、後はやり放題なGoogleの広告プログラムであるAdsenseでした。しかし、今ではサイトやブログを作るたびに審査が必要になっています。また、昔と比べて審査も厳しいです。

だから、審査を通ったとしても、ゴミのようなコンテンツをツールを使って投稿するのは止めて下さい。せっかくAdsenseの権利を手に入れることが出来たのであれば、自分の手でコンテンツを作り出して投稿して下さい。

Amazonでブログ術についての本を探す


【社内システム】Excel方眼紙が嫌ならフォーム入力システムを構築してもらって下さい

 Excelを方眼紙のように使うテクニックである、「Excel方眼紙」が悪者にされています。特に悪いのは社内での集計用フォームとしてExcelが使われるところです。特に入力する側は問題が無いのですが、集計する側は地獄です。ただ、Excel方眼紙が無くならない理由はバカバカしく明快です。


理由は2つ

  1. 記入者は困らない
  2. 上司、役職者はそんな作業をしない

です。まず、記入者は全く困りません。困るどころかおなじみのExcelファイルなので見れば分かる的な対応で記入してメールで担当者に返します。

上司や役職者も困りません。理由を書くだけバカバカしいのだが、そんな作業はやらないためです。

つまり、Excel方眼紙で困る人が少なすぎるというだけで放置されています。

Excel方眼紙からの脱出

非常にシンプルです。一番簡単な方法はGoogleフォームを使うことです。集計したいことをフォームにして、そのURLを対象者に送るだけです。受け取った側もURLのリンクをクリックして、ウェブサイト上で必要な情報を入れるだけです。

集計された情報はGoogleスプレッドシートにまとめられるので先程のコピペ地獄は有りません。

ただし、最近では社内のプライバシーマークなどの問題で、機密保持契約を結んでいない企業の仕組みを利用することは禁止されているので導入は厳しそうです。ただ、既製品で無料で使えるので情報システム部門に相談してみることをおすすめします。

余談だが、社外システムを使うことに関してはプライバシーとか機密保持とか言って上司は認めてくれないが、その話をしたあとで「キンコーン!」とスマホが鳴ったと思ったら、会社の書類がLINEされていたりします。バカバカしいけどこんな物です。

イントラネットにフォームシステムを

先程のGoogleフォームがダメなら、情報システムに相談してフォームシステムを作ってもらって下さい。 さらに、社内システムと連動すると社員番号など識別情報も入るので他の社員を偽ることも出来ません。この部分はGoogleフォームより良いのではと考えます。

なかなか、社内システムの変更を提案する考えは出ないかもしれません。しかし、会社ってそんなに硬直化はしていないと考えます。ですので、ダメ元で提案してみて下さい。

ただし、稟議を通すということなので、最初の提案は直属の上司からです。

Amazonで社内稟議について調べる

【C言語】forループのカウンタの正しい設定方法

 C言語に限らずforループは使います。そのときのカウンターの値はどうしているでしょうか? Cなのだから0始まり、1始まりはダサい、アマチュアっぽいって考えでは無いでしょうか?

鉄則はロジック通りに設定する

  1.     for(int i=0;i<9;i++){
  2.         for(int j=0;j<9;j++){
  3.             
  4.             printf("%3d",(i+1)*(j+1));    //計算式に不本意な+1が入っている。これは良くない。
  5.         
  6.         }
  7.         printf("\n");
  8.     }

掛け算の九九を書くよくあるサンプルです。これでも動作はしますが、多くの混乱の元があります。

一番は、ループが0から始まることです。これは大問題です。理由は現在の目的は九九を書くことですから。九九は1から9までです。だからループもそう書くべきです。

04行目の掛け算も問題です。(i+1)*(j+1)と謎の1を加えています。今回の場合なら単純なので分かりますが、本来なら i*j とするべきです。

低速度でメモリー資源が乏しいマイコンのプログラムは別として、ある程度計算資源のあるコンピュータならパフォーマンスよりコードの可読性を重視してみて下さい。

そうだ、ループも

  1. for(int i=1;i<=9;i++){
  2.     for(int j=1;j<=9;j++)

として下さい。始まりは1,終わりは9とロジック的に整合性のある数字のループであると考えます。

計算結果を配列に入れる直前で操作する

しかし、配列は0から始まります。今回の九九の計算結果も、最終的には一の段は0に収納されます。非常に悩ましいですが、この場合は配列にアクセスする直前に処理して下さい。

  1.     for(int i=1;i<=9;i++){
  2.         for(int j=i;j<=9;j++){
  3.             buf[i-1][j-1]=i*j;    //バッファへの収納時に初めてマイナスする。
  4.         }
  5.     }

このコードでは計算結果を二次元配列に入れていますが、計算用のループは1~9までとし、計算も変数通りで、配列への代入時に添え字をマイナス1しています。出来る限りロジック通りの数字を使い、仕方がない部分の直前で変換しています。

今回の場合、配列のゼロ要素を使わないと言う方法論もあります。現代のメモリが潤沢にあるコンピュータなら大して問題にならないことだと思います。しかし、テキストではなくグラフィックスの場合だとロジックに関係ない表示のためだけのパラメーターが多く現れます。なのでその意味として配列のゼロ要素も使うようにしています。

復習

  • 必ずロジック的に意味のある数字でループをする
  • 同じかそれ以上を罪悪だと思わないこと。九九で i=1;i<10;i++はダメです。唐突に10と言う数字がありなぜ九九で10という話になります。
  • 見た目のコードは確実にロジックから分離する

です。

AmazonでC言語の本をチェックする

【C言語】forループの基本 カッコの中がどのように実行されるか?

 C言語のfor文は最初の方で習いますが、その後は特に細かいことを気にせずに使っていると思います。普通に指定したパラメーター通りにループするだけなら特に問題は無いですが、込み入ったことをすると挙動がわからなくなることが多いです。
今回は改めて、for文の基礎というか細かいところを追いかけて見ます。

for文のカッコの中

for文のカッコの中は

for(int i=0;i<100;i++)

というようにセミコロンで、変数の初期化;条件;増分
と言った感じで「そういうものだ」という感じで書いているのでは無いでしょうか?

細かいことを考えずに動けば良いんだ! と思われます。しかし、エンジニアとしてツールを使う以上頭の片隅に真の理屈は置いておくほうが良いです。

ツールに使われているじゃなく、ツールを使っているって意識のほうが良いのでは無いでしょうか。


再びfor文のカッコの中

for文のカッコの中は以下の解釈です。

for(一度だけ実行される;ここがTrueなら「したいこと」を実行;「したいこと」が実行された後にここが実行される) 「したいこと」

です。整理するとカッコの中の1番めは、一度だけ最初に実行される箇所です。大体はループ用の変数の初期化が行われます。

カッコの二番目は、ループの各回が実行される前、この説明で言うと「したいこと」が実行される前に評価されます。ここの関数がtrueを返せば「したいこと」が実行されます。

カッコの三番目は、ループの各回が終了したら呼び出されます。多くはここでループ用の変数が増分されます。

具体的な動き

for(i=0;i<3;i++) hogehoge();
というプログラムの場合は

  1. iにゼロが代入される
  2. i<3が評価される。現在iは0なのでこの条件は真となる
  3. hogehoge()が実行される
  4. iが増分する
  5. i<3が評価される。現在はiは1なのでこの条件は真となる
  6. hogehoge()が実行される
  7. iが増分する
  8. i<3が評価される現在はiが2なのでこの条件は真となる
  9. hogehoge()が実行される
  10. iが増分する
  11. i<3が評価される、現在はiは3なので、この条件は否となりループ終了

という流れです。非常に重要なので冷静に理解できるまでトレースをしてみて下さい。

あまり、for文のカッコの中を荒らすのは良くないですが、どのようにfor文が動いているか以下のコードで確認してみて下さい。

  1. #include<stdio.h>
  2. //表示プログラムが煩雑にならないように関数にする
  3. int xtest(const char *str){    printf("%s\n",str);    return 1;}
  4. //for文がどのように回っているかチェックする
  5. main(){
  6.     int i;
  7.     xtest("Before for");
  8.     
  9.     for(i=0,xtest("init");i<xtest("conv")*5;i+=xtest("inc"))
  10.     {
  11.         xtest("for loop");
  12.         
  13.     }
  14.     
  15.     xtest("Exit for");
  16.     
  17. }

無理やり表示する文などをforのカッコ内に入れています。これでどのように実行されるか流れをつかめたのでは無いでしょうか?

  1. Before for
  2. init
  3. conv
  4. for loop
  5. inc
  6. conv
  7. for loop
  8. inc
  9. conv
  10. for loop
  11. inc
  12. conv
  13. for loop
  14. inc
  15. conv
  16. for loop
  17. inc
  18. conv
  19. Exit for
  20. PS C:\Users\j\OneDrive - フリーランス\c>

最後に

実は本職のプログラマーとされる人でも扱っているコードの深い部分を知らなかったりします。また、開発対象が大きくなるほど作業の標準化がされて、そのとおり使えば良いんだ! 的な考えになっていると思います。

ただ、それだけじゃ、ツールに使われているだけの状態なので、これを機会に色々細かいところを実験してみて下さい。

Amazonでプログラミングについての本を探す
動画を見る

【サポート】固定電話がIP化で使えなくなるという誤解

 固定電話。一般家庭では使われることが少なくなりました。新しく結婚して所帯を持つ人だと家に固定電話が無いという人も珍しく有りません。ただ、年配者だと固定観念から持たなければいけないという謎ルールで維持している人は多いと考えます。

そんな人もNTTから「2024年に固定電話がIP化される」という案内を受け取り混乱していると思います。今回は身内や知り合いでそんな人がいる人に向けたネタを提供していきます。

この案内が変な誤解を生む

何もしなくて良いと伝える

結論は知っていると思いますが、利用者側の仕組みは全く変わらないということです。NTT側がIP化されるだけであり、家には今までのアナログと同じ信号を送ってくれます。だから

  • 電話機はそのまま使える
  • 電話番号は変わらない

ということです。なので「何もしなくて良い」とだけ伝えて下さい。

ほとんどの人には重要ではない

良い知らせとしては、電話代が安くなる

電話代が全国一律になります。遠くにも市内料金と同じ金額で電話できます。長電話が好きな人であれば嬉しいです。

何か使えなくなる人は連絡が来る

ガス検針やホームセキュリティのサービスで電話回線を使っている場合はその仕組が使えなくなりますが、その連絡と新しい方法は契約しているガス会社から来るので何もする必要は無いです。

マイラインとか覚えてますか?

ISDNの人は注意

昔に安く二回線の電話を引けるとISDNにした人だと、変更になる可能性があります。その場合でも怪しい業者ではなくNTTと相談するように伝えて下さい。


信頼できる相談先を見つけるのがシニアの責務

良く、会社や商店の規模にそぐわないビジネス電話が置いてある事務所を見ます。二人しかいない会社なのに、部署が20くらいありそうな会社みたいな電話があるというものです。

あれは、ビジネスホンの営業に過剰なものを買わされてしまったのではと考えます。他にはテレビがデジタルになるからと言って高額の工事費を払ってしまうという詐欺があります。実際は何も工事しなくても良い家なのに

「工事終わったので安心してテレビを買い換えればデジタルになります」

って言って10万円くらい請求するとのこと。

こんなことにならないように、早めに自分の身の回りを相談できる連絡先を決めておき、すべての相談はそこにするようにさせて下さい。

というか、一般的な対応として初対面の人に家の重要なことを任せることは変であるということも教えて下さい。これがわかっていればすべての領域で詐欺など有りません。

【ハードウェア】トラックボールを強くおすすめする理由

 パソコンと言ったらマウスは必須。当たり前だろと突っ込まれるほどマウスはポインティングデバイスの代表格です。ここまで書いてみましたが、この説明の意味が全くわからない人も多いと思います。

実はマウスみたいなデバイスのことを「ポインティングデバイス」と呼びます。そして、ポインティングデバイスにはマウス以外にも色々あります。マウス以外で有名なものに「トラックボール」があります。

トラックボールとは?

昔なら「マウスをひっくり返したような物」という説明が出来ましたが、今では更に混乱しそうです。

トラックボールは表面についているボールを転がしてカーソルを動かすデバイスです。マウスは主に腕で操作をしますが、トラックボールは指先だけで操作します。そのため、体の筋肉を使う量が少なく長時間の作業に向いています。


平面がない場所でも快適操作

マウスを使うには広い平面が必要です。事務所などの机だと良いですが、生産現場のような机がない場所だと操作が困難です。そのときにトラックボールを使うと非常に快適です。理由は置いたまま使えるというところです。こんな、メタルラックに置いて使うことも出来ます。

メタルラックに置いても操作可能

トラックボールにも種類がある

1つ目が大きいボールを人差し指と中指で操作するものです。親指でクリック、小指で右クリックです。ボールが大きいので慣性が働き素早く操作出来ます。また、人差し指と中指で精密な操作も出来ます。

大玉を人差し指と中指で転がす

2つ目は小さいボールを親指で操作し、人差し指でクリック、中指で右クリックをするものです。ボールが小さいので素早い操作は出来ません。また、親指でポインターを動かすので精密な操作も苦手です。その一方でボタン操作はマウスと変わらないので早く操作になれることが出来ます。

マウスに似た感じで操作できる


最近では家電量販店でも取り扱いがありますので、興味のある方は是非チェックして下さい。


【生活術】パソコン関係の救援を求められたらどうする?

 保守担当からプログラマ、システムエンジニアなどの仕事をしている人、ひどい場合はIT関連の営業担当などの悩みとして

「パソコン、スマホなどのIT関連の質問を受ける」

です。これがクルマの新車情報的な噂話、「新型iPhoneがどうなるか?」みたいな話なら楽しいのだが、まず、そんな話では有りません。

JAFみたいに助けて欲しいという救援要請です。まあ、人助けをして喜んでもらえるのだったらいいのだが、休日に仕事に似たことをやっているのだから疲れます。

足成より

IT救援は○○だと考える

具体的なIT救援については後に書きますが、それらを別の業種で例えると

「隣のタクシー運転手にタダでお迎えを依頼する」

くらいの暴挙だと考えて下さい。そのくらいの失礼なことを相手にされているとまずは認識して下さい。どうでしょうか、スッキリとした後に軽々しく救援を頼む人に不快感を覚えたのでは無いでしょうか?


断りのコンセンサス

先程のタクシー運転手を例えて、断り方を考えてみます。近くに個人タクシーを営んでいる人に「タダで乗せて下さい」と言った場合は

「どうして、あなたをタダで乗せないと行けないのでしょうか?」

となります。更に、その断られたことを周りに言っても、当たり前でしょ!ということになります。これは、周りには「休日のタクシーには無料では乗せてもらえない」というコンセンサス(同意)があるためです。

一方、ITサポートに関しては残念ながらそのコンセンサスは有りません。タクシーの場合は噂話にもならないことが、あなたが断ったITサポートに関しては周りは「ケチな人」というコンセンサスが形成されていると考えて下さい。

足成から

実際にパソコンサポートを使ってみる

じつは、これが最強の断り術だったりします。近場のパソコンサポートを実際に呼んで救援してもらった実績を作って下さい。そのときに、周りに宣伝するからとチラシをもらうことも忘れないで下さい。

そして、周りがサポートを求めてきたら、その業者のチラシを渡しながら

「ここは親切でいいですよ。私も助けてもらっています」

と言って下さい。あなたが直せないのですか? と言われた場合は

「あの業者は難しいことも直してくれますよ。助かっています」

と繰り返して下さい。

家族が言いふらすのが原因

家のITサポートを引き受けていると、家族が井戸端会議的に「ウチの主人は詳しい」みたいなことを話してしまいます。それを防止する方法としては、家族の機器を直す場合は一旦預かった上で、サポートに連絡するとでも言って下さい。

ただの再起動や再設定でも目の前で行うと出来るように感じますが、一度預かって、サポートに直してもらうと言って置けば、自分自身が修理を出来るとは思われません。

まあ、部屋の中で自分で直すことにはなるのだが、そのときも無料サポートを使ったと言って数日後に返却して下さい。3日くらい放置が良いのではと考えます。

あとは、再起動や電源を落とすことで復帰することが多いです。そのため、IT機器の電源は一箇所で操作出来るように配線をしておいて下さい。「動作不良が起こったら、ここを操作」みたいに教えておけば各自操作出来ます。

いろいろな事例とその対応

私が想定したいろいろな例と対処方法です

  • ネットが接続出来ない。プリンターが出ないなど
    端末とネットワーク機器の電源再投入をやってもらう
  • パスワードが分からない
    これは理詰めで、暗証番号と同じであなた自身にしかわかりません。無理なら、パソコンサポートしかありません。
  • 有料ソフトを無料で欲しい
    私は「〇〇電機で買いました」とでも言って欲しい。よくわからないけどそのスタッフが教えてくれたとでも。
  • ソフトをインストールして欲しい
  • 私も「パソコンサポートに連絡してやってもらった」と言っておく
  • 電源が入らない
    コンセントを抜き差ししてみて? それでダメならサポートを
  • パソコンを買いたいのだけど?
    ○○電機で買えばいいのでは?私もそこで買いました。

これが一番大きな罠かも?

最後に出すなと言われそうだが、一番の罠は自分自身にあると考えます。それは

「自分のITスキルを周りに披露したい」

という願望だと考えます。別に他の能力と同様に披露しても良いだろ? と言われそうだが、生活に密着して皆さんも使っている能力を自慢した場合は単に利用されて終わるだけです。

バスケでシュートが上手い

って人は別にその後は何も問題は無いので、草試合でポイントしてもその後タダで何か責任があることを押し付けられる事は有りません。

最後に重要な言葉で終わります。

「他人のIT機器には絶対に手を触れないこと」

です。

【ハードウェア】ノートパソコンにキーボードを付けるのは良いのか?

 昔だとコンピュータ好きはデスクトップPCでした。自分でカスタムできるし、コスパという意味では最高です。 しかし、パソコンの高性能化でストレスなしに使えるノートパソコンが登場しています。 そのため、コンピュータ好きの人ほどノートパソコンを買う傾向にあります。

その人達も以前はキーボードにこだわっていても、ノートパソコンに変えたら当たり前のように装着されているキーボードを使っています。


ノートパソコンって姿勢が悪くなる

ノートパソコンの画面とキーボードの位置は100%作りての都合で決められています。あの、ユーザ体験を第一にするAppleですら他社と同じ配置です。画面を開いて、キーボードに手をおいたときの姿勢はどのメーカーのノートパソコンでも一緒です。

その作りての都合で悪い姿勢を強要させられます。最近では会社でも管理がしやすいということでノートパソコンが普及しています。電源を接続するだけで他の配線は不要だし、トラブルがあっても交換が容易だというのが理由です。

テレワークやカフェなどでの作業が増え、よりノートパソコン率=姿勢の悪い率が高くなります。


外付けキーボードを買って下さい

バカバカしいですが、ノートパソコンを快適に使うには「外付けキーボード」と「画面を持ち上げるスタンド」です。これで、デスクトップパソコン並みに快適になります。

Bluetoothで接続できるキーボードなら機能上何でも使えますが、品質の悪いキーボードですと入力が苦痛です。絶対に数千円の物は避けて下さい。

おすすめは、ちょっとミーハーですがガジェット系ブロガーが激推しているロジクールのMX Keys Miniです。

Logicool MX Keys Mini

質感や打鍵の感じは高級ノートパソコンに内蔵されているキーボードと同等です。私は、HP Spectreを使っていますが、それよりMX Keys Miniの方が打ちやすいと考えています。

他人から色々言われるのは無視ということで

ノートパソコンに外付けキーボードを付けていると大体は「いじり系」の話ばかりになります。これに関しては、強く議論せずに「使いやすいですから?」とでも言っておきましょう。

ただ、最近湧いている老害系キャラから力づくでやめるような行動になったらそれは相手が悪いので「別に勝手でしょ?」と言っておくのが良いです。上司先輩が言ってきたら、その会社はちょっと痛いなと感じる「試金石」にでもなるかもしれないが。

ついでにトラックボールもおすすめ

私は長年トラックボールを使っています。使う理由としては手を動かす量が減るということです。また、机の面積もマウスより少なくて済みますし、マウスパッドも不要です。私はケンジントンのエキスパートマウスという名前の製品です。余談だが、製品名はマウスだが、トラックボールです。

Kensington Expert Mouse Bluetooth


【生活術】絶対に交流関係のIT機器には触れないこと

 このブログを見ている人は何らかのPCスキルが有ると思われます。C言語のこと、Windowsのショートカットのことなどをググっていたらここを見ていた。

そんなあなたは交流関係でもパソコンとかネットとかスマホとかを教えて欲しい聞かれることは無いでしょうか?

足成より

絶対に他人のIT機器には手を出さないこと

良く、自分の力を他人に役立てると良いことがある。と言われることはあると思います。もちろん、物を運んでとか、簡単な力仕事を手伝う、掃除を手伝うなどは良いことです。忙しくない限り手伝って下さい。

しかし、IT機器だけは別です。


あなたが触った後の責任は全てあなたに

親切心でネットの接続が不安定になっているパソコンの設定を変えたとしましょう。もちろんその時は喜ばれますが、大体は後で調子が悪くなったと言う苦情になります。そして、その後の責任はあなたに降りかかります。

印字できない、データがクラッシュした、ネットに接続できない、ログインできない…

正直知るか? というくらいの苦情や質問が来ます。

サポートは口で電源を再投入する程度に

大体の問題はIT機器の電源を切って、入れれば回復します。その操作を相手に行ってもらって下さい。

繰り返しますが、絶対に手を触れてはいけません。また、操作してと頼まれても自分でやってほしいと言って下さい。

そして、それでもダメならパソコンを買ったメーカーなどにサポートを依頼するように行って下さい。

地元のPCサポートを体験してみる

自分のIT機器くらいは自分で直せると思っている人も、今後のために地元のPCサポートに依頼する体験をしてみて下さい。

そうすれば、他人がITで困っている場合も、「良いサポート業者知っていますよ。連絡先教えましょうか?」と言えます。

繰り返しますが、ITスキルがあっても絶対に他人の機器に手を出してはいけません。

人を助けたければ、複雑なことではなく単純な力作業や手伝い程度にしてください。


【地図】GoogleMap上の任意の座標への短いURLを作成するショートカット

 GoogleMapの普及で場所を知らせるのが楽になりました。しかし、URLが非常に長く送付された人が不安に感じることがあります。一方で短縮アドレスを使うと、怪しいアドレスではないか? という不安もあります。


Google Mapのドメインでできるだけ短くする

以下のアドレスはどう思いますか?

https://maps.google.com/?q=34.64670452638017,137.80009938451718

これならGoogle Mapであると分かるので安心できます。やっていることは非常に単純で

https://maps.google.com/?q=

というURLのq=の後に続けて座標を入れるだけです。座標はパソコンのGoogleMap上で右クリックして出てきた数字を選ぶだけです。

簡単にできるショートカットのコードを作りました

ショートカットを作成し、以下のコードをコピーして下さい。

  1. powershell -NoLogo -Command "& {Get-Clipboard | %{'https://maps.google.com/?q='+$_.Replace(' ','') } | Set-Clipboard}"

これでショートカットが作成されます。先程の方法で座標を取得し、ショートカットを実行すればURLがクリップボード上にコピーされます。

メールしたり、SNSに貼り付けたりすれば、安心できるURLによる地図の場所が配信できます。

AmazonでGoogleMapについての商品を見る

【コメント術】分かりやすいプログラムを書く方法

 昔のプログラミング初学者向けの本の定番である「素因数分解」。著者は親しみや興味が出るからだろうとこのテーマを選んだと思われます。しかし、思いっきりすべっている感もあります。

中学生の数学で習ったし、暗号とかの話にも繋がる素数や素因数分解ですが、正直つまらないし、昔習ったことなど忘れています。

まあ、そんな話より素因数分解を思い出しながら記事を読んでみて下さい。


素因数分解って?

与えられた数字をとにかく整数で割りまくって行くことです。最終的には全部の数字が素数になります。あっ、素数って何? 聞かれそうだが素数とは

「その数と1以外で割り切れない数」

のことです。皆さん大好きなセブンイレブン、7と11を例にすると

7÷1=1
7÷2=3…1
7÷3=2…1
7÷4=1…3
7÷5=1…2
7÷6=1…1
7÷7=1

と、1と7以外では割り切れません。11も

11÷1=1
11÷2=5…1
11÷3=3…2
11÷4=2…3
11÷5=2…1
11÷6=1…5
11÷7=1…4
11÷8=1…3
11÷9=1…2
11÷10=1…1
11÷11=1

と、1と11以外では割り切れません。

素因数分解に話を戻して、例えば30を割り切れるだけ割り切ると

2☓3☓5

となります。ここで出てきた2,3,5は全て素数です。このように全て素数に分解することを素因数分解と呼びます。多分というか絶対に中学一年の最初の数学で習っています。

プログラムで書くとどうなるか?

以下がプログラムで書いた素因数分解です。

  1. #include<stdio.h>
  2. int main(void)
  3. {
  4.     int num,i;
  5.     printf("Enter Natural Number?");
  6.     scanf("%d",&num);
  7.     if(num<0)
  8.     {
  9.         printf("Error %d is not Natural number.\n");
  10.         return 1;
  11.     }
  12.     
  13.     printf("Factoring\n");
  14.     
  15.     if(num==1)
  16.     {
  17.         printf("%d\n",num);
  18.     }
  19.     else
  20.     {
  21.         for(i=2;i<=num;i++)
  22.         {
  23.             if(num%i==0)
  24.             {
  25.                 printf("%d ",i);
  26.                 num/=i;
  27.                 i=1;
  28.             }
  29.         }
  30.     }
  31.     return 0;
  32. }

やっていることは、とにかく割り切れる数字が見つかるまでひたすら割っていくことをやっています。ただ、このプログラムは分かりにくいです。

理由としてはコメントが入っていないことです。これは置いておきます。

次にやたら唐突に出てくる数字が多いところです。ただ、0や1は唐突に出しても良いと妥協されています。それ以外の数字だと

  • 15行目に num=1 とある
  • 21行目にi=2
  • 27行目はi=1なのだが、どうして途中で1なのか?

という部分があります。そうだ、ツッコミはやめてほしいのですけど、目的は素因数分解を極めることでは無いので総当たりのループです。

多少わかりやすくしてみました

以下は修正したプログラムです

  1. #include<stdio.h>
  2. const int ciOne = 1; //やりすぎかもしれないが1も定義
  3. const int ciFirstPrime = 2; //最初の素数は2
  4. int main(void)
  5. {
  6.     int num,i;
  7.     printf("Enter Natural Number?");
  8.     scanf("%d",&num);
  9.     if(num<0)
  10.     {
  11.         printf("Error %d is not Natural number.\n");
  12.         return 1;
  13.     }
  14.     
  15.     printf("Factoring\n");
  16.     
  17.     /* 1が入力された場合はエラーではないが素因数分解の例外として1を出力して処理を終了
  18.     あまりエレガントでは無いが、数学でもそういうルールなので*/
  19.     if(num==ciOne)
  20.     {
  21.         printf("1\n",num);
  22.         return 0;
  23.     }
  24.     
  25.     //数字が1になるまで現在の数を割り続ける。内側のループは最初の素数2から現在の数−1までループ、割り切れたらその数字を出力し、それで割った数を現在の数とする。
  26.     while(num != ciOne){
  27.         for(i=ciFirstPrime;i<=num;i++)
  28.         {
  29.             if(num%i==0) //数字が割り切れたなら
  30.             {
  31.                 printf("%d ",i);
  32.                 num/=i;
  33.                 break;
  34.             }
  35.         }
  36.     }
  37.     
  38.     return 0;
  39. }

コメントが入っているのでズルいだろ? って言われそうですけどそれ以外で直したポイントを説明します。

まず、1という数字が入れられた場合は特例として処理します。メインのループで1を考慮するのも複雑性を上げるだけなので除外しています。

プログラミングの罠として、全て一般化したルールで実装したいという衝動に駆られますが、それにより可読性を下げたり、アルゴリズムが複雑になることは避けたいので特例のパターンは先に抜いておくことをおすすめします。

次に決め打ちの数字1,2を定数として定義しています。2、3行目で const int とある場所です。定数をプログラムの途中に配置すると後でわからなくなるので最初に定義して名前として使うのが良いです。今回は1はciOne、2はciFirstPrimeと定義しています。

34行目にbreakとありますが、一度ループから出ています。そして、その外のループで再び中に入っています。前回のプログラムではループ変数 i=1 と代入されていますが、この1は後でプラス1されて2になることを意図しています。しかし、分かりにくいのでこの方法はやめています。唐突な数字を代入されるより、breakでループを出るという考えの方がわかりやすくミスも有りません。

最後にコメントは、何を処理しているかを重点的に書いています。C言語は読めることを前提にしていますので、コードを見れば分かることは書いていません。

話はずれますが、プログラミングの解説書にかかれているコメントはプログラムを学習するためのコメントですので、本来の書き方とか異なります。決して i=1 のコメントとして「iに1を代入する」なんて書いてはいけないです。 どういう意図で代入するかを必ず書いて下さい。

以上、簡単なプログラムをわかりやすく書く方法の説明でした。

AmazonでC言語の解説本を探す



【C言語】三項演算子は悪者なのか?

 C言語で条件に応じた代入をするときはif文を普通に使っていると思います。ただ、テキストなどには「三項演算子」という方法も書かれていると思います。

三項演算子を使うとコードは非常にスッキリとします。しかし、if文と比べると何をやっているのか良くわからないという問題、つまり可読性の問題があります。


じゃー三項演算子は封印?

それでもいいんじゃないですか?と言っても良いかもです。とにかく可読性のことを考えるとif文が分かりやすいわけだから。

しかし、if文って長いです。elseを使って場合によって2つの値を入れる場合は

  1.     if(z<0){a=msgNeg;} else {a=msgPos;}

となります。さらに場所を節約するために一行にしているので、可読性は下がっていると考えます。であれば、同じ表現を

  1. b=z<0?msgNeg:msgPos;

のように三項演算子で書けば良いのでは無いでしょうか?そして、何をやっているかコメントで残しておけば十分理解できると考えます。

簡単な結果だけに適用する

冷静に考えると、三項演算子で見にくい場所は、判断結果の収納場所です。判断を書く場所はif文のカッコの中と同じです。

なので、結果によって単純な定数を代入する程度の処理だけに使って下さい。もちろん、三項演算子を使ってこのような処理をしています。というコメントは必須です。

以下はIF分と三項演算子を使った比較サンプルです。

  1. #include<stdio.h>
  2. const char *msgNeg = "負の値";
  3. const char *msgPos = "正の値";
  4. main(){
  5.     int z;
  6.     const char *a,*b;
  7.     
  8.     printf("z=?");
  9.     scanf("%d",&z);
  10.     
  11.     //zが正か負の値かでメッセージを表示する。
  12.     
  13.     //zが正か負かでメッセージを変更する。bにメッセージの文字列先頭が入る。
  14.     if(z<0){a=msgNeg;} else {a=msgPos;}
  15.     //三項演算子を使った方法。コードはスッキリするが初見ではわかりにくい
  16.     b=z<0?msgNeg:msgPos; //zが正か負かでメッセージを変更する。bにメッセージの文字列先頭が入る。 三項演算子を使用。
  17.     
  18.     printf("a=%s\nb=%s\n",a,b);
  19.     
  20. }

このような単純な処理であれば、しっかりとコメントをした上で三項演算子を使いコードのスペースを削減するのが良いと考えます。

馴染みのない複雑なアルゴリズムを記述する場合は、丁寧にIF分を使うことをおすすめしますが、単純で誰でも分かるロジックであればコード単体での可読性より、文字の少なさを優先したほうが良いと考えます。

そして、簡単なコードがコンパクトになることにより、より高水準のやりたいことに集中出来ると考えます。

AmazonでC言語の本を調べる


【C言語】Bool型はどのようにメモリー保存されているのか? 1ビット?

 C言語やC++で使われている二値型であるbool変数。trueとfalseという二値が収納できるのは分かりますが、メモリーの中でどのように保管されているのかは知っていますか? 環境によって違うと思いますがWindowsでは1バイトだったりします。


Bool型のメモリー確認

C言語は低レベルな言語なので、メモリー関連の操作が分かりやすいです。正確にはブラックボックス化されていないので調べようと思ったら力づくで調べることも出来てしまいます。

今回はC++から実装されたbool型がどのようにメモリーに展開されているかを実験していきます。

今回は嬉しいUnion

C言語には構造体という変数をグループ化する方法論があります。こちらは比較的分かりやすいですが、そのときに「共用体」というものを習わなかったでしょうか?

構造体はstructですが、共用体はunionです。ユニオンって言葉も組合って意味があるので、グループ化の一種に思えますが正直全然違います。そして、普通のプログラマにとっては使い所が分からない仕組みでもあります。

共用体とは、同じメモリーを複数の変数で使う宣言のことです。

仮にこんなコードを実行すると、小文字のaからoまでを出力します。

  1. #include<stdio.h>
  2. union test {
  3.     char str[20];
  4.     unsigned int num[5];
  5. };
  6. //bool型がどのようにメモリーに配置されているか確認。
  7. main(){
  8.     union test s;
  9.     
  10.     s.num[0]= 0x64636261;
  11.     s.num[1]= 0x68676665;
  12.     s.num[2]= 0x6C6B6A69;
  13.     s.num[3]= 0x006F6E6D;
  14.     
  15.     printf("%s\n",s.str);
  16. }

ここでキーになるのは 共用体testは str文字列と符号なし整数の numを同じメモリーで共用しています。つまり、str文字列に書き込みをすればnum型も変更されるしその逆もあります。

今回はnum型に16進数で数字を書いています。64636261と16進数で書いています。これはアスキーコードで61は小文字のa、64は小文字のdに相当します。

Windowsはリトリエンディアンなので、数字で言う低い桁がバイト単位で逆転します。このため、64636261と整数型に入力した場合、それを文字列として解釈すればabcdとなります。そして

s.num[3] = 0x006F6E6D を代入しています。これはnmoを意味します。最後のゼロは文字列の約束事で、文字列の終わりは必ずゼロにする約束です。これを守ることを前提に関数などが実装されています。プログラミングは性善説です。

本題のbool型のメモリー

以下が実験コードです

  1. #include<stdio.h>
  2. union test {
  3.     unsigned int bits;
  4.     bool bit[4];
  5. };
  6. //bool型がどのようにメモリーに配置されているか確認。
  7. main(){
  8.     union test b;
  9.     
  10.     b.bits = 0;
  11.     b.bit[0] = true;
  12.     b.bit[1] = false;
  13.     b.bit[2] = true;
  14.     b.bit[3] = true;
  15.     
  16.     printf("%x\n",b.bits);
  17. }


このコードは、共用体で符号なし整数とbool型の配列を共用しています。これを実行すると

1010001

と出力されます。ということはBool型はビット単位でのデータ保存ではなく、バイト単位であることが分かります。なのでメモリー節約が目的ではないということが分かります。


考察

実はビット単位でデータを保存すると読み書きが遅くなります。コンピュータってバイト単位で読み書きするのが効率が良いです。そのため、bool型のような1ビットの値でも1バイトを使って収納するほうが効率が良いです。

AmazonでC言語の本を探す

明和電機が豊川に来た

 『明和電機』って聞いて懐かしいと思う人は多いです。1990年代のテレビを騒がしていた新しいアーティスト。変わった楽器で演奏するパフォーマンス集団という感覚では無かったでしょうか? そんな明和電機もまだ活動しているみたいで、昨年、私の地元の豊川市で展覧会が行われました。

豊川市、桜ヶ丘ミュージアムに明和電機が

地元に来たのだから見に行った

実は私は変わったアーティストというより、前衛美術の作者という認識です。音楽を聞くというより、少し暗い世界観を楽しみにしています。

かわいい、ポロロン

入り口では可愛い『ポロロン』が出迎えてくれます。これはゆるい。手前のボタンで音を出すことが出来ます動画

こんなゆるいイメージが有名ですが、これは勘違いです。

こういう演奏がメインだと思われている

変わった形の楽器で演奏するというだけという印象は大きく。お客さんはここに多く集まっています。この演奏が一番盛り上がっている感じでした。

これも90年代は有名だった

このスタイルの演奏も典型的な明和電機のイメージを作っています。でも、もっと先にはダークな世界があります。

何か怖い

ここからが知らない人が多い明和電機の世界です。YouTubeのパフォーマンスを観た子どもたちはこれを見て怖がっています。まあ、大人でもここからは怖くて暗い世界ですから。

これは子供が喜ぶ。ボタンを押すと音がなります

怖いエリアに行く前の体験コーナー。こういうのは子どもたちは喜びますね。

では、怖い世界に入ります。



これは何?って感じです。色々と怖そうな造形の美術品が並んでいます。全て魚をモチーフにした作品で、魚器(なき)と呼ばれています。これを作るために何匹かの鯉を犠牲に…これ以上は本を読んで下さい。

13週目の胎児 サバオ君

うーん、これは怖いでしょ? 一応、思考の道具ということで過去には無印良品の電卓とともに展示された経歴があるものです。

理詰めで考えるときは電卓、理屈が通じない人と不条理な会話をするためにはこの「サバオ」が役立つとのことです。よくわからないですけど。



在廊日に本人と撮影しました


動画を見る

【C言語】バイナリーデータ作成は明確な意思を持つべき

 普段は高レベルなプログラミングをしている人も、業務によっては低レベルなプログラムをすることもあります。近年ではXMLやJSONなどのテキストベースのデータ交換手法や、データベースエンジンへの書き込みでデータのやり取りをするので、そもそもの概念がない人もいます。


データ交換に明確な意思は必要

はるか昔ですが、C言語で整数型のデータをバイナリーデータとしてディスクに保管するサブシステムを作成しました。

仕様は先輩が作っていたのだが、そのときに整数型の順番は決まっているが、どのようにバイナリー化するかが決まっていませんでした。

ビッグエンディアンか?リトルエンディアンか?

気持ち悪いので先輩に聞き返したら。「それぞれ4バイトなのだから順番に入れれば良い」と言われました。それ以上の事は言いませんでした。当然リトルエンディアンなのかわかりません。

とりあえず、ビッグエンディアンとしてプログラムを作成しましたが、後で驚く発言を聞きました。

整数は上位下位が反転するのが常識です

これが、先輩の指示でした。まあ、ひどすぎです。確かにIntel系CPUだと、int型の整数をそのままメモリーダンプすれば、上位下位は逆転します。確かにそのとおりですが、なってしまうって指示は酷いです。

仕様を作るときは、決して「なってしまう」などという表現はしません。明確に行います。この場合なら

  • 整数は4バイトのリトルエンディアンで出力する
  • 実行される環境は全てWindowsでIntelのCPUである
  • 今回はビッグエンディアンの環境では実行されない
  • 今回はパフォーマンスを優先するため、ソフトウェアでの処理は見送る
  • 今回はSUNなどのビッグエンディアンの環境への移植性は考えない

というくらいの指示が必要です。

C言語での実験

#include<stdio.h>

//int型の動きを知るプログラム
main(){

unsigned char buf[10]; //とりあえず10バイト分のバッファを確保
int *iData; //整数型のポインタを宣言

//10バイト分のバッファを全て255で埋める
for(int i=0;i<10;i++){
buf[i]= 255;
}
//整数型のポインタのアドレスをバッファの先頭に設定する
iData = (int *)buf;
//整数型ポインタのアドレスに1000を代入
*iData = 1000;

//バッファの中身を表示
for(int i=0;i<10;i++){
printf("%d\n",buf[i]);

//本プログラムの狙いとしては、全てのバッファを埋めた後、同じアドレスに整数を代入する。
//バッファーが255で無い場合は、整数型の代入によって影響を受けたということになる。
//観察ポイントとしては、255じゃない部分の数が整数型のバイト数。
//数字が昇順であればintel系CPU,じゃなければ他のCPUということになる
//メモリーマッピングをする場合は、この方法は望ましくない。積極的に仕様を決めるべきである。
}
}

以上のコードを実験のために作りました。整数型の変数をメモリにダンプするとどうなるかの確認です。

仮に10バイトの領域を確保し255のデータで埋めます。次に、整数型のポインタを宣言し、そのアドレスを先程の10バイトの領域の先頭に設定します。

そして、その整数型のアドレスに1000を書き込みます。

これを私の環境 Windows11 で実行すると 先頭が232 次が3,次が0、次も0,そして後は255が続きます。

実行結果、最初の4バイトが整数として使われている

これが意味するところは

整数型を代入すると最初の4バイトに値が書き込まれる。先頭が232,次が3ということは収納はリトルエンディアンであるということです。

C言語でプログラムを組んでいる人は、常にこのような実験コードを動かして、ハードウェアの特性を把握しておくことが必要です。

ソースコード

繰り返しますが、「リトルエンディアンになってしまう」という意識でプログラムは組まないで下さい。「リトルエンディアンにする」、「ビッグエンディアンにする」という明確な意思と、妥協するのであれば考えた上で妥協する必要があります。

ウィンドウズアプリ入門 クリップボードにコピーされたらメッセージを受信する方法

 Windowsアプリでコピーされたときにイベントを取得できると便利です。例えばコピーされた内容を画面に表示したい場合などです。 もちろんタイマーイベントで定期的にポーリングをする方法もありますが、やや無駄な処理かもしれません。 Windowsとしてはコピーされたときのイベントを...