[C言語 標準ライブラリ] stdlib.hの使い方

※本ブログでは、商品・サービスのリンク先にプロモーションを含みます。

スポンサーリンク

stdlib.hは一般的な実用性を持つマクロ、型、関数が宣言および定義されています。

スポンサーリンク

マクロ

NULL

空(NULL)ポインタ定数です。
stddef.h、locale.h、stdio.h、stdlib.h、string.h、time.h、wchar.hで定義されています。

EXIT_FAILURE

失敗終了状態であることを示します。
exit関数の実引数として使用します。

EXIT_SUCCESS

成功終了状態であることを示します。
exit関数の実引数として使用します。

RAND_MAX

rand関数が返す最大値を示します。

MB_CUR_MAX

その時のロケール(LC_CTYPEカテゴリ)の拡張文字集合におけるマルチバイト文字の最大バイト数を表す正の整数式に展開されるオブジェクト形式のマクロです。
この値がMB_LEN_MAXを超えることはありません。

size_t

sizeof演算子が生成する結果を表すための符号無し整数型です。
stddef.h、stdio.h、stdlib.h、string.h、time.h、wchar.hで定義されます。

wchar_t

処理系がサポートするロケールの中で最も大きな拡張文字集合のすべての要素に対して、区別可能なコードを表現できる値の範囲をもつ整数型です。
この型では、NULL文字はコード値0を持ちます。
stddef.h、stdlib.h、wchar.hで定義されます。

div_t

div関数が返す値を表す型です。
次のメンバを含む構造体です。

メンバ名説明
intquot商です。
intrem剰余です。

ldiv_t

ldiv関数が返す値を表す型です。
次のメンバを含む構造体です。

メンバ名説明
longquot商です。
longrem剰余です。

lldiv_t

lldiv関数が返す値を表す型です。
次のメンバを含む構造体です。

メンバ名説明
long longquot商です。
long longrem剰余です。
スポンサーリンク

数値変換関数

double atof(const char *nptr)

引数nptrが指す文字列をdouble型フォーマットに変換します。
エラー時の動作を除けば、以下の関数と同等です。

strtod(nptr, (char **)NULL);

変換された値が返されます。

使用例:

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

int main(void)
{
    const char *str1 = "123.456";
    const char *str2 = "789.012";

    double num1 = atof(str1);
    double num2 = atof(str2);

    printf("%f + %f = %f\n", num1, num2, num1 + num2);

    return 0;
}

実行結果:

123.456000 + 789.012000 = 912.468000

int atoi(const char *nptr)

定義:

int atoi(const char *str);             // int版
long int atol(const char *str);        // long版
long long int atoll(const char *str);  // long long版

引数nptrが指す文字列をint型フォーマットに変換します。
エラー時の動作を除けば、以下の関数と同等です。

strtol(nptr, (char **)NULL, 10);

strtol(nptr, (char **)NULL, 10);

strtoll(nptr, (char **)NULL, 10)

変換された値が返されます。

使用例:

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

int main(void)
{
    const char *str1 = "123";
    const char *str2 = "789";

    int num1 = atoi(str1);
    int num2 = atoi(str2);

    printf("%d + %d = %d\n", num1, num2, num1 + num2);

    return 0;
}

実行結果:

123 + 789 = 912

double strtod(const char *nptr, char **endptr)

定義:

float strtof(const char *nptr, char **endptr);         // float版
double strtod(const char *nptr, char **endptr);        // double版
long double strtold(const char *nptr, char **endptr);  // long double版

引数nptrが指す文字列をdouble型フォーマットに変換します。
まず、入力文字列が次の3つに分けられます。
・最初の省略可能な空白の連続
・変換の対象となる浮動小数点定数の形をした部分(この部分を以後「主体」と呼ぶ)
・最後にあるNULL文字を含む認識されない文字列。
次に、主体となる部分を浮動小数点数に変換し、結果が返されます。

