第9章 標準ライブラリ関数

1 ANSIライブラリ

教科書P208〜210

1-1 標準ライブラリとは

今まで普通にprintfやscanfなどの関数を使っていたが、これらの関数は自作関数を作るのと同じ方法で、コンパイラを提供しているメーカーが作ったものである。標準ライブラリ関数はあらかじめコンパイルされ、オブジェクトライブラリとして提供されているため、プログラムのリンク時、自動的に結合される

1-2 ANSIライブラリ

ANSI Cで定められた関数群。プログラム内で#includeを宣言することにより、指定したライブラリ内の関数を使うことができる

#include <stdio.h>

stdio.hライブラリを取り込むという指定。これにより、stdio.h内にある関数を利用できる。

[ANSIライブラリの種類(抜粋)]

1.stdio.h
標準入出力関数をまとめたもの
2.string.h
文字列操作関数をまとめたもの
3.ctype.h
文字操作関数をまとめたもの
4.time.h
時間に関する関数をまとめたもの
5.math.h
数値演算(算術計算)に関する関数をまとめたもの
6.stdlib.h
その他標準的に使う関数をまとめたもの

教科書209〜210ページを参照

2 算術関数

教科書P211〜213

2-1 組み込み方

算術関数(数値演算関数)を使用するには、math.hをインクルードする。

#include <math.h>

※算術関数のプロトタイプ宣言が行われているヘッダ・ファイル

[代表的な関数(抜粋)]

関数概要引数の型関数の型
abs(引数)引数の絶対値intint
acos(引数)引数のアークコサイン
(引数は−1〜1)
doubledouble
atan(引数)引数のアークタンジェント
(引数は−1〜1)
doubledouble
cos(引数)引数のコサイン
(引数の単位はラジアン)
doubledouble
exp(引数)指数e引数doubledouble
fabs(引数)引数の絶対値doubledouble
pow(引数1, 引数2)べき乗 引数1引数2doubledouble
sin(引数)引数のサイン
(引数の単位はラジアン)
doubledouble
sqrt(引数)引数の平方根doubledouble
tan(引数)引数のタンジェント
(引数の単位はラジアン)
doubledouble

[例1] 2の8乗を求める

#include     <stdio.h>
#include     <math.h>

void main(void)
{
    double a=2.0, b=8.0;
    printf("%fの%f乗は%f\n", a, b, pow(a, b));

}

[例2] x0のsin値を求める

#include     <stdio.h>
#include     <math.h>

void main(void)
{
    double x;

    scanf("%f", &x);
    printf("sin(%f) = %f\n", x, sin(x * 3.1415927 / 180.0));

}

練習問題

教科書213ページ練習問題46

3 文字列処理関数

教科書P216〜219

3-1 組み込み方

文字列処理関数を使用するには、string.hをインクルードする。

#include <string.h>

※文字列処理関数のプロトタイプ宣言が行われているヘッダ・ファイル

[代表的な関数(抜粋)]

関数概要引数の型関数の型
strcpy(引数1, 引数2)配列1に配列2をコピーchar *char *
strcat(引数1, 引数2)配列1に配列2を連結char *char *
strcmp(引数1, 引数2)文字列1と文字列2の大小比較char *int
strlen(引数)文字列の長さを返すchar *unsigned int

[char *型の引数について]

文字列操作関数に与える引数として、次のような種類がある。

3-2 各関数の説明

●文字列のコピー(strcpy)

《構文》
strcpy(s, t)
《引数》

s・・・コピー先を示すポインタ(char *)
t・・・コピー元を示すポインタ(char *)

《機能概要》

ポインタsで示される領域に、ポインタtで示される文字列(の実体)をコピーする。

《POINT》
《使用例》
/* 文字列のコピー */
#include     <stdio.h>
#include     <string.h>

void main(void)
{
    char str1[80], str2[80];

    gets(str1);
    strcpy(str2, str1);
    printf("str1 : %s\n", str1);
    printf("str2 : %s\n", str2);

}

