Download : sample-001.c
/*
* 2017/06/16 sample-001.c
*/
/*
* 返値を持つ関数
*/
#include <stdio.h>
/*
* to_upper : 引数で与えられた文字が小文字なら大文字にする
*/
char to_upper ( char ch ) {
if ( 'a' <= ch ) { /* もし、ch が 'a' 以上で.. */
if ( ch <= 'z' ) { /* 更に、ch が 'z' 以下なら.. */
return ch - 'a' + 'A'; /* 小文字なので大文字に変換して返す */
/* return 命令が実行されると、そこで関数は終了 */
} /* else {} */ /* else 以下はないので省略 */
} /* else {} */
return ch; /* 小文字でない場合は、そのまま返す */
}
/*
* main 関数
*/
int main ( void ) {
printf ( "一文字入力して、[Enter] キーを押してください : " );
putchar ( to_upper ( getchar() ) );
putchar ( '\n' );
return 0;
}
k
$ ./sample-001.exe < sample-001.in 一文字入力して、[Enter] キーを押してください : k K $
Download : sample-002.c
/*
* 2017/06/16 sample-002.c
*/
/*
* main の返値
*/
#include <stdio.h>
/*
* is_upper : ch が大文字なら 1 そうでなければ、0 を返す
*/
int is_upper ( int ch ) {
if ( 'A' <= ch ) {
if ( ch <= 'Z' ) {
return 1; /* 大文字だった.. */
}
}
return 0; /* 大文字ではなかった.. */
}
/*
* main 関数
*/
int main ( void ) {
printf ( "一文字入力して、[Enter] キーを押してください : " );
if ( is_upper ( getchar() ) ) {
printf ( "大文字なので 0 を返します。\n" );
return 0;
} else {
printf ( "大文字でなかったので 1 を返します。\n" );
return 1;
}
}
Q
$ ./sample-002.exe < sample-002.in 一文字入力して、[Enter] キーを押してください : Q 大文字なので 0 を返します。 $ echo $? 0 $
Download : sample-003.c
/*
* 2017/06/16 sample-003.c
*
* コンパイルの方法:
* cc -c -I ~/c/include sample-003.c
*/
/*
* s_print.h の使い方
*/
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合には必要 */
/*
* main 関数
*/
int main ( void ) {
s_print_char ( 'A' ); /* 文字の出力 : putchar ( 'A' ) と同じ */
s_print_newline(); /* 改行の出力 : putchar ( '\n' ) と同じ */
s_print_string ( "Hello, World\n" );
/* 文字列の出力 : printf と同じ */
s_print_int ( 123 ); /* 整数値の出力 */
s_print_newline();
return 0;
}
$ ./sample-003.exe A Hello, World 123 $
Download : sample-004.c
/*
* 2017/06/16 sample-004.c
*
* コンパイルの方法:
* cc -c -I ~/c/include sample-004.c
*/
/*
* s_input.h の使い方
*/
#include <stdio.h>
#include "s_print.h"
#include "s_input.h" /* s_input_... を利用する場合には必要 */
/*
* main 関数
*/
int main ( void ) {
s_print_string ( "一文字を入力して、[Enter] を押してください : " );
s_print_char ( s_input_char () + 1 );
s_print_newline();
s_print_string ( "整数値を一つ入力して、[Enter] を押してください : " );
s_print_int ( s_input_int () + 1 );
s_print_newline();
return 0;
}
B 123
$ ./sample-004.exe < sample-004.in 一文字を入力して、[Enter] を押してください : B C 整数値を一つ入力して、[Enter] を押してください : 123 124 $
Download : sample-005.c
/*
* 2017/06/16 sample-005.c
*
* コンパイルの方法:
* cc -c -I ~/c/include sample-005.c
*/
/*
* 二つの入力を利用する場合
*/
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
* addfunc
*/
int addfunc ( int a ) {
s_print_string ( "二つ目の整数値を入力して、[Enter] を押してください : " );
return a + s_input_int();
}
/*
* main 関数
*/
int main ( void ) {
s_print_string ( "一つ目の整数値を入力して、[Enter] を押してください : " );
s_print_int ( addfunc ( s_input_int() ) );
s_print_newline();
return 0;
}
123 456
$ ./sample-005.exe < sample-005.in 一つ目の整数値を入力して、[Enter] を押してください : 123 二つ目の整数値を入力して、[Enter] を押してください : 456 579 $
Download : sample-006.c
/*
* 2017/06/16 sample-006.c
*
* コンパイルの方法:
* cc -c -I ~/c/include sample-006.c
*/
/*
* 二つの入力を利用する場合 (失敗例)
*/
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
* subfunc
*/
int subfunc ( int a, int b ) {
return a - b;
}
/*
* main 関数
*/
int main ( void ) {
s_print_string ( "二つの整数値を入力して、[Enter] を押してください : " );
s_print_int ( subfunc ( s_input_int(), s_input_int() ) );
s_print_newline();
return 0;
}
123 456
$ ./sample-006.exe < sample-006.in 二つの整数値を入力して、[Enter] を押してください : 123 456 333 $
/*
* 20170616-01-QQQQ.c
* p-005.c を参考にする
* p-005.c は、小文字を大文字だったので、
* この課題では、それを逆にすればよい
*/
#include <stdio.h>
/*
* to_lower : 引数で与えられた文字が大文字なら小文字にする
*/
char to_lower ( char ch ) {
/* p-005.c では、 'a' だった.. */
if ( 'A' <= ch ) { /* もし、ch が 'A' 以上で.. */
if ( ch <= 'Z' ) { /* 更に、ch が 'Z' 以下なら.. */
return ch - 'a' + 'A'; /* 'a' - 'A' = 32 */
/* これだと、小文字が大文字になる */
/* これを変更すればよい */
} /* else {} */ /* else 以下はないので省略 */
} /* else {} */
return ch; /* 大文字でない場合は、そのまま返す */
}
/*
* main 関数
*/
int main ( void ) {
printf ( "一文字入力して、[Enter] キーを押してください : " );
putchar ( to_lower ( getchar() ) );
putchar ( '\n' );
return 0;
}
/*
* 20170616-02-QQQQ.c
* 二つの整数値を入力して、その商を出力する
* p-014.c が参考になる
* 関数の引数で、副作用が起きる場合は、順番を気にする
*/
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
* remainder
*/
int remainder ( int a ) {
s_print_string ( "割る整数を入力して、[Enter] を押してください : " );
/*
* 割られる数 (a) は与えられているので、
* 割る数を入力し、その値を使って、
* 余りの計算をすればよい
* あまりの計算を行う演算子は % なので、それを利用する
*/
return a % /* 入力する関数を呼ぶ */
}
/*
* main
*/
int main ( void ) {
s_print_string ( "割られる整数を入力して、[Enter] を押してください : " );
s_print_int ( remainder ( s_input_int() ) );
s_print_newline();
return 0;
}
#include <stdio.h>
void func(void) {
printf ( "Hello, World\n" );
}
int main(void) {
func();
func();
return 0;
}
#include <stdio.h>
void func(char *X) {
printf ( "Hello, " );
printf ( X ); /* 変数 X には、後から文字列が指定できる */
printf ( "\n" );
}
int main(void) {
func( "World" ); /* 関数が呼び出されるたびに X の値が変わる */
func( "皆さん" );
return 0;
}
#include <stdio.h>
void func(char X) {
/* 引数として、指定する値が「文字」の場合は、
「char *」ではなくて「char」とする
引数で与える値の「型」を指定する
「型」については、あまり説明していないが..
データ 型指定
文字列 char *
文字 char
整数 int
*/
printf ( "Hello, " );
putchar ( X ); /* 変数 X には、後から文字列が指定できる */
printf ( "\n" );
}
int main(void) {
func( 'A' ); /* 関数が呼び出されるたびに X の値が変わる */
func( 'z' );
return 0;
}
#include <stdio.h>
/*
関数が値を返す場合を考える
# 「C 言語の関数」:「数学の関数」とは違っていた
*/
/*
to_upper : 引数として、小文字を与え、それに対する大文字を返す関数
# 値(返値[かえりち])を返す関数
*/
char to_upper(char ch) {
/* 引数として文字を与え、結果として文字を返す */
return ch - 'a' + 'A'; /* 'a' - 'A' = 32 */
/* ASCII 表をみると
文字 文字コード
A 65 -> 65 + 0
B 66 -> 65 + 1
..
a 97 -> 65 = 97 - 32
-> 97 + 0
b 98 -> 66 = 98 - 32
-> 97 + 1
..
小文字を大文字するにするなら 32 を引くとよい
return ch - 32;
小文字があたえられたら、
'a' からいくつはなれるかを考える
それに 'A' を加えれば、'A' からその数だけはなれた
*/
/*
return 命令
return の後ろに「式」を書くと、
その「式」の値が、関数の返値として帰る
# この結果として、関数はここで終了する
*/
}
int main(void) {
printf ( "小文字を一つ入力し[Enter] キーを押してください : " );
putchar ( to_upper ( getchar() ) );
/* 小文字を入力し、それを大文字に変換して出力 */
putchar ( '\n' );
return 0;
}
#include <stdio.h>
/*
関数が値を返す場合を考える
# 「C 言語の関数」:「数学の関数」とは違っていた
*/
/*
to_upper : 引数として、小文字を与え、それに対する大文字を返す関数
# 値(返値[かえりち])を返す関数
*/
char to_upper(char ch) {
/* 引数として文字を与え、結果として文字を返す */
/* 小文字の場合だけ、変換し、その他の場合はそのまま返す */
/* 小文字かどうかを判定する */
/* 小文字かどうかは 'a' <= ch <= 'z' である事で判定 */
if ( 'a' <= ch ) { /* まず、'a' 以上である事をチェック */
if ( ch <= 'z' ) { /* 次に、'z' 以下である事をチェック */
/* ここでは、ch が小文字である事が解るので.. */
return ch - 'a' + 'A'; /* 'a' - 'A' = 32 */
/* ここで、return 命令が実行されるので、
ここで、関数は終了する
*/
} /* else {} */
} /* else {} */
/* ここに来るのは、23 行目の return が実行されなかった時 */
return ch; /* そうでない時は、もとまま値として返す */
}
int main(void) {
printf ( "小文字を一つ入力し[Enter] キーを押してください : " );
putchar ( to_upper ( getchar() ) );
/* 小文字を入力し、それを大文字に変換して出力 */
putchar ( '\n' );
return 0;
}
#include <stdio.h>
int main(void) {
printf ( "Hello, World\n" );
return 0;
}
#include <stdio.h>
int main(void) {
printf ( "Hello, World\n" );
return 1; /* return 0 ?????? 1 ??????牽???????? */
/* ?v???O??????яo?????u???m?v??u???s?X?e?[?^?X?v?????l????? */
/* 0 ?????A0 ??O??A?G???[?R?[?h */
}
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合 */
/*
これによって、
s_print_string : 文字列を出力
s_print_char : 文字を出力
s_print_int : 整数値を出力
s_print_newline : 改行を出力
が使えるようになる
*/
/*
コンパイルする時は、
cc -I ~/c/include -c p-008.c
と、「-I ~/c/include」を先行させる必要がある
*/
int main(void) {
s_print_string ( "abc\n" ); /* printf と同じ */
s_print_char ( 'z' ); /* putchar と同じ */
s_print_newline(); /* 改行 ( putchar( '\n' ) ) */
s_print_int ( 123 ); /* 整数値を出力 */
s_print_newline();
return 0;
}
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合 */
#include "s_input.h" /* s_input_... を利用する場合 */
/*
これによって、
s_input_string : 文字列を入力
s_input_char : 文字を入力
s_input_int : 整数値を入力
が使えるようになる
*/
/*
コンパイルする時は、
cc -I ~/c/include -c p-009.c
と、「-I ~/c/include」を先行させる必要がある
*/
int main(void) {
s_print_string ( "整数値を一つ入力して[Enter]キーを押してください : " );
s_print_int ( s_input_int() * 2 );
/* 入力された数値を二倍して、画面に出力 */
s_print_newline();
return 0;
}
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合 */
#include "s_input.h" /* s_input_... を利用する場合 */
int main(void) {
s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " );
s_print_int ( s_input_int() + s_input_int() );
/* s_input_int() を二度呼ぶ事により、二度入力され、
それぞれが、関数の返値として与えられる */
/* 入力された数値の和を計算して、画面に出力 */
s_print_newline();
return 0;
}
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合 */
#include "s_input.h" /* s_input_... を利用する場合 */
/*
* add_int は二つの引数で与えらえた整数値の和を返す
* 返値を持つ「関数」は、「数学の関数」とよくにている
*/
int add_int ( int a, int b ) {
return a + b;
}
int main(void) {
s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " );
s_print_int ( add_int ( s_input_int(), s_input_int() ) );
/* s_input_int() を二度呼ぶ事により、二度入力され、
それぞれが、関数の返値として与えられる */
/* 入力された数値の和を計算して、画面に出力 */
s_print_newline();
return 0;
}
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合 */
#include "s_input.h" /* s_input_... を利用する場合 */
/*
* sub_int は二つの引数で与えらえた整数値の差を返す
* 返値を持つ「関数」は、「数学の関数」とよくにている
*/
int sub_int ( int a, int b ) {
return a - b;
}
int main(void) {
s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " );
s_print_int ( sub_int ( s_input_int(), s_input_int() ) );
/* s_input_int() を二度呼ぶ事により、二度入力され、
それぞれが、関数の返値として与えられる */
/* 入力された数値の和を計算して、画面に出力 */
s_print_newline();
return 0;
}
#include <stdio.h>
int sub1(void) {
printf ( "関数 sub1 が呼ばれました\n" );
return 1;
}
int sub2(void) {
printf ( "関数 sub2 が呼ばれました\n" );
return 2;
}
int sub3(int a, int b) {
printf ( "関数 sub3 が呼ばれました\n" );
return a+b;
}
int main(void) {
sub3 ( sub1(), sub2() );
/*
とりあえず、sub1 と sub2 が呼び出され、
その結果使って、sub3 が呼び出されるので、
sub1 +---
sub2 +--- どちらが先に呼び出されるか ?
関数の引数は後ろから計算される
その引数に「副作用」がある場合は、その順が問題になる
数学の関数では f(g(x),h(y))で、
関数 g と h がどちらが先に計算するかはどうでもよい
# C 言語でも、g, h が純粋に計算だけをする場合は、
# 数学と同じような事がいえる
# ところが、入出力(副作用)がある場合は、そうは言ってられない
sub3
*/
return 0;
}
#include <stdio.h>
#include "s_print.h" /* s_print_... を利用する場合 */
#include "s_input.h" /* s_input_... を利用する場合 */
/*
* sub_int は二つの引数で与えらえた整数値の差を返す
* 返値を持つ「関数」は、「数学の関数」とよくにている
*/
int sub_int ( int a, int b ) {
return a - b;
}
int sub_int_from_a ( int a ) {
/* ここで、二度目の s_input_int を呼び出す事により、
二つ目の引数が、二度めの入力である事が保証される */
return sub_int ( a, s_input_int() );
}
int main(void) {
s_print_string ( "整数値を二つ入力して[Enter]キーを押してください : " );
s_print_int ( sub_int_from_a ( s_input_int() ) );
/* s_input_int() を一度しか呼ばない事により、
一つ目の引数が、最初の入力である事を保証する
/* 入力された数値の和を計算して、画面に出力 */
s_print_newline();
return 0;
}
#include <stdio.h> /* おまじない(とにかくいれよう) */
int main(int argc, char *argv[]) {
/* 最初は「int main (void)」と書くとはなしていた.. おまじない */
printf ( "Hello, World\n" );
/* 画面に「Hello World」+「改行」を出力する */
/* printf とはという説明もしてなかった */
/* 6 行目だけ意味がある記述として以下.. */
return 0; /* これもおまじない */
} /* おまじない */
/*
一行目の役割は ?
とってしまったらどうなるか ?
#include <stdio.h>
ノックアウト
それを取り除いたら、働かなくなるのであれば、
その働かなくなる機能が、それの役割
[結果] 次のメッセージが出るようになった
p-016.c: In function ‘main’:
p-016.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf ( "Hello, World\n" );
^
「printf が変」
*/
int main(int argc, char *argv[]) {
printf ( "Hello, World\n" );
return 0;
}
/*
一行目の役割は ?
とってしまったらどうなるか ?
#include <stdio.h>
ノックアウト
それを取り除いたら、働かなくなるのであれば、
その働かなくなる機能が、それの役割
[結果] 次のメッセージが出るようになった
p-016.c: In function ‘main’:
p-016.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf ( "Hello, World\n" );
^
「printf が変」
*/
int main(int argc, char *argv[]) {
/*
#include を外すと、printf の利用で、メッセージが出る
printf もはずしてみよう
[結果]
メッセージが再び出力されなくなった
--> #include <stdio.h> は、printf を利用するために必要
*/
/*
printf ( "Hello, World\n" );
*/
return 0;
}
/*
一行目の役割は ?
とってしまったらどうなるか ?
#include <stdio.h>
ノックアウト
それを取り除いたら、働かなくなるのであれば、
その働かなくなる機能が、それの役割
[結果] 次のメッセージが出るようになった
p-016.c: In function ‘main’:
p-016.c:12:2: warning: incompatible implicit declaration of built-in function ‘printf’ [enabled by default]
printf ( "Hello, World\n" );
^
「printf が変」
*/
/* #include <stdio.h> の代わりに次の行を入れる */
extern int printf (const char *__restrict __format, ...);
int main(int argc, char *argv[]) {
printf ( "Hello, World\n" );
return 0;
}
#include "p-019.h"
/*
同じフォルダの p-019.h をここに読み込む
この p-019.h には、 printf を利用するための記述があるので、
printf を利用する場合に、
#include <stdio.h>
をかくのと同じ効果がある
*/
int main(int argc, char *argv[]) {
printf ( "Hello, World\n" );
return 0;
}
#include <stdio.h>
int main(void) {
putchar ( getchar() );
return 0;
}
/*
#include <stdio.h>
*/
int main(void) {
putchar ( getchar() );
return 0;
}
#include <stdio.h> /* printf を利用するために必要 */
/* printf を利用しない場合は、不要 */
/* printf は、文字列を出力するという、
基本的な機能を担っているので、
まあ、必ず使うと思っていてよいし、
無駄にいれてあっても悪さはしないので、
いつでも入れると思ってよい(結局、おまじない)
*/
/*
#include によって、他のファイルの中身が、
ここに自動的に copy されるという事がポイント
後に、数学ライブラリ ( sin, cos, log ) を
利用する時にまた、紹介する
*/
int main(void) {
/*
int argc, char *argv[]
コマンドライン引数を利用する場合に、
宣言が必要になる
逆に、コマンドライン引数を参照しない場合は、
不要(voidでよい)
# void 自身も省略可能なので、そもそもなくてもよい
*/
printf ( "Hello, World\n" );
/* return 0 の役割は ? */
/* ノックアウトしてみる
[結果]
値として、何を返すかを指定しなかったので、
その結果として、(なぜか ?)13 が返った
(0 じゃなかったので..)エラーとして処理された
*/
/*
return 0;
*/
}
/*
Hello, World 二週目(種明かし版)
*/
#include <stdio.h>
/*
/usr/include/stdio.h をここに読み込めという意味
結果的に、stdio.h の中にある printf の宣言が読み込まれ、
printf を利用する準備がなされる
printf を使わない場合は、いらない
# もし、stdio.h に書いてあるたの関数を利用しないのであれば..
ただ、どうせ、printf は使うので、
いつでも入れておいてよい
*/
int main(int argc, char *argv[]) {
/*
int argc, char *argv[] は、コマンドライン引数を
参照する場合に必要
main の前の int は、終了ステータスを整数値として返すため
C 言語で作られたプログラムには、必ず main 関数が必要で、
それが(作成されたプログラム内では..)最初に呼び出される
*/
printf ( "Hello, World\n" );
/*
最初:文字列を出力する
引数は、「”」で挟まれているので、文字列
この記述は、printf という関数を呼び出している
printf は、C 言語の標準ライブラリで定義されているので、
とくに自分で作らなくても、すぐ利用できる
その代わりに、リンクが必要なる
*/
return 0; /* 正常終了 */
/*
プログラムが正常終了した(関数の返値が 0 なら正常)事を
プログラムを呼び出したものに伝える
*/
}
関数の作り方
最初 : 命令列に名前を付ける場合
void 関数名(void) {名前をつける命令}
二番目 : 引数を与える場合
void 関数名 ( char * 仮引数変数名, ... ) { }
三番目 : 引数に型がある
二番目は、引数に指定するデータ型が 「文字列」だったの char *
もし、引数が、「文字」だったり、「整数」だった場合は、
それぞれ、「char(文字列)」、「int(整数)」と、
型に合わせて、変数に前を変更する
四番目 : 返値を持つ関数の場合
関数名の前の void を、関数が返す値の型にする
関数の本体の中で、「return 式」を実行して、
その式の値が、関数の値になるようにする。
s_print.h/s_input.h の使い方
#include "s_print.h"
これによって、
s_print_string : 文字列を出力
s_print_char : 文字を出力
s_print_int : 整数値を出力
s_print_newline : 改行を出力
が使えるようになる
コンパイルする時は、
cc -I ~/c/include -c p-008.c
と、「-I ~/c/include」を先行させる必要がある
s_print.h がある場所が、~/c/include である事を指定している
[二周目]
Hello, World 再び
#include <stdio.h> の役割
#include <...> は、
/usr/include/... をここに読み込みなさい
という意味
#include "..." は。
同じフォルダの ... を、ここに読み込みなさい
Download : 20170616-01.c
/*
* 20170616-01-QQQQ.c
* 文字を
*/
#include <stdio.h>
/*
* to_lower : 引数で与えられた文字が大文字なら小文字にする
*/
char to_lower ( char ch ) {
if ( 'A' <= ch ) { /* もし、ch が 'A' 以上で.. */
if ( ch <= 'Z' ) { /* 更に、ch が 'Z' 以下なら.. */
/*
** この部分を完成させなさい
*/
} /* else {} */ /* else 以下はないので省略 */
} /* else {} */
return ch; /* 大文字でない場合は、そのまま返す */
}
/*
* main 関数
*/
int main ( void ) {
printf ( "一文字入力して、[Enter] キーを押してください : " );
putchar ( to_lower ( getchar() ) );
putchar ( '\n' );
return 0;
}
D
$ ./20170616-01-QQQQ.exe 一文字入力して、[Enter] キーを押してください : d $
Download : 20170616-02.c
/*
* 20170616-02-QQQQ.c
* 二つの整数値を入力して、その商を出力する
*/
#include <stdio.h>
#include "s_print.h"
#include "s_input.h"
/*
* remainder
*/
int remainder ( int a ) {
s_print_string ( "割る整数を入力して、[Enter] を押してください : " );
/*
** この部分を完成させなさい
*/
}
/*
* main
*/
int main ( void ) {
s_print_string ( "割られる整数を入力して、[Enter] を押してください : " );
s_print_int ( remainder ( s_input_int() ) );
s_print_newline();
return 0;
}
100 13
$ ./20170616-02-QQQQ.exe 割られる整数を入力して、[Enter] を押してください : 100 割る整数を入力して、[Enter] を押してください : 13 9 $