変換可能な主体の形は次の通りです。
・省略可能な正か負の符号
・それに続く数字の連なり
・省略可能な指数部
前述の主体が取るべき形は、空白以外の文字で始まる入力内で最長の部分文字列として定義されます。
入力文字列の中身が無いとか、空白ばかりであるとか、最初の空白でない文字が符号や数字や小数点でない場合には、主体はありません。

主体が変換可能であれば、最初の数字か小数点から後は、以下の点を除いて浮動小数点定数と同じように解釈されます。すなわち、小数点はピリオドとして扱われ、小数点も指数部も無い場合には数字の最後の桁の後に小数点があるものとして扱われます。主体が負の符号で始まる場合、変換後の数値は負になります。
endptrがNULLでなければ、最後の文字列へのポインタがendptrが指すオブジェクトに格納されます。

“C”ロケール以外では処理系定義の主体の形が追加対応されていてもよい。

主体がない場合や変換可能でない場合は変換は行われず、endptrがNULLでなければ、nptrの値がendptrが指すオブジェクトに格納されます。

存在するならば変換された値が返されます。
変換できなかった場合は、0が返されます。
本来の数値が表現可能な範囲を超えていた場合は、正か負のHUGE_VALが返され、errnoにはERANGEが格納されます。
アンダーフローを起こした場合は、0が返され、errnoにはERANGEが格納されます。

使用例:

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

int main(void)
{
    const char *str1 = "123.456";
    const char *str2 = "789.012xyz";

    char *endptr;

    errno = 0; // errnoをリセット
    double num1 = strtod(str1, &endptr);
    if(errno == ERANGE){
        printf("オーバーフローが発生しました。(%s)\n", str1);
        return 1;
    }

    if(endptr == str1){
        printf("桁の数字が見つかりませんでした。(%s)\n", str1);
        return 1;
    }

    errno = 0; // errnoをリセット
    double num2 = strtod(str2, &endptr);
    if(errno == ERANGE){
        printf("オーバーフローが発生しました。(%s)\n", str2);
        return 1;
    }

    if(endptr == str2){
        printf("桁の数字が見つかりませんでした。(%s)\n", str2);
        return 1;
    }

    printf("認識できない文字(%c)\n", *endptr);
    printf("%f + %f = %f\n", num1, num2, num1 + num2);

    return 0;
}

実行結果:

認識できない文字(x)
123.456000 + 789.012000 = 912.468000

このプログラムでは、まず文字列 “123.456” と “789.012xyz” を定義します。そして、strtod関数でそれらの文字列をdouble型の浮動小数点数に変換します。変換は数値が見つかるところまで行われ、数値に続く最初の未認識文字は endptr が指す場所になります。したがって、endptr が元の文字列と同じ場所を指している場合、変換が行われていないことを示します。また、変換中にオーバーフローが発生した場合、errnoがERANGEに設定されるので、それをチェックします。最後に読み込んだ数字とその和を表示します。

long int strtol(const char *nptr, char **endptr, int base)

定義:

long int strtol(const char *nptr, char **endptr, int base);              // int版
unsigned long strtoul(const char *nptr, char **endptr, int base);        // unsigned long版
long long strtoll(const char *nptr, char **endptr, int base);            // long long版
unsigned long long strtoull(const char *nptr, char **endptr, int base);  // unsigned long long版

引数nptrが指す文字列の最初の部分をlong int型フォーマットに変換します。
まず、入力文字列が次の3つに分けられます。
・最初の、省略可能な空白の連続
・変換の対象となるbaseによるある基数の整数定数の形をした部分(この部分を以後「主体」と呼ぶ)
・最後にあるNULL文字を含む認識されない文字列
次に、主体となる部分を整数に変換し、結果が返されます。

