2023年03月26日くいなちゃん


6さいからのプログラミング」第2話では、実際に主要なプログラミング言語のソースコードを見ていきます!

1Hello, world!

第1話では、コンピュータの仕組みや様々なプログラミング言語を解説し、それらのソースコードをコンパイルすることでアプリが作れることを説明しました。 それでは実際に、主要なプログラミング言語のソースコードを見てみましょう。
プログラミング入門者はまず「画面に『Hello, world!』と表示するプログラム」を作る慣わしがありますので、この「Hello, world!」プログラムを作成してみます(図1-1)。
Hello, world!
図1-1: Hello, world!

2JavaScript

まずは、比較的簡単なJavaScriptで「Hello, world!」のプログラムを作成してみます。 ソースコードは図2-1のようになります。
  1. <!DOCTYPE html>
  2. <script>
  3.   document.write("Hello, world!");
  4. </script>
図2-1: hello_world.html
これをテキストエディタで書いて「hello_world.html」という名前で保存します。 作成したファイルをWebブラウザで開くと、「Hello, world!」というテキストがブラウザに表示されていると思います(図2-2)。
JavaScriptの実行結果
図2-2: JavaScriptの実行結果
.html」ファイルは、Webページの一般的な形式です。 JavaScriptのプログラムは、Webページに埋め込む形で動作します。 1行目の<!DOCTYPE html>は、このファイルが現在主流の形式で書かれていることを示しています。
<script>」と「</script>」で囲まれた部分がJavaScriptのプログラムとなり、中に書いた命令が上から順番に実行されます。 「document.write("Hello, world!");」は、「画面に Hello, world! を表示せよ」という命令です。

3C言語

さて、C言語で書いた「Hello, world!」のソースコードは図3-1のようになります。
  1. #include <stdio.h>
  2.  
  3. int main(void)
  4. {
  5.   printf("Hello, world!\n");
  6.   return 0;
  7. }
図3-1: hello_world.c
このソースコードを「hello_world.c」というファイル名で保存して、第1話で紹介したコンパイラを入手した方はコンパイルし、エラーが起こらなければ実行してみてください。 画面に「Hello, world!」が表示されれば成功です(図3-2)。
C言語の実行結果
図3-2: C言語の実行結果
C言語のプログラムを実行すると、「int main(void) {」と「}」で囲んだ中身が上から順番に実行されます。 「printf("Hello, world!\n");」は、「画面に Hello, world! を表示せよ」という命令です。 「return 0;」は、int main(void){~} の中に書くと「アプリの実行を終了せよ」という意味になります。 従ってこのプログラムは、画面に「Hello, world!」を表示して終了するプログラムとなります。 ちなみに「#include <stdio.h>」は、「printf("Hello, world!\n");」の命令を使うときに必要となる設定をソースコードに埋め込みます。

4アセンブリ言語

今のC言語のソースコードをアセンブリ言語で書くと、図4-1のようになります。
  1. .model flat
  2. EXTRN _printf:PROC
  3. .data
  4. msg DB "Hello, world!", 0aH, 00H
  5. .code
  6. _main PROC
  7.   push OFFSET msg
  8.   call _printf
  9.   add esp, 4
  10.   xor eax, eax
  11.   ret
  12. _main ENDP
  13. END
図4-1: hello_world.asm
これはWindowsおよびVisual Studio向けに書かれていますので、他のアセンブラをお使いの場合は少々手直しが必要です。 Visual Studioをお持ちであれば、付属のアセンブラで「ml hello_world.asm /link /defaultlib:msvcrt.lib」のようにアセンブルすると、「hello_world.exe」という機械語のプログラムが出来上がって実行できます。
このプログラムはC言語よりも複雑そうな印象を受けますが、前回お話した通りアセンブリ言語は機械語に近いため、1つ1つの命令はCPUが理解しやすい単純なものです。 ここではC言語と比較しながら簡単に解説したいと思います。
まずこのプログラムを実行すると、「_main PROC」と「_main ENDP」で囲んだ中身が上から順番に実行されていきます。 C言語との対応は、表4-1の通りです。
表4-1: C言語とアセンブリ言語の対応
C言語 アセンブリ言語
int main(void)
{
_main PROC
printf("Hello, world!\n"); push OFFSET msg
call _printf
add esp, 4
return 0; xor eax, eax
ret
} _main ENDP
画面に「Hello, world!!」を表示する部分を詳しく見てみましょう。 「push OFFSET msg」は、「msgのアドレスをスタック領域に入れよ」という命令です。 この「msg」とは4行目で「msg DB "Hello, world!", 0aH, 00H」と定義されていて、これは図4-2のように、「Hello, world!」というテキストをメインメモリ上に格納してそれにmsgと名付ける意味になっています。
push OFFSET msg
図4-2: push OFFSET msg
また「スタック領域に入れよ」の「スタック領域」とは、メインメモリ上に作られた荷物置き場のようなものです。 よって「push OFFSET msg」とは、「Hello, world!」が存在する番地(図ではAC番地)を、どこかにあるスタック領域に格納する命令になります。
「call _printf」は、スタック領域に積まれているアドレスのテキストを画面に表示する命令です。 スタック領域には「Hello, world!」というテキストのアドレスが積まれていましたので、これが画面に表示されることになります(図4-3)。
call _printf
図4-3: call _printf
「add esp, 4」は、スタック領域に積まれたものを降ろす命令です。 積んだままにすると後でスタック領域を使う人が困るので降ろします(図4-4)。
add esp, 4
図4-4: add esp, 4
何となく理解できましたでしょうか。 JavaScriptでは1行で書けたことでも、アセンブリ言語では面倒な手続きを踏む必要があります。 逆に言えばCPUやメインメモリが面倒な仕組みで動いているのを、JavaScriptでは見えないようにしています。 最終的には便利な言語で書けば良いですが、裏で何が行われているかを意識することは効率の良いプログラムを書く上で重要になります。

