いつか、どこかで

【C言語とJava】配列の違い

今年の新人研修で、結構コーディングできるのに、私が配列の図解をしたら「初めてわかった!」ってなっている受講者がいて、やっぱり混同しやすいのかなーとまとめてみることにしました。

 配列の基本

まず要素5個の配列を作る場合 C言語では

int array[5];

Javaでは

int[] array = new int[5];

大括弧の位置が違いますが一緒でも良いです。メモリ上はこんなふうに違います。 f:id:riko111:20200313110924p:plain

※イメージ図です。実際のメモリ配置を表してはいません。

宣言と同時に初期化する場合、 C言語では

int array[] = {10,20,30,40,50};

Javaでは

int[] array = {10,20,30,40,50};

と同じように書けます。大括弧内の要素数は同時に初期化する場合のみ省略可能です。省略しなくても良いです。

この書き方を分けて書くと、 C言語では

int array[];
array = {10,20,30,40,50};

Javaでは

int[] array;
array = {10,20,30,40,50};

となりますが、どちらもコンパイルエラーになります。ただし、エラーになる箇所が違います。

がエラーです。これは、最初の図を見てもらえば、

  • C言語ではarrayのメモリは配列そのものなので宣言の時点で要素数が決定していないといけない
  • Javaではarrayのメモリは配列を参照するものなので宣言の時点で配列そのものの要素数が不明でもかまわない

という違いが理解できるかと思います。 そして、Javaでは

int[] array;
array = new int[]{10,20,30,40,50};

と記述することが可能です。

また、あらかじめ配列が用意されているときにその要素数を調べるには、 C言語では

int array[5];
int length = sizeof(array)/sizeof(int);

Javaでは

int array[5];
int length = array.length;

となります。

二次元配列

次に、二次元配列について見てみます。 C言語では

int array[2][3];

Javaでは

int[][] array = new int[2][3];

メモリ上はこうなります。 f:id:riko111:20200313115934p:plain

宣言と同時に初期化する場合

int array[][3] ={{10,20,30},{40,50,60}};

Javaでは

int[][] array = {{10,20,30},{40,50,60}};

となって、C言語で要素数を省略できるのは1次元目のみ、Javaではどちらも省略可となります。もちろん、省略しなくても良いです。

メモリ上はこうなります。 f:id:riko111:20200313115930p:plain

また、Javaでは

int[][] array;
array = new int[2][];
array[0] = new int[]{10,20,30};
array[1] = new int[] {40,50,60};

という風に書くことが可能で、

int[][] array;
array = new int[2][];
array[0] = new int[3];
array[1] = new int[2];

というように2次元目を違う要素数にすることが可能です。C言語では2次元目の要素数は全部同じでないといけません。

C言語でもJavaでも、次元を増やしていくことが可能ですが、

という違いがあります。

また、要素数を調べる場合、 C言語では

int array[2][3];
int length = sizeof(array)/sizeof(int);

Javaでは

int array[2][3];
int length = array.length;

となりますが、このとき、lengthに格納される値は

になります。これも、図を見てそれぞれの言語のarrayが表すメモリを見ていただければと思います。

こんなふうにC言語Javaでは配列が違うので、注意しましょう。

【Java】文字列比較に==演算子を使ってはいけない理由

研修のときに、口を酸っぱくして説明するんだけどみんな忘れちゃうやつ。

String型は参照型である

というのはどういうことかというと、

String str = "ABC";

と宣言したとき、メモリ上は、 f:id:riko111:20200312185229p:plain

となるのだけれど(イメージです。実際のメモリ配置を表してはいません)、これが例えば

public class Test {
    public static void main(String[] args){
        String str = "ABC";
        if(str == args[0]){
            System.out.println("同じ文字列です");
        } else {
            System.out.println("違う文字列です");
        }
    }
}

というコードのとき、コンパイルして実行したら、

>java Test ABC
違う文字列です

となる。これはメモリ上、 f:id:riko111:20200312185232p:plain