baseの値が0ならば、変換可能な主体の形は以下の点を除いた整数定数と同じです。
すなわち、省略可能な正か負の符号を持てるということと、整数接尾辞がないということです。
baseの値が2と36の間であれば、変換可能な主体の形は以下の点を満たすbaseを基数とする文字と数字の連続です。
すなわち、省略可能な正か負の符号を持てるということと、整数接尾辞がないということです。
a(またはA)からz(またはZ)までの文字は10から35までの数値を表します。
表す数字がbaseより小さい文字のみ許されます。
baseの値が16なら、0xまたは0Xの接頭辞が符号の後にについていてもよい。

前述の主体が取るべき形は、空白以外の文字で始まる入力内で最長の部分文字列として定義されます。
入力文字列の中身が無いとか、空白ばかりであるとか、最初の空白でない文字が符号や許される文字や数字でない場合には、主体はありません。

主体が変換可能でbaseの値が0ならば、最初の数字から後は整数定数と同じように解釈されます。
主体が変換可能でbaseの値が2と36の間であれば、これは変換の基数として使われ、各文字の値は前述した通りです。
主体が負の符号で始まる場合、変換後の数値は負になります。
endptrがNULLでなければ、最後の文字列へのポインタがendptrが指すオブジェクトに格納されます。

“C”ロケール以外では処理系定義の主体の形が追加対応されていてもよい。

主体がない場合や変換可能でない場合は変換は行われず、endptrがNULLでなければ、nptrの値がendptrが指すオブジェクトに格納されます。

存在するならば変換された値が返されます。
変換できなかった場合は、0が返されます。
本来の数値が表現可能な範囲を超えていた場合、LONG_MAXかLONG_MINが返され、errnoにはERANGEが格納されます。

使用例:

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

int main(void)
{
    const char *str1 = "123";
    const char *str2 = "789xyz";

    char *endptr;

    errno = 0; // errnoをリセット
    long num1 = strtol(str1, &endptr, 10);
    if(errno == ERANGE){
        printf("オーバーフローが発生しました。(%s)\n", str1);
        return 1;
    }

    if(endptr == str1){
        printf("桁の数字が見つかりませんでした。(%s)\n", str1);
        return 1;
    }

    errno = 0; // errnoをリセット
    long num2 = strtol(str2, &endptr, 10);
    if(errno == ERANGE){
        printf("オーバーフローが発生しました。(%s)\n", str2);
        return 1;
    }

    if(endptr == str2){
        printf("桁の数字が見つかりませんでした。(%s)\n", str2);
        return 1;
    }

    printf("認識できない文字(%c)\n", *endptr);
    printf("%ld + %ld = %ld\n", num1, num2, num1 + num2);

    return 0;
}

実行結果:

認識できない文字(x)
123 + 789 = 912

このプログラムでは、まず文字列 “123” と “789xyz” を定義します。そして、strtol関数でそれらの文字列をlong int型の整数に変換します。変換は数値が見つかるところまで行われ、数値に続く最初の未認識文字は endptr が指す場所になります。したがって、endptr が元の文字列と同じ場所を指している場合、変換が行われていないことを示します。また、変換中にオーバーフローが発生した場合、errnoがERANGEに設定されるので、それをチェックします。最後に読み込んだ数字とその和を表示します。

スポンサーリンク

擬似乱数列生成関数

int rand(void)

0~RAND_MAXの間の連続擬似乱数を発生させます。
整数の擬似乱数が返されます。
(RAND_MAXマクロ値は32767以上です)

使用例:

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

int main(void)
{
    srand(time(NULL));  // 乱数生成器の初期化

    for(int i=0; i<10; i++) {
        int random_number = rand();  // ランダムな整数の生成
        printf("%d\n", random_number);
    }

    return 0;
}

実行結果:

8508
29891
12554
6934
30204
31002
22403
23407
12003
8395

このプログラムは、10個のランダムな整数を生成し、それらを表示します。srand関数の引数には現在の時刻(time(NULL))を使用しているため、プログラムが実行されるたびに異なる数値が生成されます。

