C言語におけるポインタと配列の高度な操作

タスク1: 配列の最小値と最大値の検索

#include 
#define ARRAY_SIZE 5

void inputData(int data[], int size);
void displayData(int data[], int size);
void findMinMax(int data[], int size, int *minPtr, int *maxPtr);

int main() {
    int numbers[ARRAY_SIZE];
    int minValue, maxValue;

    printf("%d個のデータを入力してください:\n", ARRAY_SIZE);
    inputData(numbers, ARRAY_SIZE);

    printf("入力されたデータ: \n");
    displayData(numbers, ARRAY_SIZE);

    printf("データ処理中...\n");
    findMinMax(numbers, ARRAY_SIZE, &minValue, &maxValue);

    printf("結果:\n");
    printf("最小値 = %d, 最大値 = %d\n", minValue, maxValue);

    return 0;
}

void inputData(int data[], int size) {
    int i;

    for(i = 0; i < size; ++i)
        scanf("%d", &data[i]);
}

void displayData(int data[], int size) {
    int i;
    
    for(i = 0; i < size; ++i)
        printf("%d ", data[i]);
    printf("\n");
}

void findMinMax(int data[], int size, int *minPtr, int *maxPtr) {
    int i;
    
    *minPtr = *maxPtr = data[0];

    for(i = 1; i < size; ++i)
        if(data[i] < *minPtr)
            *minPtr = data[i];
        else if(data[i] > *maxPtr)
            *maxPtr = data[i];
}

1. 配列要素の中から最小値と最大値を見つけます。

2. minPtrとmaxPtrは両方ともdata[0]のアドレスを指します。

タスク2: 最大値のアドレスを返す

#include 
#define ARRAY_SIZE 5

void inputData(int data[], int size);
void displayData(int data[], int size);
int *findMaxValue(int data[], int size);

int main() {
    int numbers[ARRAY_SIZE];
    int *maxPtr;

    printf("%d個のデータを入力してください:\n", ARRAY_SIZE);
    inputData(numbers, ARRAY_SIZE);

    printf("データは: \n");
    displayData(numbers, ARRAY_SIZE);

    printf("データ処理中...\n");
    maxPtr = findMaxValue(numbers, ARRAY_SIZE);

    printf("結果:\n");
    printf("最大値 = %d\n", *maxPtr);

    return 0;
}

void inputData(int data[], int size) {
    int i;

    for(i = 0; i < size; ++i)
        scanf("%d", &data[i]);
}

void displayData(int data[], int size) {
    int i;
    
    for(i = 0; i < size; ++i)
        printf("%d ", data[i]);
    printf("\n");
}

int *findMaxValue(int data[], int size) {
    int maxIndex = 0;
    int i;

    for(i = 1; i < size; ++i)
        if(data[i] > data[maxIndex])
            maxIndex = i;
    
    return &data[maxIndex];
}

1. 配列要素の中から最大値のアドレスを返します。

2. 可能です。

タスク3: 文字列の比較と交換

#include 
#include 
#define BUFFER_SIZE 80

int main() {
    char str1[] = "プログラミング学習は楽しい";
    char str2[] = "プログラミング学習は難しい";
    char temp[BUFFER_SIZE];

    printf("sizeof(str1) vs. strlen(str1): \n");
    printf("sizeof(str1) = %d\n", sizeof(str1));
    printf("strlen(str1) = %d\n", strlen(str1));

    printf("\n交換前: \n");
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);

    printf("\n交換中...\n");
    strcpy(temp, str1);
    strcpy(str1, str2);
    strcpy(str2, temp);

    printf("\n交換後: \n");
    printf("str1: %s\n", str1);
    printf("str2: %s\n", str2);

    return 0;
}

1. 配列str1のサイズは24です。sizeof(str1)は配列が占用するメモリのバイト数を計算し、strlen(str1)はstr1が含む文字数をカウントします。

2. できません。str1は配列名で、アドレスを格納しており、直接代入できません。

3. 文字列が交換されました。

タスク4: ポインタを使った文字列操作

#include 
#include 
#define BUFFER_SIZE 80

void replaceCharacters(char *text, char oldChar, char newChar);

int main() {
    char message[BUFFER_SIZE] = "C言語のプログラミングは難しいかどうか、それは問いかけです。";

    printf("元のテキスト: \n");
    printf("%s\n", message);

    replaceCharacters(message, 'い', '*'); // 関数呼び出し

    printf("処理後のテキスト: \n");
    printf("%s\n", message);

    return 0;
}

