Home English

Kuina-chan

くいなちゃんOct 17, 2017


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

Hello World!!

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

JavaScript

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

C言語

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

アセンブリ言語

今のC言語のソースコードをアセンブリ言語で書くと、hello_world.asmのようになります。
.model flat
EXTRN _printf:PROC
.data
msg DB "Hello, world!", 0aH, 00H
.code
_main PROC
  push OFFSET msg
  call _printf
  add esp, 4
  xor eax, eax
  ret
_main ENDP
END
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言語の「int main(void) {」と「}」に相当します。 C言語の「printf("Hello, world!\n");」に当たるのは7~9行目で、「return 0;」に当たるのは10~11行目です(C言語とアセンブリ言語の対応)。
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!!」を表示する部分である7~9行目を詳しく見てみましょう。 7行目の「push OFFSET msg」は、「msgのアドレスをスタック領域に入れよ」という命令です。 この「msg」は4行目で「msg DB "Hello, world!", 0aH, 00H」と定義されていて、これはpush OFFSET msgのように、「Hello, world!」というテキストをメインメモリ上のどこかに格納しそれにmsgと名付けるという意味になっています。
push OFFSET msg
push OFFSET msg
また「スタック領域に入れよ」の「スタック領域」とは、メインメモリ上に作られた荷物置き場のようなものです。 よって「push OFFSET msg」とは、「Hello, world!」が存在する番地(図ではAC番地)を、どこかにあるスタック領域に格納する命令になります。
8行目の「call _printf」は、スタック領域に積まれているアドレスのテキストを画面に表示する命令です。 スタック領域には「Hello, world!」というテキストのアドレスが積まれていましたので、これが画面に表示されることになります(call _printf)。
call _printf
call _printf
9行目の「add esp, 4」は、スタック領域に積まれたものを降ろす命令です。 積んだままにすると後でスタック領域を使う人が困るので降ろします(add esp, 4)。
add esp, 4
add esp, 4
何となく理解できましたでしょうか。 JavaScriptでは1行で書けたことでも、アセンブリ言語では面倒な手続きを踏む必要があります。 逆に言えばCPUやメインメモリが面倒な仕組みで動いているのを、JavaScriptでは見えないようにしています。 最終的には便利な言語で書けば良いですが、裏で何が行われているかを意識することは効率の良いプログラムを書く上で重要になります。

その他の言語

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

Java

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

C#

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

PHP

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

Haskell

最後に関数型言語であるHaskellを紹介します。 hello_world.hsのようになります。
main = putStrLn "Hello, world!"
hello_world.hs
関数型言語は、C言語などとは異なる発想の言語です。 C言語などでは「ああせよこうせよ」と書いた命令が上から順番に実行されていきましたが、関数型言語では「AはBである」のような「宣言」を書き連ねてプログラムを書いていきます(手続き型と関数型)。
C言語などのイメージ:
  1. 鍋に水を入れます。
  2. 卵を入れます。
  3. 加熱します。
  4. 沸騰して5分後、火を止めます。
  5. 冷水で冷やします。
  6. ゆで卵の完成です。

関数型言語のイメージ:
  • ゆで卵とは、特殊な条件で卵をゆで、その後冷水で冷やしたものです。
  • 特殊な条件とは、水の状態からゆでて、沸騰後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!」などの文字や巨大な数や小数などを扱っているのかを解説します。 メインメモリの仕組みを理解しておけば、その後の学習がとても容易になるはずです。
1508205015ja