しかし、rand関数は生成する乱数の品質があまり高くないという問題があります。高品質の乱数が必要な場合は、より良い乱数生成アルゴリズムを実装するか、それを提供するライブラリを探すことをお勧めします。

void srand(unsigned int seed)

seedをrand関数が返す新しい乱数列のシードとして使用します。
srandが同じシード値で呼ばれるならば、乱数列も同じものが繰り返されます。
srandよりもrandが先に呼ばれた場合、srandに1を渡したのと同じ乱数列が発生します。

使用例はrand関数を参照してください。

記憶域管理関数

void *calloc(size_t nmemb, size_t size)

動的メモリを確保し、0クリアします。
nmemb個のsizeの大きさのオブジェクトの配列のための空間を確保します。
空間の全てのビットは0に初期化されます。
成功したときは確保された領域へのポインタが返され、失敗したときはNULLポインタが返されます。

使用例:

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

int main(void)
{
    int n = 10; // 配列の要素数
    int *array = (int*)calloc(n, sizeof(int)); // n要素のint型配列のメモリを確保

    // メモリ確保の確認
    if(array == NULL){
        printf("メモリの確保に失敗しました。\n");
        return 1;
    }

    // 配列の要素を表示
    for(int i=0; i<n; i++){
        printf("array[%d] = %d\n", i, array[i]);
    }

    // メモリの解放
    free(array);

    return 0;
}

実行結果:

array[0] = 0
array[1] = 0
array[2] = 0
array[3] = 0
array[4] = 0
array[5] = 0
array[6] = 0
array[7] = 0
array[8] = 0
array[9] = 0

void free(void *ptr)

確保された動的メモリ領域を開放します。
ptrが指す空間を確保されていない状態に戻します。
この領域は、以降の確保に使えるようになります。
ptrがNULLポインタである場合は何も起きません。
calloc、malloc、reallocのいずれの返り値でもなかった場合、 またはfreeかreallocによって領域が開放されていた場合の動作は未定義です。

使用例はmalloc関数を参照してください。

void *malloc(size_t size)

動的メモリを確保します。
sizeの大きさのオブジェクトのための空間を確保します。
オブジェクトの値は不定です。
成功したときは確保された領域へのポインタが返され、失敗したときはNULLポインタが返されます。

使用例:

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

int main(void)
{
    int n = 10;
    int *array = (int*)malloc(n * sizeof(int));  // n個のint型要素のメモリを確保

    // メモリ確保の確認
    if(array == NULL){
        printf("メモリの確保に失敗しました。\n");
        return 1;
    }

    // 配列に値を設定
    for(int i=0; i<n; i++){
        array[i] = i;
    }

    // 配列の要素を表示
    for(int i=0; i<n; i++){
        printf("array[%d] = %d\n", i, array[i]);
    }

    // メモリの解放
    free(array);
    array = NULL;  // ダングリングポインタを防ぐためにNULLを設定

    return 0;
}

実行結果:

array[0] = 0
array[1] = 1
array[2] = 2
array[3] = 3
array[4] = 4
array[5] = 5
array[6] = 6
array[7] = 7
array[8] = 8
array[9] = 9

void *realloc(void *ptr, size_t size)

動的メモリを再確保します。
ptrで指定されるオブジェクトのサイズをsizeに変更します。
変更前と後での小さいほうのサイズまでの内容は変化しません。
変更後のサイズのほうが大きかった場合、新たに確保された部分の内容は不定です。
ptrがNULLポインタであれば、この関数は引数にsizeを渡したmallocと同等です。
NULLポインタでなく、calloc、malloc、reallocのいずれの返り値でもないか、freeかreallocによって開放されていた場合の動作は未定義です。
確保できない場合、ptrの指すオブジェクトは変更されません。
sizeが0でptrがNULLポインタでない場合は、オブジェクトは開放されます。
成功したときは移動したかもしれない領域へのポインタが返され、失敗したときはNULLポインタが返されます。