// 関数定義
void replaceCharacters(char *text, char oldChar, char newChar) {
    int i;

    while(*text) {
        if(*text == oldChar)
            *text = newChar;
        text++;
    }
}

1. 古い文字を新しい文字に置き換えます。

2. 可能です。

タスク5: 文字列配列のソート

#include 
#include 
void sortStrings(char *names[], int count);

int main() {
    char *subjects[4] = {"C言語プログラミング",
                         "C++オブジェクト指向プログラミング",
                         "オペレーティングシステム",
                         "データ構造とアルゴリズム"};
    int i;

    sortStrings(subjects, 4);

    for (i = 0; i < 4; i++)
        printf("%s\n", subjects[i]);

    return 0;
}

void sortStrings(char *names[], int count) {
    int i, j;
    char *temp;

    for (i = 0; i < count - 1; ++i)
        for (j = 0; j < count - 1 - i; ++j)
            if (strcmp(names[j], names[j + 1]) > 0) {
                temp = names[j];
                names[j] = names[j + 1];
                names[j + 1] = temp;
            }
}

タスク6: ID検証

#include 
#include 
#define NUM_IDS 5

int validateId(char *idStr); // 関数宣言

int main() {
    char *identifications[NUM_IDS] = {"31010120000721656X",
                                     "330106199609203301",
                                     "53010220051126571",
                                     "510104199211197977",
                                     "53010220051126133Y"};
    int i;

    for (i = 0; i < NUM_IDS; ++i)
        if (validateId(identifications[i])) // 関数呼び出し
            printf("%s\t有効\n", identifications[i]);
        else
            printf("%s\t無効\n", identifications[i]);

    return 0;
}

// 関数定義
// 機能: ポインタidStrが指すID番号の文字列が形式上正しいかチェックする。
// 形式が正しい場合、1を返す。そうでなければ、0を返す。
int validateId(char *idStr) {
    char validChars[11] ={'0','1','2','3','4','5','6','7','8','9','X'};
    int i, isValid = 0;
    
    if(strlen(idStr) != 18){
        return 0;
    }
    
    for(i = 0; i < strlen(idStr) - 1; i++){
        if(idStr[i] > '9' || idStr[i] < '0'){
            return 0;
        }
    }
    
    for(i = 0; i < 11; i++){
        if(idStr[17] == validChars[i]){
            isValid = 1;
        }
    }
    
    return isValid;
}

タスク7: 文字列のエンコードとデコード

#include 
#include 
#define BUFFER_SIZE 80
void encodeText(char *text); // 関数宣言
void decodeText(char *text); // 関数宣言

int main() {
    char inputText[BUFFER_SIZE];

    printf("英語のテキストを入力してください: ");
    gets(inputText);

    printf("エンコードされた英語のテキスト: ");
    encodeText(inputText); // 関数呼び出し
    printf("%s\n", inputText);

    printf("エンコードされた英語のテキストをデコード: ");
    decodeText(inputText); // 関数呼び出し
    printf("%s\n", inputText);

    return 0;
}

/*関数定義
機能: sが指す文字列をエンコード処理する
エンコードルール:
a~zまたはA~Zの間の文字は、その後の文字に置き換える; その中で、zはaに置き換え、ZはAに置き換える
その他の非文字文字は、そのまま保持する
*/
void encodeText(char *text) {
    char *ptr = text;
    while(*ptr != '\0'){
        if(*ptr == 'z'){
            *ptr = 'a';
        }
        if(*ptr == 'Z'){
            *ptr = 'A';
        }
        if(*ptr >= 'a' && *ptr < 'z'){
            *ptr = *ptr + 1;
        }
        if(*ptr >= 'A' && *ptr < 'Z'){
            *ptr = *ptr + 1;
        }
        ptr++;
    }
}

/*関数定義
機能: sが指す文字列をデコード処理する
デコードルール:
a~zまたはA~Zの間の文字は、その前の文字に置き換える; その中で、aはzに置き換え、AはZに置き換える
その他の非文字文字は、そのまま保持する
*/
void decodeText(char *text) {
    char *ptr = text;
    while(*ptr != '\0'){
        if(*ptr > 'a' && *ptr <= 'z'){
            *ptr = *ptr - 1;
        }
        if(*ptr == 'a'){
            *ptr = 'z';
        }
        if(*ptr > 'A' && *ptr <= 'Z'){
            *ptr = *ptr - 1;
        }
        if(*ptr == 'A'){
            *ptr = 'Z';
        }
        ptr++;
    }
}

タグ: C言語 ポインタ 配列 文字列操作 アルゴリズム

6月29日 22:38 投稿