/*
* 20180427-01-QQQQ.c
* 歌詞を出力する
*/
#include <stdio.h>
/*
* 「一番星みつけた」
* (C) 生沼勝作詞(注)・信時潔作曲/文部省唱歌(一年)
* http://www.mahoroba.ne.jp/~gonbe007/hog/shouka/ichibanboshi.html
*/
void uta ( char *ichi, char *basyo, char *ki ) {
printf ( ichi );
printf ( "番星みつけた。\n" );
printf ( "あれあの" );
printf ( basyo );
printf ( "の\n" );
printf ( ki );
printf ( "の木のうえに。\n" );
}
void itibanboshi() {
uta ( "一", "森", "杉" );
printf ( "\n" );
uta ( "二", "どて", "柳" );
printf ( "\n" );
uta ( "三", "どて", "柳" );
printf ( "\n" );
}
/*
* main
*/
int main ( void ) {
itibanboshi();
return 0;
}
/*
p-001.c
「関数の作り方(関数定義)」の復習
例 : 「pritnf ( "Hello, World\n" );」に
print_hello という名前を付ける事を考える
1. 名前(関数名)を決める
「print_hello」とした
2. その名前を、main の前(外)に書く
3. 名前の前に 「void」, 後ろの 「(void)」 を書く
4. そのさらに後ろに空の 「{}」を入れる
5. 「{}」の間に、名前を付けたい命令を書く
「pritnf ( "Hello, World\n" );」に名前をつけたいので、
この内容を「{}」の間に、入れる
「関数の利用の仕方(関数呼び出し)」の復習
1. 名前を付けた命令を実行するには、「関数名();」とするだけ
*/
#include <stdio.h>
/*
関数 print_hello の定義
*/
void print_hello (void) {
/* printf ( "@@@ : print_hello の開始\n" );
*/
printf ( "Hello, World\n" );
}
int main(void) {
/* printf ( "@@@ : main の開始\n" );
*/
print_hello();
return 0;
}
/*
p-002.c
p-001.c の動作確認
[ポイント]
p-001.exe を実行すると、メッセージが一つ表示される。
関数 print_hello の中の「printf(...):」
Q.1 main などいらないのでは ?
A.1 main がないと、リンクの時に「main がない」と怒られる
=> main は必要
Q.2 命令は、どの順で実行されるのか ?
# print_hello が頭にあるから、これから ??
C Program は、必ず、main から始まる
=> main は必ず必要
# おまじないとして main を..
# => C の Program の開始部分を指定している
[p-002.c プログラムの構造]
0. main : 必ず main から実行される
1. printf
2. hello_world : 関数呼び出しがあると..
2.1 printf : それぞれ、名前つけられた命令が実行される
2.2 printf
2.3 printf
3. printf
[p-001.c プログラムの構造]
0. main
1. hello_world
1.1 printf
p-001.c の動作を理解するために p-002.c で追加した
printf 命令は。何時、何が、どの様に、起きているかを知る
「手がかり」として「(特別に)追加した」print 命令
=> 「デバッグプリント」と呼ぶ
!! プログラムの振る舞いがよくわからないとき
!! => プログラムのあちらこちらに、「デバッグプリント」
!! を入れると、理解できる事がよくある
*/
#include <stdio.h>
/*
関数 print_hello の定義
*/
void print_hello (void) {
printf ( "@@@: print_hello の最初\n" ); /* 2.1 */
printf ( "Hello, World\n" ); /* 2.2 */
printf ( "@@@: print_hello の最後\n" ); /* 2.3 */
}
int main(void) {
printf ( "@@@: main の最初\n" ); /* 1 */
print_hello(); /* 関数 print_hello の呼び出し */ /* 2 */
printf ( "@@@: main の最後\n" ); /* 3 */
return 0;
}
/*
p-003.c
「Hello, 色々」という形プログラムを考える
例:
Hello, 世界
Hello, 皆さん
Hello, 友達
...
*/
#include <stdio.h>
int main(void) {
printf ( "Hello, 世界\n" );
printf ( "Hello, 皆さん\n" );
printf ( "Hello, 友達\n" );
return 0;
}
/*
p-004.c
「Hello, 色々」という形プログラムを考える
例:
Hello, 世界
Hello, 皆さん
Hello, 友達
...
方針
関数を作って、main は、関数呼び出しにする
print_hello_world
print_hello_yours
print_hello_friend
*/
#include <stdio.h>
void print_hello_world(void) {
printf ( "Hello, 世界\n" );
}
void print_hello_yours(void) {
printf ( "Hello, 皆さん\n" );
}
void print_hello_friend(void) {
printf ( "Hello, 友達\n" );
}
int main(void) {
print_hello_world();
print_hello_yours();
print_hello_friend();
return 0;
}
/*
p-005.c
「Hello, 色々」という形プログラムを考える
例:
Hello, 世界
Hello, 皆さん
Hello, 友達
...
方針
関数を作って、main は、関数呼び出しにする
print_hello_world
print_hello_yours
print_hello_friend
[考察]
新しくつくった三つの関数は、よく似ている
hello, 何か
# コンピュータは繰り返しが得意
# 人間は、繰り返しが苦手
# 人間が不得意な繰り返しをコンピュータにやらせる
# => プログラミング
## 今回はコピー&ペーストですんだので、それほど大変はないが..
## プログラミングで「コピー&ペースト」は危険
うまく、一つのことで、三つの事ができないか ?
[単純な案]
print_hello_world();を三度呼ぶ
=> print_hello_world()を一つだけ定義すればよい
<= 同じメッセージしかでない
=> 不都合
[問題点]
(現状)関数が同じだと、同じ結果しかでない
=> 不自由
(希望)関数を減らしたい(一つにしたい)
結果は変えたい
「数学の「関数」」であれば、引数を指定して
同じ関数で、異なる値を返す事ができる
=> C 言語の関数でも同じ事ができる
[複数の関数をまとめる]
もし、
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
void print_hello_X(void) {
printf ( "Hello, X\n" );
}
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
として、X のところが変わるならうれしい...
=> できない
やりたいことの「違い」が、「違う命令の有り無し」になるようにする
printf の () の中が異なるだけ
=> その中身に「X」という名前を付ける
#「""」で挟まれたものは、
# 「文字列」という「情報を表すもの(data)」
## ここでは、「データに名前をつけて」いる
## cf. 関数定義が、「命令に名前を付けて」いる
*/
#include <stdio.h>
void print_hello_X(char *X) { /* (void) => (char *X) : 名前を使う */
printf ( "Hello, " );
printf ( X ); /* 関数の特徴となるデータに X という名前を付けた */
} /* 違うものが、同じとみなせる */
/* 「引数付き」関数 */
void print_hello_world(void) {
/* printf ( "Hello, " );*/
/* printf ( "世界\n" );*/ /* world の特徴は この行 */
print_hello_X("世界\n" ); /* hello_X の X に "世界\n" を指定 */
/* 引数付き関数に、変更したい部分として、
引数を指定する事により、個々の
具体的なふるまいをさせる事ができる */
}
void print_hello_yours(void) {
printf ( "Hello, " );
printf ( "皆さん\n" ); /* yours の特徴は この行 */
}
void print_hello_friend(void) {
printf ( "Hello, 友達\n" );
}
int main(void) {
print_hello_world();
print_hello_yours();
print_hello_friend();
return 0;
}
/*
p-006.c
print_hello_X という「引数付き関数」を利用して、
他の関数も作成してまう
*/
#include <stdio.h>
void print_hello_X(char *X) {
printf ( "Hello, " );
printf ( X ); /* 具体的には、引数で指定された値に入れ替わる */
/* X は「値が変わる」ので、「変数」と呼ばれる */
/* cf.数学の関数と同じ
f(x)=x*x
の時は、
f(3) -> 3*3 -> 9
*/
}
void print_hello_yours(void) {
print_hello_X("皆さん\n" );
/*
print_hello_X("皆さん\n" ); call
print_hello_X(char *X) が見つかる
X = "皆さん\n" として
printf ( "Hello, " );
printf ( X );
の二つの命令が実行される。
これは結果的には、変数 X のところに「皆さん\n」が入って
printf ( "Hello, " );
printf ( "皆さん\n" );
と同じ
*/
}
void print_hello_world(void) {
print_hello_X("世界\n" );}
void print_hello_friend(void) {
print_hello_X("友達\n" );
}
int main(void) {
print_hello_world();
print_hello_yours();
print_hello_friend();
return 0;
}
/*
p-007.c
print_hello_X という「引数付き関数」を利用して、
他の関数も作成してまう
main
print_hello_world
print_hello_X
printf
print_hello_yours
print_hello_X
printf
print_hello_firend
print_hello_X
printf
*/
#include <stdio.h>
void print_hello_X(char *X) {
printf ( "@@@ X 開始\n" );
printf ( "Hello, " );
printf ( X ); /* 具体的には、引数で指定された値に入れ替わる */
/* X は「値が変わる」ので、「変数」と呼ばれる */
/* cf.数学の関数と同じ
f(x)=x*x
の時は、
f(3) -> 3*3 -> 9
*/
}
void print_hello_yours(void) {
printf ( "@@@ yours 開始\n" );
print_hello_X("皆さん\n" );
/*
print_hello_X("皆さん\n" ); call
print_hello_X(char *X) が見つかる
X = "皆さん\n" として
printf ( "Hello, " );
printf ( X );
の二つの命令が実行される。
これは結果的には、変数 X のところに「皆さん\n」が入って
printf ( "Hello, " );
printf ( "皆さん\n" );
と同じ
*/
}
void print_hello_world(void) {
printf ( "@@@ word 開始\n" );
print_hello_X("世界\n" );}
void print_hello_friend(void) {
printf ( "@@@ friend 開始\n" );
print_hello_X("友達\n" );
}
int main(void) {
printf ( "@@@ main 開始\n" );
print_hello_world();
print_hello_yours();
print_hello_friend();
return 0;
}
/*
p-008.c
引数付き関数、いろいろ
(その 1) 同じ文字列を二度出力する
two_print
*/
void two_print(char *message) {
printf ( message ); /* 同じメッセージを二度書きたい */
printf ( message ); /* メッセージそのものは引数指定.. */
/* メッセージとなる変数には、「message」
という名前を付ける */
/*
[ポイント]
変数は、何度でも参照可能で、その値は毎回同じ
*/
}
int main(void) {
two_print ( "Hello, World\n" );
two_print ( "こんにちは、みなさん\n" );
return 0;
}
/*
p-009.c
引数付き関数、いろいろ
(その 2) 複数の引数をとる
誰が、誰に、何をする
who_whom_did
*/
#include <stdio.h>
void who_whom_did(char *who,char *whom,char *did) {
/* 変数は、複数もつことができる */
/* 関数の定義の時に、複数指定したら、呼び出すときも同じ数 */
printf ( who ); /* A さん */
printf ( "が、" ); /* が */
printf ( whom ); /* B さん */
printf ( "に、" ); /* に */
printf ( did ); /* キス */
printf ( "した。\n" ); /* した。 */
/*
命令の複数の部分を変更できる
=> 変更したい箇所に応じて、変数を設けて、置き換えればよい
*/
}
int main(void) {
who_whom_did ( "A 君", "B さん", "キス" );
who_whom_did ( "X さん", "Y さん", "メール" );
return 0;
}
/*
p-010.c
課題 : 20180427-01 の安易な答え
*/
#include <stdio.h>
int main(void) {
printf ( "一番星みつけた。\n" );
printf ( "あれあの森の\n" );
printf ( "杉の木のうえに。\n" );
printf ( "\n" );
printf ( "二番星みつけた。\n" );
printf ( "あれあのどての\n" );
printf ( "柳の木のうえに。\n" );
printf ( "\n" );
printf ( "三番星みつけた。\n" );
printf ( "あれあの山の\n" );
printf ( "松の木のうえに。\n" );
return 0;
}
# # Makefile (拡張子はない) # # # # は Makefile の中ではコメント # # 空白と[TAB] は、区別される # 空白のところには、空白を、[TAB] のところには[TAB] を入れる # # # 20180427-01-9999.exe の作り方 # 「20180427-01-9999.exe」 を作るには、「20180427-01-9999.o」を材料に # 「cc -o 20180427-01-9999.exe 20180427-01-9999.o」という調理をする 20180427-01-9999.exe : 20180427-01-9999.o cc -o 20180427-01-9999.exe 20180427-01-9999.o # # 20180427-01-9999.o の作り方 # 「20180427-01-9999.o」 を作るには、「20180427-01-9999.c」を材料に # 「cc -c 20180427-01-9999.c」という調理をする 20180427-01-9999.o : 20180427-01-9999.c cc -c 20180427-01-9999.c
?O?????K
1. ??????????A??????????????s?????
???? : ?uprintf("???b?Z?[?W");?v????
???s??????A?????L?q???????????????(????)
# cf.
# ?^?????v???O??????A?????`(?v???O??????????Z???s????)
# ???????????X?g??A????????
# ???X?g??????????????????
2. ???????O??t????(???)
a) ????(??)????O??t???鎖??????? (?????`)
i) ???????閼?O??t???鎖??A??????????
ii) (????..) ???????A?????яo??????????
=> ?v???O?????S?????????Z?????A??????????
# ?????b?g?????????????A???????????????
b) (??????O?????????????)??????O(?????)??????A
?Q??????(?????яo??)
?????v???O???? : helloworld
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
#include <stdio,h>
int main(void) {
pritnf ( "Hello, World\n" ); /* ???????????????????????? */
return 0;
}
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
=> (????)
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
Hello, World
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
[?????????]
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
#include <stdio,h>
int main(void) {
pritnf ( "Hello, World\n" ); /* ????????? */
pritnf ( "Hello, World\n" );
pritnf ( "Hello, World\n" );
return 0;
}
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
=> (????)
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
Hello, World /* ????(????o??)?????? */
Hello, World
Hello, World
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
[???????????????]
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
#include <stdio,h>
int main(void) {
pritnf ( "Hello, World\n" );
pritnf ( "????????A?F????\n" );
pritnf ( "?j?[?n?I\n" );
return 0;
}
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
=> (????)
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
Hello, World /* ?????????????? */
????????A?F????
?j?[?n?I
-- 8< ---- 8< ---- 8< ---- 8< ---- 8< ---- 8< --
==
[???T????e]
????????(??)
Download : 20180511-01.c
/*
* 20180511-01-QQQQ.c
* 分割コンパイルの main
*/
#include <stdio.h>
/*
* main
*/
int main ( void ) {
sub_20180511_01_9999(); /* サブルーチンを呼ぶ */
return 0;
}
Download : 20180511-01-01.c
/*
* 20180511-01-01-QQQQ.c
* 分割コンパイルの sub
*/
#include <stdio.h>
/*
* sub_20180511_01_9999
*/
void sub_20180511_01_9999 ( void ) {
printf ( "これは、9999 番のサブルーチンです\n" );
}
Download : Makefile-20180511.txt
# # Makefile-20180511-9999.txt # 分割コンパイルの Makefile # 20180511-01-9999.exe : 20180511-01-9999.o 20180511-01-01-9999.o cc -o 20180511-01-9999.exe 20180511-01-9999.o 20180511-01-01-9999.o 20180511-01-9999.o : 20180511-01-9999.c cc -c 20180511-01-9999.c 20180511-9999-01-01.o : 20180511-01-01-9999.c cc -c 20180511-01-01-9999.c
$ ls 20180511-01-9999.c 20180511-01-01-9999.c Makefile $ make cc -c 20180511-01-9999.c cc -c 20180511-01-01-9999.c cc -o 20180511-01-9999.exe 20180511-01-9999.o 20180511-01-01-9999.o $ ./20180511-01-QQQQ.exe これは、9999 番のサブルーチンです $