使用例:

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

int main(void)
{
    int n = 5;
    int *array = (int*)malloc(n * sizeof(int));  // n個のint型要素のメモリを確保

    // メモリ確保の確認
    if(array == NULL){
        printf("メモリの確保に失敗しました。\n");
        return 1;
    }

    // 配列に値を設定
    for(int i=0; i<n; i++){
        array[i] = i;
    }

    // 配列を拡張する
    int new_n = n * 2;
    int *new_array = (int*)realloc(array, new_n * sizeof(int));  // メモリの再確保

    // メモリ確保の確認
    if(new_array == NULL){
        printf("メモリの再割り当てに失敗しました。\n");
        free(array);  // 元のメモリを解放
        return 1;
    }else{
        array = new_array;  // 新たに確保したメモリのアドレスを保存
    }

    // 新たに確保した領域に値を設定
    for(int i=n; i<new_n; i++){
        array[i] = i;
    }

    // 配列の要素を表示
    for(int i=0; i<new_n; i++){
        printf("array[%d] = %d\n", i, array[i]);
    }

    // メモリの解放
    free(array);

    return 0;
}

実行結果:

array[0] = 0
array[1] = 1
array[2] = 2
array[3] = 3
array[4] = 4
array[5] = 5
array[6] = 6
array[7] = 7
array[8] = 8
array[9] = 9
スポンサーリンク

環境に関連する関数

void abort(void)

プログラムの実行を中断します。
SIGABRTシグナルが捕らえられ、シグナルハンドラが返らない事態にならない限り、異常なプログラムの終了を引き起こします。
出力ストリームがフラッシュされるか、入力ストリームが閉じられるか、一時ファイルが削除されるかどうかは処理系定義です。
処理系定義の「非成功時の終了」状態がraise(SIGABRT)によって実行環境に返されます。
この関数は、呼び出し元に戻ることはありません。

使用例:

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

// ファイルを開いて、その内容を表示する関数
void print_file(const char *filename)
{
    FILE *file = fopen(filename, "r");
    if(file == NULL){
        fprintf(stderr, "ファイルオープンに失敗しました。(%s)\n", filename);
        abort();
    }

    char ch;
    while((ch = fgetc(file)) != EOF){
        putchar(ch);
    }

    fclose(file);
}

int main(void)
{
    // 存在しないファイルを開こうとする
    print_file("non_existent_file.txt");

    return 0;
}

実行結果:(VisualStudioのデバッグモードで実行した場合、以下のウィンドウが表示されます)

int atexit(void (*func)(void))

funcが指す関数の終了時に、引数なしで呼び出されるように登録します。
登録に成功すれば0が返され、失敗すれば0以外が返されます。
処理系は少なくとも32個の関数を登録できなければなりません。

使用例:

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

// プログラム正常終了時に呼ばれる関数
void on_exit(void)
{
    printf("プログラムが正常終了しました。\n");
}

int main(void)
{
    // on_exit関数を終了時に実行する関数として登録
    if(atexit(on_exit) != 0){
        fprintf(stderr, "atexitの登録に失敗しました。\n");
        return 1;
    }

    printf("Hello, World!\n");

    return 0;
}

実行結果:

Hello, World!
プログラムが正常終了しました。

void exit(int status)

プログラムの正常終了を引き起こします。
2度以上exitが呼ばれた場合の動作は未定義です。
まず、全てのatexitによって登録された関数が、登録されたのとは逆の順番で実行されます。
次に、全ての書かれていないバッファにためられたデータをもつ開いたストリームはフラッシュされ、 全ての開いたストリームは閉じられ、tmpfileによって作られた一時ファイルは削除されます。
最後に、制御は実行環境に戻ります。
statusの値が0かEXIT_SUCCESSであれば、処理系定義の「成功時の終了」状態が返されます。
EXIT_FAILUREであれば、処理系定義の「非成功時の終了」状態が返されます。
他の場合の返される状態は処理系定義です。
この関数は、呼び出し元に戻ることはありません。

