未経験者向け、わかりにくいプログラミング講座


できるだけわかりにくく説明していきます。

第一回:エクセルの式

エクセルの表の中には式も書けます。
式を書けば、もう立派なプログラムです。
では次のように書いてみましょう。

=A1+B1

これは、この式を書いたセルに、セルA1とセルB1の値を足した値を表示せよというプログラムです。
簡単ですね?

第二回:エクセルの関数を使う

エクセルの表の中に次のように書いてみましょう。

=SUM(A1:A3)

これは、A1〜A3までの値を全て足した結果を計算せよ。
という関数です。

簡単ですね。

第三回:エクセルでの関数の作り方

関数の使い方がわかったところで、次は関数の作り方です。

まず、ツール>マクロ>VisualBasicEditorをクリックします。

真っ白なエディターが出てきますね。

そこに、

Function 現実(妄想 As Integer) As Integer
現実 = 妄想 * 2
End Function

と書いてみましょう。
これで関数の出来上がりです。

では出来上がった関数を使ってみましょう。
エクセルシートのセルの中に

=現実(A1)

と書いてみます。
すると現実が表示されますね?

以上でエクセルの関数の作り方の説明は終わりです。

第四回:C言語

まず一番簡単な「こんにちは世界」の作り方です。

#include <stdio.h>
void main(void)
{
printf("こんにちは世界\n");
}

C言語のコードはこれだけです。これをコンパイルし、リンクするとプログラムは完成です。
実行すると黒い画面の中に白い文字で

こんにちは世界

と表示されます。

では解説です。

#include <stdio.h>
これは<stdio.h>というヘッダーファイルをインクルードしろという命令です。

インクルードとはプログラムの中に取り込むことです。
ヘッダーファイルとは関数や定数の定義などを書いた定義ファイルです。
<>これは自分で作成したファイルではなく、既に用意された標準的なヘッダーファイルという意味です。
stdio.hはstandard input output の略で標準的な入出力関数が定義してあります。

void main(void)
最初のvoidは戻り値なしという意味です。
戻り値とは関数が返す値のことです。
C言語のプログラムはまずはじめにmainという名前で作ります。
mainが最初に実行され、mainから様々な関数を呼びます。
()この括弧の中に引数の定義を書きます。
引数はパラメータとも呼ばれています。
中学校のときに習ったF(x)と同じです。
F(x)の場合はxがパラメータです。
()の中のvoidは引数なしという意味です。

{
}
関数の中身は{}で囲みます。

printf("こんにちは世界\n");
printfはprint formatの略で、指定したフォーマットで表示します。
printfは
printf("%d", ...);(%dは整数を表示しろという書式)
というように""で囲まれた中に書式を書き、2つ目以降のパラメータに表示したい値を示す変数などを書くのですが、この書式に文字列を指定すると指定した文字列がそのまま表示されます。
\nは改行するという意味です。
;は命令の終わりを意味します。

コンパイルとはC言語のコードをマシン語のコードに変換して中間ファイルを生成することです。
リンクとは生成されたマシン語の中間ファイルをつなぎ合わせ実行ファイルを生成することです。

これらを行うプログラムをそれぞれ、コンパイラ、リンカと呼びます。

ではコンパイラ、リンカはどうやって手に入れるのでしょうか?

UNIXとMacには標準で装備されてます。

しかし、Windowsには標準装備されてません。
通常Windowsアプリケーションを作るときはVC++を使用しますが、VC++は高額なソフトなのでお金をかけたくない人には向きません。
VC++のアカデミーパックなら安く手に入りますが、学生向けです。

本格的なアプリケーションを作るのでなければ、無料でC言語のコンパイラを入手する方法もあります。

cygwinというフリーソフトです。
http://www.cygwin.com/

このcygwinはWindows上でUNIXのコマンドを実行できる優れもので、C言語のコンパイルも出来ます。

以上で「こんにちは世界」の説明は終わりです。

ものすごく簡単なことを説明しようと思ったのですが、意外と複雑なことをしているのだと気付き驚いてます。


第五回:制御コード

制御コードは言語によって違いがありますが、意味は大体同じです。
ここではC言語で説明します。

まず制御コードの種類をあげます。
;
{
}
if
else
switch
case
break
while
for
return

他にもありますが、よく使うのはこんなところです。
では、意味を説明しましょう。

;
これは行の終わりを意味します。
a=b+c;b=c+d;
というように1行に続けて書いても、コンパイラは;の有無で行の終わりとみなします。

{
これはプログラムブロックの開始を意味します。

}
これはプログラムブロックの終了を意味します。

if
else
switch
case
これらは条件分岐をするための命令です。

while
for
これらはループをするための命令です。

break
これはswitch,while,forの処理を抜けるときに使います。

return
これは関数を抜けるときに使います。



if(a == 1){
// a が 1 のときここに書いた命令が実行されます
} else {
// a が 1 以外のときここに書いた命令が実行されます
}

switch(a){
case 1:
// a が 1 のときここに書いた命令が実行されます
break;
case 2:
// a が 2 のときここに書いた命令が実行されます
break;
case 3:
// a が 3 のときここに書いた命令が実行されます
break;
default:
// a が 1,2,3 以外のときここに書いた命令が実行されます
break;
}

while(a > 1){
// a が 1 より大きい間はここに書いた処理が繰り返し実行されます。
}

for(i=0; i<10; i++){
// まず i を 0 に初期化し
// i が 10 より小さいか判定して
// {}内の処理を実行します。
// 次に i に 1 を足します。
// i が 10 より小さい間、繰り返し実行します。
}