こういう状態で、●と□を比較しているので、等しくないと判断される。

public class Test {
    public static void main(String[] args){
        String str = "ABC";
        if(str.equals(args[0])){
            System.out.println("同じ文字列です");
        } else {
            System.out.println("違う文字列です");
        }
    }
}

と記述すれば、strが参照している文字列と、args[0]が参照している文字列の比較に鳴るので、等しいと判断される。

メモリ管理のやっかいなところ

で、問題は、

public class Test {
    public static void main(String[] args){
        String str1 = "ABC";
        String str2 = "ABC";
        if(str == str2){
            System.out.println("同じ文字列です");
        } else {
            System.out.println("違う文字列です");
        }
    }
}

と書いたら、等しいと判断されること。

これはなぜかというと、

  1. String型はクラスで定義された型なので、正確には
String str1 = new String("ABC");

と書くべきである。 でもStringはとってもよく使うので例外的に、

String str1 = "ABC";

と書ける。

2.ただし、省略形の書き方は、明示的なオブジェクトの生成を指定していないので、

String str1 = "ABC";
String str2 = "ABC";

と書くと、str1はオブジェクト生成が行われるが、str2では先程生成したオブジェクトをそのまま参照する。 つまり、メモリ上は f:id:riko111:20200312190359p:plain

になる。 これはJVMがそういうふうにメモリ管理することにしてるので。

なので最後のコード書いて、なーーんだ==で文字列比較してちゃんと出来るじゃ~んってならないでね。 そして、C++C#だと、==で文字列比較できるのにー、っていう人、それはC++C#には演算子オーバーロードという機能があって、Javaにはないからです…

Pythonエンジニア認定試験に合格しました

今月に入ってから勉強始めたPythonの試験を昨日受けてきました。

f:id:riko111:20200315100638j:plain

試験用の公式テキスト、「Pythonチュートリアル」を買って、

Pythonチュートリアル 第3版

Pythonチュートリアル 第3版

  • 作者:Guido van Rossum
  • 発売日: 2016/03/24
  • メディア: 単行本(ソフトカバー)

全部終わってないけど基本的なところはまあ押さえられたかなーって思ってやってみたので得点0の分野がありますが(笑)、無事に受かりました。

他の言語経験者なら簡単にマスターできると思います。便利で楽しい言語だなと思いました。

プロフィール

プログラミング

もともと、ものを作ることが好きなのに壊滅的に不器用、という子供でした。絵を書いたり手芸をしたり工作をしたり。好きなのに不器用。まともなクオリティに持っていこうとすると人の3倍くらい時間がかかる。

そんな私が高校生の時にプログラミングに出会いました。

不器用さ関係なく物が作れる!!!

っていう感動は、私ほど不器用でないと理解していただけないと思います。

そんなわけで、大学で情報処理工学科に進学。

大学

地方の私大の情報処理工学科。入学したのが90年代頭。100人超えの同級生、女子は私含め3人。

時代が時代だけに、大学でやったのはFortranPascalC言語。割と不真面目な大学生なので、コードは出来る人のコピペ(笑) そんな中、私は自分の特技に気づきます。

  • どんなソフトでもわりとすぐ使えるようになる
  • OSの違い、ソフトの違いが気にならない

まあ、今でこそOSといえばWinかMacLinux、ですけど、当時はNECIBM互換機、SharpSonyは自社OS、Macは超高級品、大学はUNIXとかって時代。そこで同級生とかいろんな研究室とかのマシンをどんどん触ってたら、周りのみんなは使い慣れたものじゃないとやなんだなー、自分はそうでもないなー、となったわけです。

卒業研究では、研究室に受け継がれてきたC言語で書かれたレンダリングソフトに、テクスチャマッピングの機能を追加。実はコードの半分は当時の彼氏が書いた。でも、彼が書いた部分を読んだら、初めてC言語が理解できました。