使用例:

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

int main(void)
{
    FILE *file = fopen("non_existent_file.txt", "r");
    if(file == NULL){
        fprintf(stderr, "ファイルオープンに失敗しました。\n");
        exit(EXIT_FAILURE);  // プログラムを異常終了させる
    }

    // ファイルの内容を処理...

    fclose(file);

    exit(EXIT_SUCCESS);  // プログラムを正常終了させる
}

実行結果:

ファイルオープンに失敗しました。

void _Exit(int status)

正常プログラム終了を引き起こして制御をホスト環境に戻します。
以下のものは呼び出されません。
・atexit関数で登録された関数
・at_quick_exitで登録された関数(C11)
・signal関数で登録されたシグナル処理ルーチン
ホスト環境に戻される状態の決定は、exit関数での決定と同じ方法で行われます。
オープンしている出カストリームがフラッシュされるか、オープンしているストリームがクローズされるか、一時ファイルが削除されるかどうかは処理系定義です。

使用例:

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

int main(void)
{
    FILE *file = fopen("non_existent_file.txt", "r");
    if(file == NULL){
        fprintf(stderr, "ファイルオープンに失敗しました。\n");
        _Exit(EXIT_FAILURE);  // プログラムを即座に異常終了させる
    }

    // ファイルの内容を処理...

    fclose(file);

    _Exit(EXIT_SUCCESS);  // プログラムを即座に正常終了させる
}

実行結果:

ファイルオープンに失敗しました。

char *getenv(const char *name)

実行環境によって提供される環境変数リストからnameが指す文字列にマッチするものを検索します。
環境名の集合および環境リストを変更する方法は処理系定義です。
成功したときはマッチしたリスト要素に関連付けられた文字列へのポインタが返されます。
この文字列をプログラムが変更してはならないが、次のgetenvの呼び出しによって上書きされるかもしれません。
指定されたnameが見つからなかった場合は、NULLポインタが返されます。

使用例:

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

int main(void)
{
    // "PATH"環境変数の値を取得
    char *path = getenv("PATH");

    if(path == NULL){
        printf("環境変数のPATHが存在しません。\n");
    }else{
        printf("PATH: %s\n", path);
    }

    return 0;
}

実行結果:
環境変数「PATH」に値が表示されます。

int system(const char *string)

引数stringが指す文字列を実行環境に渡し、処理系定義の方法によってコマンドプロセッサに実行させます。
stringにNULLポインタを渡すことによってコマンドプロセッサの存在を問い合わせることができます。
引数がNULLポインタであった場合、コマンドプロセッサが使用可能な時のみ0以外の値が返されます。
引数がNULLポインタでなければ、処理系定義の値が返されます。

使用例:

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

int main(void)
{
    // システムコマンド 'echo' を実行する
    int result = system("echo Hello, World!");

    if(result == -1){
        printf("コマンドの実行に失敗しました。\n");
        return 1;
    }

    return 0;
}

実行結果:

Hello, World!

探索・整列ユーティリティ関数

char *bsearch(const void *key, const void base, size_t nmemb, size_t size, int (compar)(const void *, const void *))

配列の要素を二分法で検索します。
baseが最初の要素を指しているnmemb個の要素をもつ配列を検索し、keyが指すオブジェクトに適合するものを見つけます。
個々の配列の要素のサイズはsizeによって指定されます。
comparが指す比較関数の引数にはkeyと配列の要素がこの順番で渡されます。
keyの方が配列の要素より小さいか、等しいか、大きいかによって負、ゼロ、正の値が返されます。
配列の要素は、keyより小さいもの、等しいもの、より大きいものの順番に並んでいる必要がある。
適合するものがあれば適合する配列の要素が返され、そうでなければNULLポインタが返されます。
2つ以上の要素が適合した場合に、どのポインタが返されるかは未定義です。