●文字列の連結(strcat)

《構文》
strcat(s, t)
《引数》

s・・・連結先を示すポインタ(char *)
t・・・連結元を示すポインタ(char *)

《機能概要》

ポインタsで示される領域に格納されている文字列の後ろに、ポインタtで示される文字列(の実体)をコピーする。

《POINT》
《使用例》
/* 文字列の連結 */
#include     <stdio.h>
#include     <string.h>

void main(void)
{
    char str1[80], str2[80];

    gets(str1);
    gets(str2);
    strcpy(str1, str2);
    printf("str1 : %s\n", str1);
    printf("str2 : %s\n", str2);

}

●文字列の比較(strcmp)

《構文》
strcmp(s, t)
《引数》

s・・・比較する文字列を示すポインタ(char *)
t・・・比較する文字列を示すポインタ(char *)

《機能概要》

文字列sとtを比較し、その結果を次の値(int型)で返す。
比較結果返す値
s>t正の数(0より大きい値)
s=t
s<t負の数(0より小さい値)

《POINT》
《使用例》
/* 文字列の比較 */
#include     <stdio.h>
#include     <string.h>

void main(void)
{
    char str1[80], str2[80];

    gets(str1);
    gets(str2);
    if (strcmp(str1, str2) == 0)
        printf("一致\n");
    else
        printf("不一致\n");

}

●文字列の長さを取得(strlen)

《構文》
strlen(s)
《引数》

s・・・長さを取得したい文字列を示すポインタ(char *)

《機能概要》

文字列sの長さを取得し、その結果を返す(unsigned int型)。

《POINT》
《使用例》
/* 文字列の長さを取得 */
#include     <stdio.h>
#include     <string.h>

void main(void)
{
    char str[80];

    gets(str);
    printf("文字列「%s」の長さは %d \n", str, strlen(str));

}

練習問題

  1. 教科書219ページ練習問題48
  2. 2つの文字列を入力し、連結して3つ目の文字配列に格納する関数を作成せよ。
    /* インクルードファイル */
    ここを考える
    
    /* プロトタイプ宣言 */
    void strcpy2(char *, char *, char *);
    
    void main(void)
    {
        char str1[80], str2[80], str3[80];
    
        gets(str1);
        gets(str2);
        strcat2(str3, str1, str2);
        printf("str1 = %s\n", str1);
        printf("str2 = %s\n", str2);
        printf("str3 = %s\n", str3);
    
    }
    
    ここから関数を作成する
    ・
    ・
    ・

4 文字検査・変換マクロ

教科書P220〜222

4-1 組み込み方

文字検査・変換マクロを使用するには、ctype.hをインクルードする。

#include <ctype.h>

※文字検査・変換マクロが定義されているヘッダ・ファイル

4-2 文字検査・変換マクロの紹介

[文字検査マクロ(is〜)]

《機能概要》

引数に与えられた文字を調べ、検査項目を満たせば真(0以外)、満たさなければ偽(0)を返す。

《文字検査マクロの種類(抜粋)》
マクロ概要
isalpha(文字)文字が英字('A'〜'Z', 'a'〜'z')かどうかを調べる
isalnum(文字)文字が英数字('A'〜'Z', 'a'〜'z', '0'〜'9')かどうかを調べる
isascii(文字)文字がASCIIコード(0x00〜0x7f)かどうかを調べる
iscntrl(文字)文字がコントロールコード(0x00〜0x1f, 0x7f)かどうかを調べる
ヌル文字('\0')や改行文字('\n')など
isdigit(文字)文字が数字('0'〜'9')かどうかを調べる
islower(文字)文字が英小文字('a'〜'z')かどうかを調べる
isupper(文字)文字が英大文字('A'〜'Z')かどうかを調べる
isspace(文字)文字がスペース(空白文字)かどうかを調べる
(0x09〜0x0d, 0x20)
isxdigit(文字)文字が16進文字('0'〜'9', 'A'〜'F', 'a'〜'f')かどうかを調べる
《使用例》
#include     <stdio.h>
#include     <ctype.h>

