---
title: cp-8. 関数
tags:  #プログラミング #c #関数 #関数呼び出し #引数 #金子邦彦研究室  
author: [kunihikokaneko](https://www.docswell.com/user/6674398749)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/D7YPN8M87M.jpg?width=480
description: C プログラミング入門 （スライド資料とプログラム例）（Visual Studio 2019 を使用）（全１５回） https://www.kkaneko.jp/pro/adp/index.html  金子邦彦研究室ホームページ https://www.kkaneko.jp/index.html
published: February 21, 22
canonical: https://www.docswell.com/s/6674398749/KMVPXK-2022-02-21-181228
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/D7YPN8M87M.jpg)

cp-8. 関数
（C プログラミング入門）
URL: https://www.kkaneko.jp/pro/adp/index.html
金子邦彦
1


# Page. 2

![Page Image](https://bcdn.docswell.com/page/VEN5XQW9J8.jpg)

内容
例題１．棒グラフ
関数とは．プログラム実行順．データの流れ．
引数と仮引数
例題２．月の日数
return 文
例題３．１か月分のカレンダー
例題４．月初めの曜日
例題５．カレンダー
関数の集まりとしてのプログラム
2


# Page. 3

![Page Image](https://bcdn.docswell.com/page/Y79Y8DX3E3.jpg)

仕事の分割
○○の仕事を
頼む！
△△の仕事を
頼む！
頼む人
担当者Ａ
担当者Ｂ
3


# Page. 4

![Page Image](https://bcdn.docswell.com/page/G786832LJD.jpg)

関数とは
関数Ａ
呼び出し側
関数Ｃ
関数Ｂ
呼び出され側
呼び出され側
プログラムは，しばしば，複数の関
数に「分割」される
4


# Page. 5

![Page Image](https://bcdn.docswell.com/page/L7L9RV2QER.jpg)

目標
• １つの main 関数と，その他の複数の関数から
構成されたプログラムを読んで，理解できる能
力を習得する
• 複数の関数の間での「情報の受け渡し」につい
て理解する
5


# Page. 6

![Page Image](https://bcdn.docswell.com/page/4EMZRG9K7W.jpg)

例題１．棒グラフ
• 整数から，その長さだけの棒を表示する関数を作
る
例） 5 → *****
• 上記で作った関数を使って，「整数を読み込んで，
読み込んだ長さの棒を表示するプログラム」を作
る
6


# Page. 7

![Page Image](https://bcdn.docswell.com/page/PER6RZG6J9.jpg)

棒グラフ
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void bar( int len )
{
int i;
for (i=0; i&lt;len; i++) {
printf(&quot;*&quot;);
bar関数
}
printf(&quot;\n&quot;);
return;
}
int main()
{
int len;
printf( &quot;len=&quot; );
scanf( &quot;%d&quot;, &amp;len );
bar( len );
return 0;
}
main関数
7


# Page. 8

![Page Image](https://bcdn.docswell.com/page/P7XMR9XDJX.jpg)

棒グラフ
実行結果の例
len=5
*****
8


# Page. 9

![Page Image](https://bcdn.docswell.com/page/37KGRPWDED.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
bar(len);
bar 関数
void bar( int len )
戻り
return;
9


# Page. 10

![Page Image](https://bcdn.docswell.com/page/LJ3N8X1PJ5.jpg)

プログラム実行順
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void bar( int len )
{
int i;
for (i=0; i&lt;len; i++) {
④
printf(&quot;*&quot;);
bar関数
}
⑤ printf(&quot;\n&quot;);
⑥ return; 戻り
}
main 関数の先頭行
int main()
がプログラムの始まり
{
int len;
① printf( &quot;len=&quot; );
② scanf( &quot;%d&quot;, &amp;len );
main関数
③ bar( len ); 関数呼び出し
⑦ return 0;
main 関数内の return
}
がプログラムの終わり
10


# Page. 11

![Page Image](https://bcdn.docswell.com/page/8JDWM2X3EG.jpg)

プログラム実行順
bar 関数
void bar( int len )
main 関数
int main()
printf( &quot;len=&quot; );
関数
呼び出し
scanf( &quot;%d&quot;, &amp;len );
if( i &lt; len )
No
bar( len );
return 0;
i = 0;
Yes
printf( &quot;*&quot; );
i++;
戻り
printf(&quot;\n&quot;);
return;
11


# Page. 12

![Page Image](https://bcdn.docswell.com/page/VEP9R1PP78.jpg)

プログラム実行順
• 普通，プログラム中の文は逐次的に実行され
る
• 関数呼び出しでは，関数の先頭に「ジャン
プ」する．
関数呼び出しの例） bar( len );
• 関数の中で return 文に出会うと，関数呼び出
しの場所に戻る．
12


# Page. 13

![Page Image](https://bcdn.docswell.com/page/27VMRY2V7Q.jpg)

main 関数
• プログラムの実行を開始すると，自動的にmain
関数が呼ばれる
• プログラムの開始は，main 関数の最初の行から
• main 関数内の return 文は，「プログラムの終わり」
を示す
• プログラムには，必ず main 関数が書かれていな
ければならない
13


# Page. 14

![Page Image](https://bcdn.docswell.com/page/5JGGM9R1JL.jpg)

関数定義の例
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
頭部
void bar( int len )
{
型int名前
i; 仮引数
for (i=0; i&lt;len; i++) {
printf(&quot;*&quot;);
bar関数
}
本体
printf(&quot;\n&quot;);
return;
}
int main()
{
型名前
int len;仮引数（は空）
printf( &quot;len=&quot; );
scanf( &quot;%d&quot;, &amp;len );
bar( len );
return 0;
}
頭部
本体
main関数
14


# Page. 15

![Page Image](https://bcdn.docswell.com/page/47QXRWVNJP.jpg)

関数定義
• 関数定義とは，関数の実体をプログラムとして
書くこと
• 関数には，名前，型，仮引数がある
例） void bar(
int len )
int main()
型
名前
関数側から呼び出し側に
返されるデータに関係する
仮引数
呼び出し側から関数側に
渡されるデータに関係する
• 仮引数のそれぞれにも，型と名前がある
15


# Page. 16

![Page Image](https://bcdn.docswell.com/page/KE468KM3J1.jpg)

関数でのデータの流れ
関数Ａ
関数呼び出し時に，
データ（処理すべき
データ）を渡す
呼び出し側
関数からの戻り時に，
データ（処理結果の
データ）を返す
関数Ｂ
呼び出され側
16


# Page. 17

![Page Image](https://bcdn.docswell.com/page/L71V2X8ZJG.jpg)

データの流れ
main 関数
int main()
関数呼び出し
bar(len);
① len の値を，
bar 関数に渡す
bar 関数
void bar( int len )
型
仮引数
②整数を受け取って，
「len」という名前で使う
戻り
return;
③main 関数には，
何も返さない
17


# Page. 18

![Page Image](https://bcdn.docswell.com/page/G7WLRNZ6J2.jpg)

データの流れ
値がコピーされる
len
5
main 関数内で宣言された len
main 関数
int main()
関数呼び出し
bar(len);
① len の値を，
bar 関数に渡す
len
5
仮引数で宣言された len
len
5
こちらは使われない
main 関数内で宣言された len
と，仮引数で宣言された len は
別のもの
sum 関数
void bar( int len )
仮引数
型
②整数を受け取って，
「len」という名前で使う
戻り
return;
③main 関数には，
何も返さない
18


# Page. 19

![Page Image](https://bcdn.docswell.com/page/4JZMR31R73.jpg)

引数と仮引数
• 関数呼び出し側
• カッコの中に書いた変数等の値（引数という）が，
関数に渡される
（例） bar( len );
len の値を，bar 関数に渡す（引数）
• 呼び出された関数側
• 呼び出された関数は，値を受け取って，名前を付け
て使用する（仮引数という）
（例） int bar( int len )
整数を受け取って，「len」
という名前で使う（仮引数） 19


# Page. 20

![Page Image](https://bcdn.docswell.com/page/YE6NRXL1EV.jpg)

引数と仮引数
• 引数
• 関数などに実際に渡される「データ」のこと
• 関数呼出しの（，）内に並べる
• 定数や変数や式を書く
• 仮引数（パラメータともいう）
• 関数定義の（，）中で宣言された変数のこと．
（例） void bar(int len)では，変数 len が宣言されている．
• 関数は，呼び出された時点において，値を受け取り，当
該関数の仮引数である変数にセットする．
• 引数で与えられた値が，仮引数の変数に代入され
て情報の受け渡しが行われる．
20


# Page. 21

![Page Image](https://bcdn.docswell.com/page/GE558X1LE4.jpg)

例題２．月の日数
• 年と月から，日数を求める関数を作る
• うるう年の２月ならば２９
• 求めた日数は，関数の返り値として，呼び出し側に返
すこと．
例） 2001 年 11 月 → 30
• 上記で作った関数を使って，「年と月を読み込ん
で，日数を求めるプログラム」を作る
21


# Page. 22

![Page Image](https://bcdn.docswell.com/page/972NKX13JR.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int num_of_day( int y, int m)
{
int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
if ( (m == 2) &amp;&amp; (((y % 400) == 0) || (((y % 100) != 0) &amp;&amp; ((y % 4) ==
0)))){
return 29;
}
else {
return num_days[m-1];
}
}
int main()
{
int y;
int m;
int n;
printf( &quot;y=&quot; );
scanf( &quot;%d&quot;, &amp;y );
printf( &quot;m=&quot; );
scanf( &quot;%d&quot;, &amp;m );
n = num_of_day(y, m);
printf( &quot;number of days(%d) = %d\n&quot;, m, n );
return 0;
}
22


# Page. 23

![Page Image](https://bcdn.docswell.com/page/DJYPN8Z8JM.jpg)

月の日数
実行結果の例
y=2001
m=11
number of days(11) = 30
23


# Page. 24

![Page Image](https://bcdn.docswell.com/page/V7N5XQ39E8.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
n = num_of_day(y, m);
num_of_day 関数
int num_of_day( int y, int m )
戻り
return 29;
うるう年のとき
return num_days[m-1];
うるう年
でないとき
24


# Page. 25

![Page Image](https://bcdn.docswell.com/page/YJ9Y8D9373.jpg)

#include &lt;stdio.h&gt;
プログラム実行順
#pragma warning(disable:4996)
int num_of_day( int y, int m)
{
int num_days[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
⑤ if ( ( m == 2 ) &amp;&amp; (((y % 400) == 0) || (((y % 100) != 0) &amp;&amp; ((y %4) == 0)))){
⑥ return 29;
}
else {
⑥ return num_days[m-1];
}
}
int main()
{
int y;
int m;
int n;
① printf( &quot;y=&quot; );
② scanf( &quot;%d&quot;, &amp;y );
③ printf( &quot;m=&quot; );
④ scanf( &quot;%d&quot;, &amp;m );
⑦ n = num_of_day(y, m);
⑧ printf( &quot;number of days(%d) = %d\n&quot;, m, n );
⑨ return 0;
25
}


# Page. 26

![Page Image](https://bcdn.docswell.com/page/GJ86839LED.jpg)

プログラム実行順
main 関数
num_of_day 関数
int main()
int num_of_day( int y, int m)
関数
呼び出し
n = num_of_day(y, m);
if( ・・・ ) Yes
No
return 29;
return num_days[m戻り 1];
26


# Page. 27

![Page Image](https://bcdn.docswell.com/page/LJL9RVWQ7R.jpg)

データの流れ
main 関数
int main()
関数呼び出し
n = num_of_day(y, m);
① y と m の値を，
num_of_day 関数に渡す
num_of_day 関数
int num_of_day( int y, int m )
仮引数
型
②整数を２つを受け取って，
「y」 と 「m」という名前で使う
戻り
うるう年のとき
return 29;
③main 関数に，29 を返す
うるう年
return num_days[m-1]; でないとき
③main 関数に，num_days[m-1]
27
の値を返す


# Page. 28

![Page Image](https://bcdn.docswell.com/page/47MZRGYKJW.jpg)

データの流れ
値がコピーされる
y
m
2001
11
main 関数
int main()
関数呼び出し
n = num_of_day(y, m);
① y と m の値を，
num_of_day 関数に渡す
y
m
y
m
2001
11
2001
11
num_of_day 関数
int num_of_day( int y, int m )
型
仮引数
②整数を２つを受け取って，
「y」 と 「m」という名前で使う
戻り
うるう年のとき
return 29;
③main 関数に，29 を返す
うるう年
return num_days[m-1];
でないとき
③main 関数に，num_days[m-1]
28
の値を返す


# Page. 29

![Page Image](https://bcdn.docswell.com/page/P7R6RZ96E9.jpg)

関数の中の return 文
• 関数の呼び出しの場所に戻ることを示す
• return 文で書いた式の値が，呼び出し側に返される
（例）return;
return 29;
← 何も返さない
← 29 を返す
return num_days[m-1]; ← num_days[m-1] を返す
29


# Page. 30

![Page Image](https://bcdn.docswell.com/page/PJXMR9QDEX.jpg)

void の意味
• 関数には，型がある
•
•
•
•
int
double
void など
但し，void は，「関数が return 文で，何も返さな
いこと（値を返さない関数）」 を示す
例） void print_calendar( int num_days, int youbi )
• void で関数定義したら，return の次に式を書
かない（ 「return;」 ）．
30


# Page. 31

![Page Image](https://bcdn.docswell.com/page/3JKGRP9D7D.jpg)

関数から返された値の使い方
n = num_of_day(y, m);
関数呼び出し
num_of_day 関数から返された値が n に入る
• 関数は，一種の「式」であって，「値」を持
つ
• この「値」が，関数から返された値
31


# Page. 32

![Page Image](https://bcdn.docswell.com/page/LE3N8XWPE5.jpg)

例題３．１か月分のカレンダー
• 日数と曜日から，１か月分のカレンダーを表示す
る関数を作る
• 日数は，２８，２９，３０，３１ のいずれか
• 曜日は，０，１，…，６ のいずれか
• 表示される日付は，２桁の幅とし，それぞれの間に１
つの空白を置くこと．
32


# Page. 33

![Page Image](https://bcdn.docswell.com/page/8EDWM2K37G.jpg)

#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
void print_calendar( int num_days, int youbi )
{
int i;
int d;
int x;
if ( ( num_days &lt; 28 ) || ( num_days &gt; 31 ) || ( youbi &lt; 0 ) || ( youbi &gt; 6 ) )
{
渡された値がおかしいときは，
return;
何もせずに終わる
}
}
for ( i = 0; i &lt; ( youbi * 3 ); i++ ) {
曜日の分だけ空白を表示
printf( &quot; &quot; );
}
d = 1;
x = youbi;
do {
日付を書く
printf( &quot;%2d &quot;, d );
d++;
if ( x == 6 ) {
printf( &quot;\n&quot; );
土曜日に来たら改行する
x = 0;
}
else {
x++;
}
月末まで書いたら終える
} while ( d &lt;= num_days );
return;
33


# Page. 34

![Page Image](https://bcdn.docswell.com/page/V7P9R1KPJ8.jpg)

前のページからの続き
int main()
{
int num_days;
int youbi;
printf( &quot;num_days=&quot; );
scanf( &quot;%d&quot;, &amp;num_days );
printf( &quot;youbi=&quot; );
scanf( &quot;%d&quot;, &amp;youbi );
print_calendar( num_days, youbi );
return 0;
}
34


# Page. 35

![Page Image](https://bcdn.docswell.com/page/2JVMRYVVJQ.jpg)

１か月分のカレンダー
実行結果の例
num_days=30
youbi=4
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30
35


# Page. 36

![Page Image](https://bcdn.docswell.com/page/5EGGM9L1EL.jpg)

関数呼び出しの流れ
main 関数
int main()
関数呼び出し
print_calendar(num_days,
youbi);
num_of_day 関数
void print_calendar( int num_days, int youbi )
戻り
return;
渡された値が
おかしいとき
return;
36


# Page. 37

![Page Image](https://bcdn.docswell.com/page/4JQXRWYNEP.jpg)

プログラム実行順
print_calendar 関数
main 関数
void print_calendar( int num_days, int youbi )
int main()
関数
呼び出し
if( ・・・ ) Yes
No
return;
print_calendar( num_days, youbi );
１か月分のカレンダーの表示
戻り
return;
37


# Page. 38

![Page Image](https://bcdn.docswell.com/page/K7468KW3E1.jpg)

1か月分のカレンダーの表示
「曜日」の分だけ空白を表示
日付を書く
書いた日付は土曜日か？
Ｎｏ
Ｙｅｓ
改行する
日付を１足す
日付を０にする
日付が「日数」を超えたか？Ｎｏ
Ｙｅｓ
38


# Page. 39

![Page Image](https://bcdn.docswell.com/page/LJ1V2XYZEG.jpg)

例題４．月初めの曜日
• ツエラーの公式を使い，年と月から，月初め
の曜日を求める関数を作る
• 曜日は，０，１，…，６ のいずれか
０：日曜日
１：月曜日
２：火曜日
３：水曜日
４：木曜日
５：金曜日
６：土曜日
39


# Page. 40

![Page Image](https://bcdn.docswell.com/page/GJWLRNG6E2.jpg)

月初めの曜日
#include &lt;stdio.h&gt;
#pragma warning(disable:4996)
int zeller( int y, int m, int d )
{
if ( ( m == 1 ) || ( m == 2 ) ) {
y = y - 1;
m = m + 12;
}
return (y + (y/4) - (y/100) + (y/400) + ((13 * m + 8 ) / 5) + d) % 7;
}
int first_day( int y, int m )
{
return zeller( y, m, 1 );
}
int main()
{
int y;
int m;
int f;
printf( &quot;y=&quot; );
scanf( &quot;%d&quot;, &amp;y );
printf( &quot;m=&quot; );
scanf( &quot;%d&quot;, &amp;m );
f = first_day(y, m);
printf( &quot;first days(%d, %d) = %d\n&quot;, y, m, f);
return 0;
}
40


# Page. 41

![Page Image](https://bcdn.docswell.com/page/4EZMR3LRJ3.jpg)

例題５．カレンダー
• 年と月から，カレンダーを表示するプログラ
ムを作る
41


# Page. 42

![Page Image](https://bcdn.docswell.com/page/Y76NRXW17V.jpg)

「カレンダー」のプログラムの関数分
割
•
役割ごとに，関数を作る．
1. 本体
2. 月の日数
3. 月初めの曜日
4. １ヶ月分のカレンダー
42


# Page. 43

![Page Image](https://bcdn.docswell.com/page/G7558XML74.jpg)

カレンダー
年
月
月の日数
例題２で
作成済み
日数
年
main関数
月
main関数
のみを新規
に作成
曜日
日数
曜日
月初めの
曜日
１か月分の
カレンダー
例題４で
作成済み
例題３で
作成済み
43


# Page. 44

![Page Image](https://bcdn.docswell.com/page/9J2NKX93ER.jpg)

コメントでおおまかな処理を書く
int main()
{
/* 年と月を読み込む */
/* 年と月から「月の日数」を求める */
/*年と月から「月初めの曜日」を求める */
/* 「月の日数」と「月初めの曜日」からカレンダーを表示す
る */
return 0;
}
44


# Page. 45

![Page Image](https://bcdn.docswell.com/page/DEYPN848EM.jpg)

コメント
• コメントは，プログラムの中に書く注釈のこと．
• プログラムの説明や使用上の注意などを書く．
• コメントは，プログラム実行では無視される．
• コメントの始まりは／＊で，終わりは＊／である．あ
るいは／／を使って，１行分のコメントを書くことも
ある．コメントは，入れ子にすることができない．
• 次のコメントは入れ子になっていて，間違いである．
/* n = n + 1; /* n は「空き領域」の先頭を指す */ */
45


# Page. 46

![Page Image](https://bcdn.docswell.com/page/VJN5XQY978.jpg)

warning(disable:4996)
カレンダー#pragma
int main()
{
int y;
int m;
int nissu;
int youbi1;
/* 年と月を読み込む */
printf( &quot;y=&quot; );
scanf( &quot;%d&quot;, &amp;y );
printf( &quot;m=&quot; );
scanf( &quot;%d&quot;, &amp;m );
printf( &quot;日 月 火 水 木 金 土\n&quot; );
/* 年と月から「月の日数」を求める */
nissu = num_of_day(y, m);
/*年と月から「月初めの曜日」を求める */
youbi1 = first_day(y, m);
/* 「月の日数」と「月初めの曜日」からカレンダーを表示する */
print_calendar( nissu, youbi1 );
return 0;
}
46


# Page. 47

![Page Image](https://bcdn.docswell.com/page/YE9Y8DP3J3.jpg)

－関数と変数－
データ
変数
処理手順
関数
プログラム
main 関数
ライブラリ関数
（printf, scanf など）
ユーザが自分で
定義した関数
47


# Page. 48

![Page Image](https://bcdn.docswell.com/page/GE8683DL7D.jpg)

関数の種類
• main関数
• プログラムは，main 関数を必ず含む
• ライブラリ関数
• システムに既に組み込まれた関数
• ユーザが定義した関数
• プログラマが独自の関数を定義可能
48