使用例:

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

int compare(const void *a, const void *b)
{
    return (*(int*)a - *(int*)b);
}

int main(void)
{
    int arr[] = {1, 2, 3, 4, 5, 6, 7, 8, 9};
    int key = 5;
    int *item;

    int n = sizeof(arr) / sizeof(arr[0]);

    // 使用する配列はソート済みである必要があります。
    item = (int*) bsearch(&key, arr, n, sizeof(int), compare);
    if(item != NULL){
        printf("検索された項目 = %d\n", *item);
    }else{
        printf("key = %d は見つかりませんでした。\n", key);
    }

    return 0;
}

実行結果:

検索された項目 = 5

char *qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *))

配列の要素をクイックソート法で並び替えます。
baseが最初の要素を指しているnmemb個の要素をもつ配列をソートします。
個々の配列の要素のサイズはsizeによって指定されます。
配列の中身はcomparが指す関数に従って昇順にソートされます。
comparが指す比較関数の2つの引数には比較されるオブジェクトへのポインタが渡されます。
最初の引数の方が次の引数より小さいか、等しいか、大きいかによって負、ゼロ、正の値が返されます。
配列の要素は、keyより小さいもの、等しいもの、より大きいものの順番に並んでいる必要があります。
2つ以上の要素が適合した場合に、どのポインタが返されるかは未定義です。

使用例:

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

// 配列の要素を比較する関数
int compare(const void *a, const void *b)
{
    return (*(int*)a - *(int*)b);
}

int main(void)
{
    int numbers[] = {7, 3, 4, 1, 8, 5, 2, 6};
    int n = sizeof(numbers) / sizeof(numbers[0]);

    qsort(numbers, n, sizeof(int), compare);

    printf("ソート後:");
    for(int i=0; i<n; i++){
        printf("%d ", numbers[i]);
    }

    return 0;
}

実行結果:

ソート後:1 2 3 4 5 6 7 8

整数算術関数

int abs(int j)

定義:

int abs(int j);                   // int版
long int labs(long int j);        // long版
long long int llabs(long long int j);  // long long版

引数jの絶対値を計算します。
結果が表現不可能な場合の動作は未定義です。※
jの絶対値が返されます。
※:2の補数表現では、最も小さい負の値の絶対値は表現できません。

使用例:

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

int main(void)
{
    int number = -10;
    int absoluteNumber = abs(number);

    printf("%d の絶対値は %d です。\n", number, absoluteNumber);

    return 0;
}

実行結果:

-10 の絶対値は 10 です。

div_t div(int numer, int denom)

定義:

div_t div(int numer, int denom);                          // int版
ldiv_t ldiv(long int numer, long int denom);              // long版
lldiv_t lldiv(long long int numer, long long int denom);  // long long版

整数の除算を行い、商と余りを返します。
numerをdenomで割った商と余りを計算します。
割り切れない場合、商は代数的な商に近い整数のうち大きさが小さいほうとなります。
結果が表現できない場合の動作は未定義です。
そうでなければquot * denom + remはnumerと等しくなります。
商と余りから成るdiv_t構造体が返されます。
div_t構造体は以下のメンバを持ちます。

メンバ名説明
intquot商(quotient)
intrem余り(remainder)

使用例:

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

int main(void)
{
    int numerator = 17;
    int denominator = 5;
    div_t result;

    result = div(numerator, denominator);

    printf("商 = %d, 余 = %d\n", result.quot, result.rem);

    return 0;
}

実行結果:

商 = 3, 余 = 2

マルチバイト文字・ワイド文字変換関数

int mblen(const char *s, size_t n)

sがNULLポインタでなければ、sが指すマルチバイト文字のバイト数を決定します。
mbtowcのシフト状態が影響を受けないことを除けば、これは以下と同等です。

