ソフトウェアII 第7回(2025/01/23)
本日のメニュー
- シェルスクリプト入門
- プログラミング言語紹介
本日は課題もないので気楽に聞いてください。終わったら適宜任意の質問タイムにしますので、試験勉強がんばってください。
シェルスクリプト入門
今日はこれまで学んできたC言語から少し離れて、これまで「コンパイル」と「プログラムの実行」を担ってきたターミナルを少ししっかりと使うことを考えてみましょう。
コマンドラインシェル
ターミナルに入力されたユーザから文字列を解釈し、それを適切にOSに伝える役割を果たすのが「コマンドラインシェル」です。直感的にはユーザが入力したコマンドを順次実行していく様子を記述するプログラミング言語とみなすことができます。ターミナルから何らかの作業をしたいという観点に立った時、コマンドラインシェルを使うことは以下の点で有用です。
- ファイルの操作やプログラムの実行を簡単に書くことができる
- すでに存在する複数のプログラムを組み合わせて利用する
例えばファイルをあるディレクトリから別のディレクトリに移すという操作をしたい場合に、C言語でこれをわざわざ記述するのは現実的ではありません。例えばディレクトリAにあるhoge.txt というファイルをディレクトリBに移動したい場合、
#include <stdio.h>
int main(void){
char old[] = "A/hoge.txt";
char new[] = "B/hoge.txt";
rename(old, new);
return 0;
}
というコードをコンパイルして実行すれば確かに要件を満たしますが、コマンドmv
を知っている上で、
mv A/hoge.txt B
とすればより簡単です。Unix系を扱う上では標準とされているコマンドは先人たちの需要に基づいて取り込まれてきたものですので、これらを知ってさっと使えることは非常に価値があります。これらに加えて、コマンドラインシェルにもC言語などと同様に制御構造が存在し、例えば「似たようなことを変数を変えてN回繰り返す」といった処理もコマンドラインシェルで記述することができます。
今日はこのようなUnix環境におけるコマンドラインシェルの中でも、特に現在の多くの環境で標準となっているBash を使ってみましょう。今時はzsh だろとか fish が良いよねとか先祖からの教えでtcshを使うことになっているとかを語れる方は今日は気楽に聞いてください。 Unix系環境を想定しているので、Windowsユーザの場合はWSLやCygwin、msys などを想定しています。Powershell は残念ながら互換性がないので、別扱いです。
コマンド
これまでもソフトウェア1/2を通して基本的なコマンドにはいくつか触れてきたと思います。少し復習しましょう。
-
ls
: ファイル一覧表示 -
pwd
: 現在のディレクトリを表示 -
cd
: ディレクトリ の移動 -
cat
: 引数で与えられたファイルを連結し標準出力へ(1ファイルだと中身の表示) -
mkdir
: ディレクトリ 作成 -
mv
: ファイルの移動/リネーム -
cp
: ファイルのコピー -
rm
: ファイルの削除
上記はおもにファイル自体を取り扱うコマンドでした。
他に頻出のコマンドとしてecho
があります。
-
echo
: 引数の文字列をそのまま標準出力へ
もうちょっとコマンド
基本的なコマンドをいくつかざっくり紹介します。
-
head
: ファイルの先頭から指定行数表示 -
tail
: ファイルの末尾から指定行数表示 -
sed
: ストリームエディタ。よく使うのは文字列置換。 -
nl
: 行頭に行番号を付与 -
find
: 指定条件を満たすファイルを探してくる -
xargs
: 受け取った入力をコマンドライン引数にする -
sort
: 指定列の条件に基づいてファイルの行を並べ替え -
uniq
: ファイル中ユニークな行を取り出してくる
上記は主にファイルを操作したりするコマンドですが、もちろん他にも基本として知っておくべきコマンドは数多く存在します。触っていくうちに慣れていきましょう。
素早くターミナルを操作してみる
ターミナルを操作する際に、矢印だけを使っていないでしょうか。bashで使えるショートカットを使ってみましょう。以下の表ではCtrl
キーとの同時押しをC-x
、Meta
キー(WindowsだとAlt / Macだと esc が標準)との同時押しをM-x
と記載します。
ショートカット | 機能 |
---|---|
C-a | 行頭へ移動 |
C-e | 行末へ移動 |
C-f | 1文字進む |
C-b | 1文字戻る |
M-f | 1単語進む |
M-b | 1単語戻る |
C-l | 現在行を残して画面クリア |
C-k | 行末まで切り取り削除 |
C-u | 行頭まで切り取り削除 |
C-y | 上記で切り取ったものを貼り付ける |
C-r | コマンド履歴のインクリメンタルサーチ |
これらのショートカットとファイル名などのTAB補完を効果的に用いることでタイピング速度はそれほどでなくても、かなり効率的に作業が進められるようになります。
連続する数字を出力する
例えば、整数引数を受け取って、それが3の倍数のときに「 3で割り切れるので、3で割り切れます」と出力する以下のC言語のプログラムがあったとします。
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char **argv){
if (argc != 2){
fprintf(stderr, "usage: %s integer\n", argv[0]);
exit(1);
}
int num = atoi(argv[1]);
if ( num % 3 == 0)
printf("(Shinjiro): %dは 3で割り切れるので、3で割り切れます。\n", num);
return 0;
}
上記のプログラムをコンパイルして、プログラムを実行可能にします。
gcc -o shinjiro shinjiro.c
さてこのプログラムが正しく動きそうか、1から1000 ぐらいまで試したいとします。これまではこのような繰り返しはCのプログラムの方に書いていたかと思います。もしくはターミナルに変数を変えながら1000回Enterを叩くという人もいたかもしれません。しかし、よくあるシチュエーションとして実験用のプログラムを汎用的に作ったのち、それをテストする場合は、変化させるパラメータなどはシェルで制御する方が簡単なケースが多いです。
bashで連続する数字を出力する場合、いくつかの方法がありますが、ここではforループを使う方法を示します。
for i in {1..1000}; do ./shinjiro $i ; done
上記の構文はbash で繰り返しを書く際によく書く構文です。i は変数であり、in 以下の要素を順次代入します。変数名はiに限りません。実際に実行されるのは do から done に囲まれた部分で、for のところでセットされたi を $i という形で参照しています。なお、{1..100}
という書き方はbash において、空白区切りで数字の列を出力するものです。
echo {1..10}
などとするとどのような出力が得られるでしょうか?この{..}
の記述は便利で、例えばaからzまでの系列を得たい場合には
echo {a..z}
とすると空白区切りで出力できます。一つ注意点として、開始・終了の文字や数字と..
の間に空白を入れてはいけません。
スクリプトを書いてみる
シェルスクリプトというものを書いてみましょう。シェルスクリプトは文字通りコマンドラインシェルをベースにしたスクリプト言語です。スクリプトといっても一番最初は、一回の処理で使うコマンドを羅列するだけで立派なシェルスクリプトになります。以下の内容をhelloworld.sh
という名前で保存してみましょう。
#!/bin/bash
# シェルスクリプトでは #以降がコメントになる
echo "Hello, World"
echo "Hello, Exam"
echo "Good bye Software2"
一行目にある#!/bin/bash
はシェバン とよばれ、OSにこのスクリプトはこの言語で実行してねということを指示するおまじないです。Pythonを書いたことのある人は#!/usr/bin/python
といった書き方をしたことがあるかと思います。
最も基本的な実行法はbash
で呼び出すことです。
# bash で 今書いたスクリプトを実行する
bash helloworld.sh
ただ、実際にはスクリプト単独で実行するケースが多いので、一工夫します。まずは現在のファイルのパーミッションを確認してみましょう。ファイルのパーミッションとは、今のユーザがそのファイルに対して何ができるのかの情報です。helloworld.sh があるディレクトリで以下を実行します。
# ls に -l オプションをつけて詳細情報を表示
ls -l
以下のような結果が得られるかと思います。
-rw-r--r-- 1 dsk_saito staff 79 1 19 09:53 helloworld.sh
先頭にあるr
および w
等がファイルに対する権限を表して、このファイルは
- 所有者(最初のブロック)は読み取り
r
と 書き込みw
ができる - 同じグループのユーザ(2番目のブロック)は読み取り
r
のみできる - グループも異なる他のユーザ(3番目のブロック)は読み取り
r
のみできる
この状態ではこのシェルスクリプト単体で実行することができません。
以下のコマンドでスクリプトに実行権限を付与します。
chmod u+x helloworld.sh
ls -l
# -rwxr--r-- 1 dsk_saito staff 79 1 19 09:53 helloworld.sh
このコマンドは所有者(ユーザ: u)に実行権限(x)を付与する(+)という意味になります。
この状態で以下のように実行ができます。
./helloworld.sh
- 上記の手順でhelloworld.sh の写経と実行をしてみましょう。
シェルスクリプトにおける変数
シェルスクリプトにおける変数は基本的に全て文字列を扱います。幸か不幸か型はありません。文字列ですがダブルコーテーションで囲む必要はありません。シェルスクリプトにおける変数の最大の注意点は以下です。
- 変数を代入する際は空白を開けずに=で代入する。$ はつけない
- 変数を使うとき(参照するとき)は$をつける
例をみてみましょう。
#!/bin/bash
teacher=situ
comment="Good afternoon"
echo $comment, ${teacher}
変数参照は$をつける他にも、${} で囲むことも可能です。
計算する
シェルスクリプトにおける変数は基本的に文字列なので、数字も文字列として解釈されます。たとえば以下の例を実行してみましょう
#!/bin/bash
x=10
echo $x
echo $x+2
ただし、数字を扱いたい場合もあるので、その場合は$(()) という変数展開を使います。
#!/bin/bash
x=10
echo $x
echo $((x+2))
$(( )) は内部で演算を行ってくれる便利な変数展開です。これを使う場合は中のx
は$が不要です。なお$(()) 内部は空白に対して寛容です。注意点としてbash の場合は整数演算のみです。zshと呼ばれるbashより高機能なシェル(bashの構文はほぼ使える)では、実数の演算も受け付けます。
変数展開をもう少し詳しく
bashの変数は様々な形で展開することができます。以下に例を示します。一つずつみていきましょう。こちらの変数展開では{} で変数を囲みつつ必要な演算をかきます。
#!/bin/bash
var="ThisSampleisBoring.jpg"
echo ${var}
echo ${#var} # 文字数を出力
echo ${var:0:4} # 0番目から4文字取り出し
echo ${var:12:6} # 12番目から6文字取り出し
echo ${var%.jpg} # 末尾から.jpg を取り除く
echo ${var#This} # 先頭からThis を取り除く
echo ${var%s*} # 末尾からsで始まる任意長の文字列を最短一致で取り除く
echo ${var%%s*} # 末尾からsで始まる任意長の文字列を最長一致で取り除く
echo ${var#*s} # 先頭からsで終わる任意長の文字列を最短一致で取り除く
echo ${var##*s} # 先頭からsで終わる任意長の文字列を最長一致で取り除く
echo ${var/Sample/Lecture} # Sample を Lecture で置換
echo ${var/is/as} # is を asで置換(1回)
echo ${var//is/as} # is を as で置換(全て)
上の変数展開を用いることで、文字列の抽出や置換が容易に実現できます。例えばファイルの拡張子部分を除いて別のファイルを作るなどの場合に用いることができます。
ここまでのシェルスクリプトを写経して実行してみましょう。
コマンドの結果を代入する
コマンドの結果を代入する方法は二つあります。一つは$() で囲む方法です。
#!/bin/bash
# printf コマンドで0埋めで4桁表示した結果をvar に代入
var=$(printf %04d 5)
echo $var
もう一つはバックコーテーション` で囲む方法です。
#!/bin/bash
# printf コマンドで0埋めで4桁表示した結果をvar に代入
var=`printf %04d 5`
echo $var
for ループをもう一度
forループを使うケースはいくつかあります。以下に例を示します。
#!/bin/bash
# 決まった回数(1から10まで)実行
for n in {1..10}; do
echo "Hello, world ($i)"
done
ちょっと便利なコマンドにseq
があります。
seq 1 10 # 1から10まで表示
seq 0 2 10 # 0から10まで2個飛ばしで表示
これを利用してforループを書くと以下のようになります
#!/bin/bash
for i in $(seq 0 2 10); do
echo "Hello, world ($i)"
done
ディレクトリ以下にあるファイルそれぞれに操作をしたい場合をやってみましょう。下準備としてディレクトリ の下に100個ファイルを作ります。各ファイルにはランダムな数字が入るとします。シェルでは環境変数$RANDOM が、毎回異なる乱数を出してくれるのでこれを利用します。
#!/bin/bash
# 0 から99までファイルを作る
# ファイル名は00.txt , 01.txt, ....
for i in $(seq 0 99);do
var=$(printf %02d $i)
echo $RANDOM > $var.txt
done
ディレクトリを見てみると100個ファイルができていることがわかります。
続いてこれらのファイルに、データ0 を追記したいとします。
#!/bin/bash
# * でそのディレクトリ以下のファイル全てを指定する。拡張子で制約することもできる
# >> で追記する
for i in *.txt ; do
echo 0 >> $i
done
最後に拡張子.txt を除いてみましょう。
#!/bin/bash
for i in *.txt ; do
mv -v $i ${i%.txt}
done
なお、一応別の書き方として、C言語っぽいものもあるので紹介します。二重括弧でくくります。
#!/bin/bash
for (( i = 0 ; i < 10 ; i++ )); do
echo $(( i * i ))
done
if 文と演算子
例えば、決められたファイル名を並べて、該当するファイルが存在するときだけls
するようなシチュエーションを考えましょう。シェルスクリプトにもif文による制御が存在します。
#!/bin/bash
for i in {a.txt,b.txt,c.txt};do
if [ -e $i ];then
ls -l $i
fi
done
シェルスクリプトのif 文は非常に空白にうるさいのですが、条件文を空白を開けて [ と ] で囲みます。-e はその名前のファイルが存在するかどうかをチェックする演算子です。他にも以下の表のような演算子があります。
ファイル演算子 | 役割 |
---|---|
-d file | ディレクトリかどうか |
-f file | ファイルかどうか |
-e file | ファイルが存在するかどうか |
-L file | シンボリックリンクかどうか |
-r file | 読み取り可能か |
-w file | 書き込み可能か |
-x file | 実行可能か |
引数を取り出す
シェルスクリプトでは引数は$1、$2 といった形で取り出します。$0 は自身のプログラム名です。$# で引数の個数を取り出せます。
#!/bin/bash
if [ $# != 2 ]; then
echo "usage: $0 arg1 arg2"
exit 1;
fi
echo "0: $0"
echo "1: $1"
echo "2: $2"
ここまでのスクリプトを写経してそれぞれ実行してみましょう
配列
bashでも配列定義が可能です。
#!/bin/bash
ARRAY=(a b c) # () でくくると配列になります
echo ${ARRAY[@]} # 全ての要素を配列として展開
echo ${ARRAY[*]} # 要素を空白区切りで連結したものを展開
echo ${#ARRAY[@]} # 長さ
ARRAY[0]=A #個別代入
echo ${ARRAY[@]}
ARRAY+=(d) # 末尾に追加...括弧が必須です
echo ${ARRAY[@]}
echo ${ARRAY[@]:1:2} # 部分配列... みたいなのも可能
# seqのコマンド実行結果を配列に格納
ARRAY2=( `seq 1 2 10` )
# for文操作
for i in ${ARRAY[@]}; do
echo $i
done
# 別の書き方
for (( i = 0 ; i < ${#ARRAY[@]} ; i++)); do
echo ${ARRAY[$i]}
done
なお、zshはbash互換が基本なのですが、配列のインデックスがなぜか1始まりなので、ちょっと(慣れている人は逆にかなり)注意が必要です。
プロセス置換
コマンドの実行結果を一時ファイルを作成せずに、ファイルのように扱うテクニックです。読み込み用と書き込み用があります。 パイプに近いですが、かなり柔軟な処理ができるのと、個々のプロセスが並列で走るので並列化が可能です。
#!/bin/bash
# プロセス置換を使わない場合
# file1 file2 は最終的にはいらない一時ファイル
echo "1 2 3" > file1
echo "daaaa" > file2
cat file1 file2 > file3
rm file1 file2
# プロセス置換を用いると
cat <(echo "1 2 3") <(echo "daaaa") > file3
まとめ
シェルスクリプトの機能をかなりざっくり説明しました。シェルスクリプトの基本機能の範囲でC言語 / Pythonで書くには複雑になることを場合によっては極少量の記述で実現可能になります(いちいちPython書くな的なシチュエーションですね)。またUNIXには先人たちの所産であるコマンド群が存在するので、それらと組み合わせることで作業の効率化を実現できます。
一方、実行速度はあくまでコマンドを一つずつ実行するのと同様ですので、お世辞にもものすごく速いとはいえません。ファイル操作等であっても本当に速さが要求される場合は、C言語で専用の処理を書く必要性もありますが、普段使いでシェルスクリプトを使いこなすことで、大幅な効率化が実現できます。
今回紹介しなかった機能として
- ファイルリダイレクト・パイプの詳細
- プロセスのファアグラウンド・バックグラウンド処理
などがあります。興味がある人はキーワードをもとにぜひ春休みの期間に少しターミナルに慣れ親しみつつ進めるとよいと思います。
プログラミング言語紹介
ここでは、いくつかのプログラミング言語をごくごく簡単に紹介していきます。キーワードをヒントに次に学ぶ参考にしてください。後半につれ、如実にバテていくため、必要な部分は講義後追記します。以下部分的に常体記述になります。
言語の動向
プログラミング言語の動向等を知る上で、StackoverflowのDeveloper Survery をみると技術動向を確認できる。例えば言語に関するアンケート では言語のシェアの情報がざっくり知れる。今日紹介しないものでもメジャーなものがいくつもある。
アセンブリ
CPUに与える機械語プログラムは純粋なビット列だが、さすがにそのままでは人間が直感的に理解するのは難しいため、ビット列に対応する文字列命令で記述したもの。C言語よりもさらに機械語に近いと考えると良い(低水準 と言われる)。
C言語から当該CPUのアセンブリを出力したい場合は以下のようにコンパイルする。
// helloworld.c
#include <stdio.h>
int main(){
printf("Hello, World\n");
return 0;
}
gcc -S helloworld.c
-S
オプションをつけることで、このCPUのアセンブリが出力される。M1 mac だと以下のような感じ。
.section __TEXT,__text,regular,pure_instructions
.build_version macos, 12, 0 sdk_version 13, 1
.globl _main ; -- Begin function main
.p2align 2
_main: ; @main
.cfi_startproc
; %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] ; 16-byte Folded Spill
add x29, sp, #16
.cfi_def_cfa w29, 16
.cfi_offset w30, -8
.cfi_offset w29, -16
mov w8, #0
str w8, [sp, #8] ; 4-byte Folded Spill
stur wzr, [x29, #-4]
adrp x0, l_.str@PAGE
add x0, x0, l_.str@PAGEOFF
bl _printf
ldr w0, [sp, #8] ; 4-byte Folded Reload
ldp x29, x30, [sp, #16] ; 16-byte Folded Reload
add sp, sp, #32
ret
.cfi_endproc
; -- End function
.section __TEXT,__cstring,cstring_literals
l_.str: ; @.str
.asciz "Hello, World\n"
.subsections_via_symbols
これをオブジェクトファイルにするには
as helloworld.s
とすると helloworld.o が出力されるので、最後にリンクをする。
用途としては、コンパイラ自体の開発や、コードの高速化における解析などが挙げられる。CPU自体の研究をする場合にも触れる可能性が大きい。 なお、C言語でも、一部をアセンブリで記述する方法があり、予約後 asm
を使ってCのソースコードに直接アセンブリを記述できる機能がある(インラインアセンブラ)と呼ばれる。
Fortran
C言語の大先輩。世界最初の高水準言語として1950年代に登場。FORTRAN と書くとFOTRAN 77 と呼ばれる70年代の仕様、Fortran と書くと、90年代以降の仕様を指す。Fortran 90以降は比較的柔軟にかけるようになった。数式記述が直感的に数値計算分野ではいまだに用いられる。行列計算のライブラリなどはC言語で使われるものでも、Fortran で書かれたものがある(BLASやLAPACKなど)。言語レベルで並列計算を書きやすいのもC言語に比べると数値計算に強い要因(C言語の場合pthread等のライブラリによるサポートが必要)。
余談ですがこの言語、配列のインデックスが1スタートなので、私の場合「1からプログラミングを教えてください」と言われた場合、こちら系の言語を教えるのかなと思ったりします。「0からプログラミングを教えてください」と言われたらひとまずC言語を教えます。
! test.f90
! コメントは! で
program main
integer :: a = 10
real :: d = 3.34
real v(5)
print *, a
print *, d
do i=1,5
v(i) = i
end do
do i=1,5
print *,v(i)
end do
end program main
コンパイラはgfortran
などがメジャーです。Macの人はbrewで、Linux環境の人は各自のパッケージマネージャ(apt, yum, dnf, pacman, port, )
C++
C言語にオブジェクト指向の概念を入れたもの。というのが基本的な説明ですが、言語仕様の拡張により柔軟な記述力とC言語由来の高速性を兼ね備えています。以下は、入門書によくあるiostream
を使ったhello worldと、何となくC++っぽい要素を入れたものです。
#include <iostream> // .h が要らない
#include <cstdio> // c*** で c言語標準もほぼ使える
int main(){
// std は名前空間と呼ばれる
std::cout << "Hello, world" << std::endl;
// cstdio を読んでいるので、もちろん以下も可能
printf("Hello, world\n");
// c++ では 代入以外に、初期化子という記法が使える
int i = 10;
int j(10);
std::cout << i << " " << j << std::endl;
return 0;
}
コンパイラはg++
です。
g++ helloworld.cpp
以下、段々簡潔に....
Java
Cの後にできた、オブジェクト指向のプログラミング言語。JVMという仮想マシンで動く中間コードを生成し、実行マシンへの依存が少ないため30億のデバイスで動く(客先では動かないかもしれない)。「30億のデバイスで動くのに客先では動かない」とか「お前にSunは救えるか」など、インタネット的なネタには事欠かないが、基本的に良い言語。CやC++に比べると、ポインタを直接触らせないなど、安全性もかなり配慮されている。
// Testクラスのmainメソッドとして実行プログラムを書く。
class Test{
public static void main(String[] args){
System.out.println("Hello,World");
}
}
Perl
スクリプト言語の古参と言えばこれ。100人いれば100通りの書き方があると言われるあたり、Pythonとは根本的に思想が異なる。文字列操作にかなり強く、2024年現在、40代から60代の人は実務で世話になっているケースも多い。Unixシステムの基本プログラムが依存している場合も多く、多くの場合インストール作業なしで標準で使える環境が多い。
#!/usr/bin/perl
# コメントは#で、変数は必ず$から始まる。セミコロンは必要
$a = 8;
$b = 3;
$str = "abcdefg";
print "(a b) = ($a $b)\n"; #フォーマットなしで変数展開を直接かける
$str =~ s/a/c/g; # aを全てcに置換。このような簡潔な文字列処理がある
print $str,"\n";
上のスクリプトをtest.pl で保存して
perl test.pl
で実行できる。
Ruby
まつもとゆきひろ氏開発のスクリプト言語。齋藤の感覚では島根といえば鷹の爪とRuby と思っている。Perlからの影響を受けつつ、簡潔な文法で人気も高い。Ruby on Rails など、Web系での実績も多い。機械学習系には若干弱いか。現在はruby3系が主力。
システム標準で入っていることも多いが、最新版を入れたい場合などはRubyのページ にアクセスするとよい。
Python
現在、かなり広く用いられているスクリプト言語。強力なライブラリ群が開発されており、人工知能ブームも相まって、かなり使用者が多い。速度面では遅いが、コンパイラ言語でライブラリ部分を組み込むなどでカバーしている。インストールパターンは多岐に渡るが、まずは本家のページを見ましょう。齋藤個人としてはネットの記事に安直に踊らされて、何もわからないのにpyenvやanacondaでpythonを導入... という愚行はお勧めしない。
コンパイラ言語
ここからはいくつかの視点をベースにもう少し言語を紹介していきます。まずはコンパイラ言語。これはC言語同様、ソースコードをコンパイルしてバイナリを生成するタイプです。私も全ての言語に十分に精通しているわけではないので、
Go
Googleが2009年に開発したコンパイラ言語。静的型づけ。並列性に優れている。本家ページ から比較的容易にコンパイラを導入可能。
D
C言語をベースにしつつ、発展した言語。オブジェクト指向的な書き方の他、関数型プログラミング(後述のHaskellなど)もできるなど、マルチパラダイムな言語。本家ページ 。
Rust
Mozillaが2010年に開発した言語。Stack Overflowで「最も愛されているプログラミング言語」にここ8年ほど選ばれるなど、非常に注目度が高い。安全性に関しては特に評価が高く、システム用のコードを書く際にC/C++を置き換える最有力の言語となってきている。Linuxカーネルのモジュール開発も近年Rustによるものが増えてきている。本家ページ 。
Web系
ウェブ関係で使用することの多い言語をまとめます。
PHP
HTML内部に埋め込んで用いる言語。元々Webページに動的要素を導入する際は、Perl/Python/Rubyなどのスクリプト言語をCGIとして用いることが多かったが、PHPはHTMLとの親和性が高く、現在幅広く使われている。 本家ページ。
Javascript
現在のウェブを支える中核技術といっても過言ではない。ウェブにおける動的処理への使用が多かったが、近年ではNode.js、React, Vue.js などの様々なライブラリにより一つのプラットフォームを形成するに至っている。ちなみにVS CodeはElectronと呼ばれる技術で、Javascriptなしに語ることはできない。Javaとは「インド」と「インドネシア」以上に違う。なお、Googleのアプリ(Google Doc, Google Spreadsheet, Google Formなど)を高機能にするGoogle Apps Script (GAS)という機能はJavascriptを基本としている。環境としてはブラウザさえあればよい。また上記のGASでも色々試せる。
数値計算系
数値計算への使用がかなりやりやすい環境。スクリプト言語であることが多いが、JITなど実行時にコンパイルする機能を備えているものも近年は多く、ちょっとしたアルゴリズムの確認から本格的なシステム開発まで可能になっている。
MATLAB
Mathworks開発の数値計算統合環境。各CPUに最適化された数値計算ライブラリを内蔵し、高速なコードを簡単にかける。電気系関係では制御系の研究などではシェアが大きい印象。デメリットは有料の環境というところだが(通称Matworks税)、東大生であるうちはキャンパスライセンスで費用負担なしで利用できるので、試してみるとよい。
GNU Octave
いわゆるMATLABクローンの一つ。MATLABに近い機能をオープンソースで提供することを目的に開発されている。多くのMATLABコードが改変なしか少ない改変で動作する。詳しくは本家ページ に。
Julia
近年注目されている数値計算言語。MATLAB/Octave系統のスクリプト言語的な容易さと、C言語並みの高速性を目指している。パッケージ管理システムも充実しており、今後のシェア拡大にも注目である。本家ページ。
R
統計処理に強い言語。少し変わった構文だが根強い人気がある。本家ページ。
OS特化系
かなり特定のOSでの使用を意識した言語を少し紹介する。
C#
Windows系開発を想定した、マイクロソフト開発のコンパイラ言語。C/C++からの派生という位置付けだが、かなりJavaの要素が入っている印象。Linux/Mac系統からの開発のハードルがかなり高いのが難点か。
Objective-C
Mac系開発を主導してきた、Apple開発のコンパイラ言語。C言語に、Smalltalkと呼ばれるオブジェクト指向言語の要素を取り入れたC言語の上位互換という位置付け。後述のSwiftが出るまではMac/iPhoneでのアプリケーション開発の主力言語だった。初期では参照カウンタベースのメモリ管理、Objective-C 2.0からはガベージコレクタが導入されて、高級言語感が出ている。C言語の上位互換のため、Linux等でも一応書くことができるが、MacのUI等を触る部分はMac限定になる。Linuxでこの辺りを触りたい場合はGNUstepを導入する。
Swift
2014年に登場したApple系開発言語。発表時の標語はC言語の荷物のないObjective-C .... オープンソースなので、Linuxでも開発は可能。本家ページ。
Kotlin
Android開発の公式言語。Javaやその派生のGroovyなどからの影響が大きい。本家ページ。
変わり種
このまとめ方は失礼かもしれませんが、いくつか変わったものを。プログラミング言語の幅広さを知れるかと思います。
なでしこ
日本語でかけるプログラミング言語のひとつ。変数や制御構造を自然言語的に書くので、なかなか趣深い。本家ページ 。
Haskell
関数型プログラミング言語。上で紹介した言語は手続型だったりオブジェクト指向型だったり多いが、関数型言語は数学的な意味での関数を主軸にしたプログラミング言語で、引数に対する参照透過性を持つ。つまり関数に状態がない。他の言語とは少し感覚が違うので、なかなか手をつけにくいが、興味があればぜひトライしてみるとよい。本家ページ 。
講義内演習
時間があれば、簡単なC言語のプログラムをちょっとずつC++にしていくお話をしようと思います。
アンケート
UTAS上で工学部が出している授業評価アンケートがありますので、そちらに回答をお願いします。成績には一切影響しません。
またソフトウェア2について、別途、より詳細なアンケートをとろうと思います。こちらも成績には一切影響しません。試験で忙しいと思うので、落ち着いた頃にかSlackかUTOLにて連絡します。こちらもぜひ忌憚なくコメントをお願いします。
フリーディスカッション
適当な時間、講義全体に対して自由に質問コメントを受け付けます。