void main(void)
{
    char c;
    scanf("%c", &c);
    if (isalpha(c) != 0)
        printf("文字「%c」は英字\n", c);
    else
        printf("文字「%c」は英字以外の文字\n", c);

}

[文字変換マクロ(to〜)]

《機能概要》

引数に与えられた文字を調べ、検査項目を満たせば指定の文字に変換した文字を返す。満たさなければ与えられた文字をそのまま返す。

《文字変換マクロの種類(抜粋)》
マクロ概要
tolower(文字)文字が英大文字('A'〜'Z')なら小文字に変換
toupper(文字)文字が英小文字('a'〜'z')なら大文字に変換
《使用例》
#include     <stdio.h>
#include     <ctype.h>

void main(void)
{
    char c;
    scanf("%c", &c);
    printf("変換前:%c\n", c);
    if (islower(c) != 0)
        c = toupper(c);
    printf("変換後:%c\n", c);

}

練習問題

教科書222ページ練習問題49

5 乱数

教科書P214〜215

5-1 組み込み方

乱数(決められた範囲内の任意の値)を発生させるための標準ライブラリ関数を紹介する。

関数機能引数の型関数の型
rand()0〜32767(int型の正の最大)の整数乱数を発生voidint
srand(引数)乱数列の開始点を引数によりセットunsigned intvoid

[使用例]

#include     <stdio.h>
#include     <stdlib.h>

void main(void)
{
    int     i;

    for (i=0 ; i<10 ; i++)
        printf("%d\n", rand());

}

5-2 任意の範囲内で乱数を発生させるには?

rand関数は、0から32767のいずれかの値を返す。では、例えばさいころの数(1から6のいずれか)のように、指定した範囲内の値を発生させるにはどうすればよいかを考える。

[手順1] 0から任意の値までの乱数を求める

rand関数から返ってくる値を、任意の値+1で割った余りを求めると、0から任意の値までの整数になる。

《例》0から6までの範囲で乱数を発生させる
rnd = rand() % (6 + 1);

※7で割った場合の余りは0,1,2,3,4,5,6のいずれかになる

[手順2] 任意の範囲内で乱数を求める

0から任意の値までの乱数は出せれるようになった。では、下限から上限までの範囲で乱数を発生させるにはどうすればよいかを考える。
例えば下限が1、上限が6の範囲で乱数を発生させるには、0から5(上限−下限)の乱数に1(下限)を加算すればよい。

《例》1から6までの範囲で乱数を発生させる
rnd = 1 + rand() % (6 - 1 + 1);

※0から5の範囲で発生させた乱数に1を足すことにより、1から6の範囲になる

[乱数発生の構文]

つまり、範囲を指定した乱数発生の構文は次のようになる。

《構文》

乱数の値 = 下限の値 + rand() % (上限の値 − 下限の値 + 1);

5-3 srand関数の利用方法

1の使用例のプログラムは、実は何回実行しても同じ値の乱数が発生してしまう。これは、rand関数を呼び出す際、乱数列の開始点を指定していないため、一番最初から表示してしまうためである。
乱数列の開始点を指定するには、srand関数を利用する。

[使用例2(開始点を入力する)]

#include     <stdio.h>
#include     <stdlib.h>

void main(void)
{
    int     i, seed;

    printf("seed = ");
    scanf("%d", &seed);
    srand(seed);

    for (i=0 ; i<10 ; i++)
        printf("%d\n", rand());

}

※入力する値を変えるたびに、出てくる乱数が変わる

[応用]

使用例2のプログラムでは、開始点を入力しなければならないので、実際のプログラムでは使いにくい。そこで、システム時間を利用して、実行するたびに違う値になるようプログラムを改造する。

#include     <stdio.h>
#include     <stdlib.h>
#include     <time.h>

void main(void)
{
    int     i;
    time_t  nt;

    srand(time(&nt));

    for (i=0 ; i<10 ; i++)
        printf("%d\n", rand());

}

[ TOP ]