注意事項です  

本ブログのソースコードは、表示の都合上、全角文字になっていますのでご注意ください。
1

2012/9/9

コードレビューチェックリスト  

C言語では、他の新しい言語に比べてメモリ関連の不具合が発生しやすいという特徴があります。メモリ関連の不具合は、改修するのに手間がかかります。再現手順がわからなかったり、いきなりプログラムが死ぬので欲しいエラーログが吐かれていなかったりするからです。

そういうこともあって、コードレビューは重要だと思います。レビュー時にチェックすべき代表的な項目をチェックリストとしてつくってみました。

これからブラッシュアップしていきたいです。

----
コードレビューチェックリスト

●メモリ
□メモリの不正アクセスはないですか?
□バッファーオーバーランはないですか?
□解放済みメモリにアクセスしていませんか?
□メモリリークはないですか?
□ヌルポインタアクセスはないですか?

●データ
□変数の初期値設定漏れはないですか?
□0オリジン/1オリジンか明確になってますか?
□C言語の文字列の扱いは正しいですか?

●計算
□桁溢れ、オーバーフロー、アンダーフローはないですか?
□0割りの可能性はないですか?
□演算子の優先順位は正しいですか?
□キャスト(暗黙も含む)は正しいですか?

●制御
□ループの開始条件、終了条件は正しいですか?
□境界値の処理は正しいですか?
□異常系の処理は正しいですか?

●その他
□タイプミスはないですか?
----
0

2010/2/20

文字列のクイックソート  ソート

文字列のクイックソートのサンプルソースです。
文字列のクイックソートを行うにも標準ライブラリのqsort()を使います。

#include <stdlib.h>
void *qsort(
    void *ソート対象の配列, size_t その要素数, size_t 要素1つの大きさ, 
    int (*比較関数)(const void *, const void *));

比較関数は第1引数<第2引数なら0より小さい数を
第1引数=第2引数なら0を
第1引数>第2引数なら0より大きい数を返す必要があります。

下記サンプルはコマンドライン引数文字列を昇順にソートします。

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

int cmpfnc(const void *s1 , const void *s2)
{
    return strcmp(*(char **)s1, *(char **)s2);  /* キャストが必要 */
/*  降順にしたい時は逆にする */
/*  return strcmp(*(char **)s2, *(char **)s1); */
}

int main(int argc, char *argv[])
{
    int i;

    qsort(&argv[1], (size_t)(argc - 1), sizeof(char *), cmpfnc);
    for (i=1;i<argc;i++) {
        printf("%s\n", argv[i]);
    }

    return EXIT_SUCCESS;
}
1

2010/2/19

整数のクイックソート  ソート

整数のクイックソートのサンプルソースです。
クイックソートを行うには標準ライブラリのqsort()を使います。

#include <stdlib.h>
void *qsort(
void *ソート対象の配列, size_t その要素数, size_t 要素1つの大きさ, 
int (*比較関数)(const void *, const void *));

比較関数は第1引数<第2引数なら0より小さい数を
第1引数=第2引数なら0を
第1引数>第2引数なら0より大きい数を返す必要があります。

下記サンプルはコマンドライン引数を昇順にソートします。

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

int cmpfnc(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b); /* キャストが必要 */
/*  降順にしたい時は逆にする */
/*  return (*(int *)b - *(int *)a); */
}

int main(int argc, char *argv[])
{
    int i;
    int data[5] = {0, 0, 0, 0, 0};

    for (i=0;i<5 && i<argc-1;i++) {
        data[i] = atoi(argv[i+1]);
    }
    qsort(data, 5, sizeof(int), cmpfnc);
    for (i=0;i<5;i++) {
        printf("%d ", data[i]);
    }
    printf("\n");

    return EXIT_SUCCESS;
}
0

2010/2/18

バイナリサーチ  サーチ

バイナリサーチのサンプルプログラムです。
バイナリサーチを行うには標準ライブラリのbsearch()を使います。

#include <stdlib.h>
void *bsearch(
    const void *検索キー, const void *検索対象の配列, 
    size_t その要素数, size_t 要素1つの大きさ, 
    int (*比較関数)(const void *, const void *));

bsearch()は,配列[0]から配列[要素数-1]を二分検索し,
検索キーと一致した要素のポインタを返します。
    
比較関数は第1引数<第2引数なら0より小さい数を
第1引数=第2引数なら0を
第1引数>第2引数なら0より大きい数を返す必要があります。

また,検索対象の配列は昇順にソートされている必要があります。
見つからなかった場合にはNULLが返さます。

下記サンプルは,コマンドライン引数から数値を受け取り
その数が,ランダムに発生させた100個の数の中にあれば
発見した数を表示し,見つからなければnot foundと表示します。

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

#define NUM 100

/* 比較関数 */
int cmpfnc(const void *a, const void *b)
{
    return (*(int *)a - *(int *)b); /* キャストが必要 */
}

int main(int argc, char *argv[])
{
    int i;
    int k;
    int a[NUM];
    int **r;

    if (argc < 2) {
        printf("error\n");
        return EXIT_FAILURE;
    }

    srand(time(NULL));
    for(i=0;i<NUM;i++) {
        /* 1〜100の乱数を発生 */
        a[i] = 1 + rand() % 100;
    }

    /* あらかじめソートしておく */
    qsort(a, NUM, sizeof(int), cmpfnc);

    /* コマンドライン引数から探索keyを取得 */
    k = atoi(argv[1]);

    /* 探索 */
    r = bsearch(&k, a, NUM, sizeof(int), cmpfnc);
    if (r != NULL) {
        printf("%d\n", *r);
    } else {
        printf("not found\n");
    }

    return EXIT_SUCCESS;
}
0



teacup.ブログ “AutoPage”
AutoPage最新お知らせ