先週に引き続き関数を取り上げます.
よく使う関数を用意しておこう.
1.二つの整数を渡すと,大きい方を答える関数
2.整数の2乗を計算する関数
3.整数の3乗を計算する関数
4.整数のn乗を計算する関数
#include <stdio.h>
int large(int a, int b)
{
if(a>b){
return a;
}else{
return b;
}
}
int square(int a)
{
return a*a;
}
int cube(int a)
{
return a*a*a;
}
int power(int a, int n)
{
int i, pow=1;
if(a==0){
return 0;
}else{
for(i=0; i<n; i++){
pow *= a;
}
return pow;
}
}
void main()
{
int a, b, n;
printf("aの値を入力してください:");
scanf("%d", &a);
printf("bの値を入力してください:");
scanf("%d", &b);
printf("n乗のnの値を入力してください:");
scanf("%d", &n);
printf("大きい数の値は%d\n", large(a, b));
printf("aの2乗は%d\n", square(a));
printf("bの3乗は%d\n", cube(b));
printf("aの%d乗は%d\n", n, power(a, n));
printf("a^3 + b^2 + a^n =%d", cube(a) + square(b) + power(a,n));
}
これまでは,一つの値しか関数から戻すことができなかった.また,同じ変数名を使っていても,関数の方で値を変えても,mainでは変化しなかった.これは,関数には変数の中身が伝えられているためです.
今回は,関数から複数の値を戻したい場合や,文字列や配列データを渡したい場合を考えよう.この場合,関数に変数のしまってある場所を伝え,その場所のデータを関数で使うようにすれば,よいと考えられる.
変数のしまってある場所(アドレス)を扱うのは,ポインタの出番です.
ポインタを用いて,変数の場所を関数に渡したプログラムの例です.
#include <stdio.h>
int test2(int *a) /* 変数aのアドレスを受け取る(ポインタ変数) */
{
*a += 10; /*aの指すアドレスの中身に1を加えるから,main関数でも変化する */
return *a;
}
void main()
{
int a, b;
printf("aの値を入力してください:");
scanf("%d", &a);
printf("関数へ渡す前のaの値は,%dです\n", a);
b = test2(&a); /* 変数aのアドレスを関数に渡す */
printf("関数から戻ると...\naの値は%d\nbの値は%d\n", a, b);
}
aに2を入力すると,どのように関数にわたり,
ポインタを用いて,アドレスを関数に渡せることがわかりました.
では,関数に配列データを渡してみましょう.
まずは,入力された文字の長さを返す関数を作ってみましょう.
配列を受け渡している例を見てください.
#include <stdio.h>
void dim_init(int *ary, int no, int val)
{
int i;
for(i = 0; i < no; i++){
ary[i] = val;
}
}
void main()
{
int i;
int ary[] = {1,2,3,4,5};
dim_init(ary, 5, 0);
for(i =0; i < 5; i++){
printf("ary[%d] = %d\n", i, ary[i]);
}
}
このプログラムは,配列aryの先頭からno番目までの要素の値をvalに設定する関数です.関数の初期化などの際に用います.関数には,配列の先頭のアドレス(ary)が渡されるので,関数側ではポインタ(int *ary)で受け取っています.関数で変更の加えられたデータは,特に戻り値を指定していませんが,main関数では,その変更が反映されます.
文字列は,配列として扱うことを思い出してください.関数に文字列を受け渡すには,上記の配列の場合と同様,ポインタを用います.
ここで,文字の長さを数えるプログラムを関数を用いて書き換えてみよう.
#include <stdio.h>
void main()
{
char str[128];
int i;
printf("文字列を入力してください:");
scanf("%s", str);
for(i = 0; str[i] != 0x00; i++);
printf("入力された文字列は,%sです.", str);
printf("文字数は,%dです.",i);
}
ここで,青い色の部分を関数にしてみよう.
#include <stdio.h>
int moji_nagasa(char *str)
{
int i;
for(i = 0; str[i] != 0x00; i++);
return(i);
}
void main()
{
char str[128];
int i;
printf("文字列を入力してください:");
scanf("%s", str);
printf("入力された文字列は,%sです.", str);
printf("文字数は,%dです.", moji_nagasa(str));
}
(2) 配列の要素の和を求める関数を作成せよ.
(3) ある文字列を入力したとき,文字数を数える関数を利用して,文字を逆に並べ替える関数を作成せよ.