そして、先輩たちは割とバブルな人たちだけど、ちょうど就職難が始まっていたロストジェネレーション世代。大学のコネでプログラミング関係ないとこに就職してしまう私がいました。

会社員

最初の会社は女子はお茶くみと電話番、本業が何であろうと必ずそれをこなすもの。みんなのコーヒーの好みを覚える、昭和なオフィス。1年で辞めました。

辞めたときには次を決めていて、小さいけれど自社で開発をしている工業電子機器の会社。おりしものPCブームでパソコン教室を始めるということで、C言語の組み込みプログラマー兼PCインストラクターに。

出たばかりのWindows95、無料だけど全然まともな表示が出来ないInternet Explorer2、マウスのダブルクリックだけでも必死な人たち、という毎日でしたが、教える仕事って楽しいなーと思い始めたところへ、1年ほどでパソコン教室は閉めることに。そのままプログラマとして残っても良いよ、と言われたのだけれど、教える仕事を続けたくて辞めさせてもらうことに。そしたら、会社都合の離職票を出してもらえて、すぐに満額の失業手当の給付を受けることが出来ました。

失業手当をもらいながら1ヶ月、教える仕事を探していたら、フルタイムの仕事はなかなかなく、でもいくつか掛け持ちならなんとかやっていけるということも分かり、社会人3年目にして私はフリーランサーとなりました。

フリーランス

教える仕事は、

  • 街の小さなパソコン教室でWindows入門やOffice一通り
  • 家電量販店のPC購入者向け教室でやっぱりWindows入門やOffice関連
  • IT系専門学校で上記系+Mac入門、Adobe

あと、小さなプリントショップから単発でDTP用データ(PagemakerQuarkXPress使用)作成とか。

大学時代に気づいた自分の特技を遺憾なく発揮して、Windowsの仕事もMacの仕事もしてました。

2000年に、夫(あ、フリーランスになるちょっと前に結婚してました。卒研のコード半分書いてくれた人)の就職に伴い関東へ移住。

そしたら、家電量販店のお仕事で登録していた派遣会社から、新入社員向け研修のプログラミングの講師の仕事が紹介されました。

そこからは、技術系講師の仕事をするようになって、Javaを独学で覚え、UMLを学び、気づいたら設計技法まで講義をするようになっていました。

久々の会社員

楽しく技術系講師をしているといくつか壁が出てきます

  • 現場を離れて久しいので今の現場がわからない
  • 基礎的なことが多くて技術的な面で頭打ちになってる気がする
  • ミドルウェアなんかにめっきり疎い

というわけで、2006年に一念発起して就活。色々苦労しましたが最終的には複数社内定を頂いて、自社開発のベンチャーにWebエンジニアとして就職。 10年近くフリーランスやって実は勤め人向いてないんじゃないかと思ってたけど、チームに恵まれて、むちゃくちゃ楽しかった。デスマとかもあったけど、時間の融通も利いたし、有給休暇って素晴らしいなと思ったし。

仕事ではSeaserMayaaを覚えたのが楽しかった。Androidアプリも作れるように。

そんな楽しい会社、入社当初は30人クラスだったのが100人クラスになろうとしているうちにだんだん傾いてきて、東日本大震災の数カ月後、私のいたプロジェクトがまるっと他会社に売られることに。でも、私だけ会社に残れと。

フリーランスに逆戻り

すったもんだの末、私は会社をやめてフリーランスに戻り、しばらくは元いたプロジェクトの仕事を一緒にしてました。辞めた会社は今は、名前だけはそのままですが中身や製品は全く違う会社になっています。プロジェクト仲間とは、今でも個人的な付き合いがあったり、仕事請けたりしてます。

その後、フリーに戻ったのが以前のフリー時代の仕事の人に知られたり、色々なんだかんだあって、今はエンジニア兼講師を名乗っています。

エンジニアとしてはWebアプリやスマホアプリ開発。 講師としてはJava、C、C++C#VB .Netを教えています。そのうちPython出来るようになる予定。

そんな感じの、とりとめもないプロフィールでした。