5その他の言語

その他の言語のソースコードを、最後にいくつか簡単に紹介します。 書き方は違っても、C言語と似た言語が多いです。

5.1Java



Javaのソースコードは図5-1のようになります。 JavaScriptと名前は似ていますが、全くの別言語です。
  1. public class HelloWorld
  2. {
  3.   public static void main(String[] args)
  4.   {
  5.     System.out.println("Hello, world!");
  6.   }
  7. }
図5-1: HelloWorld.java
3行目と6行目で囲まれた部分が上から順に実行され、5行目で画面に「Hello, world!」が表示されます。 C言語と同じ流れです。

5.2C#



C#のソースコードは図5-2のようになります。 Javaによく似ています。
  1. class HelloWorld
  2. {
  3.   static void Main(string[] args)
  4.   {
  5.     System.Console.WriteLine("Hello, world!");
  6.   }
  7. }
図5-2: HelloWorld.cs
プログラムの動作もJavaと同様です。

5.3PHP



PHPのソースコードは図5-3のようになります。
  1. <!DOCTYPE html>
  2. <?php
  3.   echo "Hello, world!";
  4. ?>
図5-3: hello_world.php
PHPは、JavaScriptのようにWebページに埋め込む形で書く言語です。 ただし、Webブラウザ側ではなくサーバ側で動作しますので、プログラムを実行させるにはサーバ等の環境が必要です。 「<?php」と「?>」で囲んだ部分がPHPのプログラムとなり、3行目で画面に表示しています。

5.4Haskell



最後に関数型言語であるHaskellを紹介します。 図5-4のようになります。
  1. main = putStrLn "Hello, world!"
図5-4: hello_world.hs
関数型言語は、C言語などとは異なる発想の言語です。 C言語などでは「ああせよこうせよ」と書いた命令が上から順番に実行されていきましたが、関数型言語では「AはBである」のような「宣言」を書き連ねてプログラムを書いていきます(図5-5)。

C言語などのイメージ:

  1. 鍋に水を入れます。
  2. 卵を入れます。
  3. 加熱します。
  4. 沸騰して5分後、火を止めます。
  5. 冷水で冷やします。
  6. ゆで卵の完成です。

関数型言語のイメージ:

  • ゆで卵とは、特殊な条件で卵をゆで、その後冷水で冷やしたものです。
  • 特殊な条件とは、水の状態からゆでて、沸騰後5分間ゆでることです。
  • ゆでるとは、鍋に入れた水と一緒に加熱し、完了したら火を止めることです。
図5-5: 手続き型と関数型
先ほどのHaskellのソースコードを見ると「putStrLn "Hello, world!"」とありますが、これは「画面に Hello, world! を表示すること」という意味です。 また「main = ...」は「mainとは、...である」を意味します。 よってこのプログラムは「mainとは、画面に Hello, world! を表示することである」という意味になります。 Haskellのプログラムを実行すると「main」が実行される決まりになっているため、結果的に画面には「Hello, world!」が表示されます。
今回は様々なプログラミング言語のソースコードを紹介しました。 画面に「Hello, world!」を表示するだけのプログラムでしたが、この代わりにモンスターの絵を表示すればゲームが作れますし、ボタンを表示すればツール系のアプリが作れます。 Hello, world! のプログラムでは実用的なアプリを作るイメージが湧かないかもしれませんが、少し応用すると何でも作れるようになります。
次回は、今回のお話を掘り下げて、00~FFの16進数しか格納できないはずのメインメモリが、どうやって「Hello, world!」などの文字や巨大な数や小数などを扱っているのかを解説します。 メインメモリの仕組みを理解しておけば、その後の学習がとても容易になるはずです!
1679822314jaf