[アルゴリズム] 選択ソートの実装(C言語編)

banner-1183445_1280
LINEで送る
Share on GREE
Share on LinkedIn

C言語って高速に動作するアプリケーションが作れるけどコンパイル言語って面倒くさいな〜って思っていましたが、
実はそれは、「ポインタ」を勉強することを避けてきた事も原因でした。
今回、関数を実践で使うことによって、ポインタについて非常によく理解することができました。
そして、C言語の色々なルールや法則をここにきてようやく理解できたので、この企画やっていて本当に良かったと思える瞬間でしたね。

という訳で、選択ソートのC言語編ですが、構築時間は30分程度でしたが、少し調査に時間をかけた内容でした。

ソースコード

結果

無事にソートされてて、一件落着です。

解説

前回のバブルソートでは、main関数だけで処理しましたが、今回は全ての言語で関数を基準に汎用性構築を行うという趣旨なので、C言語でも行なってみましたが、今まで知らなかった事がいくつかありました。

・関数の返り値に変数を使ってはいけない。
・ポインタで変数を受け渡すと、宣言の仕方によっては配列のサイズが変わってしまう

C言語に長けている人にとっては当たり前のことかもしれませんが、今どきのインタプリタ系言語では、このC言語のルールがイマイチ理解しがたい状態なのです。
C言語自体が、宣言という面倒くさい手続きがあるため、言語自体が面倒くさい言語という認識になってしまっているんでしょうね。

関数の返り値

今回は「selectSort」という基本コアエンジン部分の関数と、「arrayView」という表示を行う2つの関数を構築しましたが、
オブジェクト思考で考えると、selectSortに配列を渡して、ソート処理をしたデータをreturnして、受け取ったmain関数でそのままarraySortに受け流すという事が一般的なフローと考えられますが、ここでは、乱数配列部分をポインタとして扱うことで、returnを有しないvoid関数にして、直接元の変数を上書きしているという流れです。
便利とは言えないが、メモリの無駄使いをしないというポインタ、今まで本当に意味が分からなかったんですが、こういう事だったんですね。

関数に渡した配列のサイズ

今回宣言時に「int numbers[] = **」として任意サイズで受け取る仕様にしているんですが、numbers[10]のようにサイズ指定してあれば、さほど気にしなくても良いんですが、こういう処理って実際に個数が可変する汎用性って必須じゃないですか?
という事でこの仕様で関数に渡すと、main関数では、28バイトのメモリサイズに対して、関数に渡したあとでは、8バイトという結果になってしまいました。
部分的なソースコードですが、以下のような詳細です。

どうやらこれは、任意個数での宣言と、受け渡した配列の型が違っていることが原因なようです。
下記に書かれていました。勉強になりました。
文字配列を関数に受け渡すとsizeof() 関数の値が変わる。
ポインタとして、同じ配列を渡していると思ってたのにそもそもの器が違う状態ってどういう事なのか???
numbers[]と*numbersの違いと言われるとわかった気になりますが、やはりわからないですね。
こういう時どうすればいいかというと、「そのうち分かるでしょう!!」とその場をスルーします。
ただし、こういう状況がアリ得るということを忘れてはいけませんね。

関連リンク

選択ソート

解説
Javascript
PHP
Python
Shell
Awk
C言語

アルゴリズム過去記事

http://wordpress.ideacompo.com/?cat=562&tag=Algorithm

Leave a Reply

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です