mbtowc((wchar_t *)0, s, n);

sがNULLポインタである場合、状態依存の符号化を持つか持たないかで非0か0が返されます。
sがNULLポインタでない場合、sがNULL文字を指す時は0が返され、n以下のバイト数で正しいマルチバイト文字が形成される時はマルチバイト文字内のバイト数が返され、マルチバイト文字として認識されない時は-1が返されます。

int mbtowc(wchar_t *pwc, const char *s, size_t n)

sがNULLポインタでなければ、sが指すマルチバイト文字のバイト数を決定します。
次に、マルチバイト文字に相当するwchar_tで表す文字コードを決定します。
(NULL文字に相当する文字コードは0です。)
マルチバイト文字が認識可能で、pwcがNULLポインタでなければ、pwcが指すオブジェクトにその文字コードが格納されます。
sが指す配列の最大nバイトまでが吟味されます。
sがNULLポインタである場合、状態依存の符号化を持つか持たないかで非0か0が返されます。
sがNULLポインタでない場合、sがNULL文字を指す時は0が返され、n以下のバイト数で正しいマルチバイト文字が形成される時はマルチバイト文字内のバイト数が返され、マルチバイト文字として認識されない時は-1が返されます。
戻り値はnやMB_CUR_MAXマクロの値より大きくなることはありません。

int wctomb(char *s, wchar_t wchar)

wcharの値のワイド文字に対応する、シフト状態の変化を含むマルチバイト文字を決定します。
対応するマルチバイト文字は、sがNULLポインタでなければsが指す配列オブジェクトに格納されます。
最大でMB_CUR_MAX文字が格納されます。
wcharの値が0なら、シフト状態は初期に戻ります。
sがNULLポインタである場合、状態依存の符号化を持つか持たないかで非0か0が返されます。
sがNULLポインタでない場合、wcharの値に対応する認識可能なマルチバイト文字がなければ-1が返され、対応するものがあればそのマルチバイト文字に含まれるバイト数が返されます。
戻り値はMB_CUR_MAXマクロの値より大きくなることはありません。

マルチバイト文字列・ワイド文字列変換関数

size_t mbstowcs(wchar_t *pwcs, const char *s, size_t n)

マルチバイト文字列をワイド文字列に変換します。
引数sが指す初期シフト状態で始まるマルチバイト文字の連続を対応するn以下のコードとして、pwcsの指す配列オブジェクトに格納します。
NULL文字以降のマルチバイト文字は吟味されることも、変換されることもありません。
各マルチバイト文字は、関数のシフト状態が変わらないことを除けば、mbtowcの呼び出しによって変換されたかのように変換されます。
pwcsが指す配列オブジェクトのn以前の要素は変更されます。
重複するオブジェクトの間でコピーが行われた時の動作は未定義です。
認識不可能なマルチバイト文字に出くわした場合は-1が返されます。
そうでなければ、終端0コードを除いた、変更された配列の要素数が返されます。
配列は戻り値がnである場合にはNULL止めされません。

size_t wcstombs(char *s, const wchar_t *pwcs, size_t n)

ワイド文字列をマルチバイト文字列に変換します。
pwcsが指すコードの連続を初期シフト状態で始まる、対応するマルチバイト文字の連続に変換し、 結果がnバイトに達する手前で止め、マルチバイト文字としてsの指す配列オブジェクトに格納します。
各マルチバイト文字は、関数のシフト状態が変わらないことを除けば、wctombの呼び出しによって変換されたかのように変換されます。
sが指す配列オブジェクトのn以前の要素は変更されます。
重複するオブジェクトの間でコピーが行われた時の動作は未定義です。
対応する認識可能なマルチバイト文字が存在しないコードに出くわした場合は-1が返されます。
そうでなければ、終端NULL文字を除いた、変更されたバイト数が返されます。
配列は戻り値がnである場合にはNULL止めされません。

スポンサーリンク
C言語

コメント