以上で制御コードの説明は終わりです。


第六回:変数

変数とは、数学で習ったxとかyのことです。

int x = 1;
int y = 3;
int a = x + y;

というように使います。
上の例だと a には 4 が入ります。
簡単ですね。

変数には、型というものがあります。
int型は整数です。
char型は8Bit整数です。
short型は16Bit整数です。
long型は32Bit整数です。
int型はコンピュータによって変わります。32Bitパソコンでは32Bit整数です。

float型は32Bit小数です。
double型は64Bit小数です。

なんだかめんどくさくなってきました。
変数の説明はこれで終わりにします。


第7回:2値画像から線を抽出するプログラム

曲線、斜め線は難しいので、横線と縦線だけです。

CRect lineX1[1000], lineXRect[100], lineY1[1000], lineYRect[100];
int lineIndex1 = 0, lineIndexRectX = 0, lineIndexRectY = 0, lx=0, ly=0;
for(int i=0; i < 1000; i++){
lineX1[i].left = 0;
lineX1[i].top = 0;
lineX1[i].right = 0;
lineX1[i].bottom = 0;
lineY1[i].left = 0;
lineY1[i].top = 0;
lineY1[i].right = 0;
lineY1[i].bottom = 0;
}
for(i=0; i < 100; i++){
lineXRect[i].left = 0;
lineXRect[i].top = 0;
lineXRect[i].right = 0;
lineXRect[i].bottom = 0;
lineYRect[i].left = 0;
lineYRect[i].top = 0;
lineYRect[i].right = 0;
lineYRect[i].bottom = 0;
}
for(y=0; y < h; y++){
for(int x=0; x < w; x++){
if(m_Pixel[x][y] == 1){
lineX1[lineIndex1].left = x;
lineX1[lineIndex1].top = y;
lineX1[lineIndex1].bottom = y;
for(x=lineX1[lineIndex1].left + 1; x < w; x++){
if(m_Pixel[x][y] == 1){
lineX1[lineIndex1].right = x;
} else {
break;
}
}
if(lineX1[lineIndex1].right - lineX1[lineIndex1].left >= m_nLength){
lineIndex1++;
}
}
}
}
for(i = 0; i <= lineIndex1; i++){
if(lineX1[i].left == 0 && lineX1[i].right == 0){
continue;
}

lineXRect[lineIndexRectX] = lineX1[i];
int j = i + 1;
while(lineXRect[lineIndexRectX].bottom + 1 >= lineX1[j].bottom){
if(lineX1[j].left == 0 && lineX1[j].right == 0){
break;
}
if(lineXRect[lineIndexRectX].bottom >= lineX1[j].bottom){
j++;
continue;
}
if(lineXRect[lineIndexRectX].bottom + 1 == lineX1[j].bottom){
if(lineXRect[lineIndexRectX].right - lineX1[j].left >= m_nLength &&
lineX1[j].right - lineXRect[lineIndexRectX].left >= m_nLength){
lineXRect[lineIndexRectX].bottom++;
if(lineX1[j].left > lineXRect[lineIndexRectX].left){
lineXRect[lineIndexRectX].left = lineX1[j].left;
}
if(lineX1[j].right < lineXRect[lineIndexRectX].right){
lineXRect[lineIndexRectX].right = lineX1[j].right;
}
lineX1[j].left = lineX1[j].right = 0;
}
}
j++;
}
}

lineIndex1 = 0;
for(int x=0; x < w; x++){
for(y=0; y < h; y++){
if(m_Pixel[x][y] == 1){
lineY1[lineIndex1].left = x;
lineY1[lineIndex1].top = y;
lineY1[lineIndex1].right = x;
for(y=lineY1[lineIndex1].top + 1; y < h; y++){
if(m_Pixel[x][y] == 1){
lineY1[lineIndex1].bottom = y;
} else {
break;
}
}
if(lineY1[lineIndex1].bottom - lineY1[lineIndex1].top >= m_nLength){
lineIndex1++;
}
}
}
}
for(i = 0; i <= lineIndex1; i++){
if(lineY1[i].top == 0 && lineY1[i].bottom == 0){
continue;
}

lineYRect[lineIndexRectY] = lineY1[i];
int j = i + 1;
while(lineYRect[lineIndexRectY].right + 1 >= lineY1[j].right){
if(lineY1[j].left == 0 && lineY1[j].right == 0){
break;
}
if(lineYRect[lineIndexRectY].right >= lineY1[j].right){
j++;
continue;
}
if(lineYRect[lineIndexRectY].right + 1 == lineY1[j].right){
if(lineYRect[lineIndexRectY].bottom - lineY1[j].top >= m_nLength &&
lineY1[j].bottom - lineYRect[lineIndexRectY].top >= m_nLength){
lineYRect[lineIndexRectY].right++;
if(lineY1[j].top > lineYRect[lineIndexRectY].top){
lineYRect[lineIndexRectY].top = lineY1[j].top;
}
if(lineY1[j].bottom < lineYRect[lineIndexRectY].bottom){
lineYRect[lineIndexRectY].bottom = lineY1[j].bottom;
}
lineY1[j].top = lineY1[j].bottom = 0;
}
}
j++;
}
}

では解説します。
まず、幅1ドットの線に分解してます。そして規定の長さ以上のものだけを線とみなし、幅1ドットの線を合体させて、幅を持った線として抽出してます。規定の長さなど持たずに規定の縦横比がある長方形を線とみなすプログラムを作ろうと思ったけど難しかったのでやめました。

次回は、C++の基礎です。