第7章 演習問題 解答例

7.1 アドレスとは

a7-1-1.c

図7-1-2(P.247)の1次元配列の値とそれぞれの要素のアドレスを表示するプログラムを作成してください。

/* a7-1-1.c */
#include <stdio.h>

int main(void)
{
    char str[3] = "AB";

    printf("str[0]の要素の値        : %#x\n", str[0]);
    printf("str[1]の要素の値        : %#x\n", str[1]);
    printf("str[2]の要素の値        : %#x\n", str[2]);
    printf("str[0]の要素のアドレス  : %p\n", &str[0]);
    printf("str[1]の要素のアドレス  : %p\n", &str[1]);
    printf("str[2]の要素のアドレス  : %p\n", &str[2]);
    printf("strの先頭要素のアドレス : %p\n", str);

    return 0;
}

[Back]

a7-1-2.c

図7-1-3(P.247)の2 次元配列の値とそれぞれの要素のアドレスを表示するプログラムを作成してください

/* a7-1-2.c */
#include <stdio.h>

int main(void)
{
    char str[2][2] = {"A", "C"};

    printf("str[0][0]の要素の値        : %#x\n", str[0][0]);
    printf("str[0][1]の要素の値        : %#x\n", str[0][1]);
    printf("str[1][0]の要素の値        : %#x\n", str[1][0]);
    printf("str[1][1]の要素の値        : %#x\n", str[1][1]);
    printf("str[0][0]のアドレス        : %p\n", &str[0][0]);
    printf("str[0][1]のアドレス        : %p\n", &str[0][1]);
    printf("str[1][0]のアドレス        : %p\n", &str[1][0]);
    printf("str[1][1]のアドレス        : %p\n", &str[1][1]);
    printf("str[0]の先頭要素のアドレス : %p\n", str[0]);
    printf("str[1]の先頭要素のアドレス : %p\n", str[1]);
    printf("strの先頭要素のアドレス    : %p\n", str);

    return 0;
}

[Back]

7.2 ポインタで変数を指す

a7-2-1.c

ポインタが指す値を2倍するプログラムを、コメントを参考に空欄部を埋めて作成してください。

/* a7-2-1.c */
#include <stdio.h>
int main(void)
{
    double x = 123.4;
    double *p;           // ポインタpの宣言
    p = &x;              // ポインタにxのアドレスを代入

    printf("%f\n", *p);  // ポインタの指す値を表示
    *p *= 2;             // ポインタの指す値を2倍
    printf("%f\n", *p);  // ポインタの指す値を表示

    return 0;
}

[Back]

7.3 ポインタで配列を指す

a7-3-1.c

文字型配列に"AbcDefGHijk1234lmNOP" という文字列が初期化されています。この文字列の小文字をtoupper関数(P.222)を使って、すべて大文字に変換してください。

/* a7-3-1.c */
#include <stdio.h>
#include <ctype.h>

int main(void)
{
    char str[] = "AbcDefGHijk1234lmNOP";
    char *p = str;

    while (*p != '\0') {
        *p = toupper(*p);
        printf("%c", *p);
        p++;
    }

    return 0;
}

[Back]

a7-3-2.c

文字型配列str1に、"ABCDEFGHIJKLMNOPQRSTUVWXYZ"という文字列が初期化されています。ポインタを2つ用いて、文字型配列str2に、この文字列を逆順に格納してください

/* a7-3-2.c */
#include <stdio.h>

int main(void)
{
    char str1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char str2[30];
    char *p1 = str1, *p2 = str2;

    // p1を文字列の最後まで進める
    while (*p1 != '\0') {
        p1++;
    }
    // 逆順に文字列を代入する
    while (p1 > str1) {
        p1--;
        *p2 = *p1;
        p2++;
    }
    *p2 = '\0';
    printf( "str1 = %s\n", str1 );
    printf( "str2 = %s\n", str2 );

    return 0;
}

図のように、いったん'\0'まで進めたp1を戻しながらp2へのコピーを行います。 解説図

[Back]

a7-3-3.c

要素数10の整数型配列を2つ用意し、片方を整数値で初期化してください。そして、奇数の値のみもう1つの配列に代入してください。

/* a7-3-3.c */
#include <stdio.h>
#define N 10

int main(void)
{
    int array1[N] = {10, 15, 22, 45, 9, 66, 71, 4, 37, 82};
    int array2[N], i, j;
    int *p1 = array1, *p2 = array2;

    for (i = 0, j = 0; i < N; i++) {
        // 奇数なら代入する
        if (*(p1 + i) % 2 == 1) {
            *(p2 + j) = *(p1 + i);
            j++;
        }
    }

    printf("配列1 = ");
    for (i = 0; i < N; i++) {
        printf("%d ", *(p1 + i));
    }

    printf("\n配列2 = ");
    for (i = 0; i < j; i++) {
        printf("%d ", *(p2 + i));
    }

    return 0;
}

[Back]

a7-3-4.c

a7-3-3.cの配列1の合計値、平均値、最大値、最小値を求めてください。

/* a7-3-4.c */
#include <stdio.h>
#define N 10

int main(void)
{
    int array1[N] = {10, 15, 22, 45, 9, 66, 71, 4, 37, 82};

    // 合計値を求める
    int *p = array1;
    int sum = 0;
    for (int i = 0; i < N; i++) {
        sum += *p;
        p++;
    }

    // 平均値を求める
    double avg = (double)sum / N;

    // 最大値と最小値を求める
    p = array1;
    int max = *p;
    int min = *p;
    for (int i = 1; i < N; i++) {
        p++;
        if (max < *p) {
            max = *p;
        }
        if (min > *p) {
            min = *p;
        }
    }

    printf("合計値 = %d\n", sum);
    printf("平均値 = %.1f\n", avg);
    printf("最大値 = %d\n", max);
    printf("最小値 = %d\n", min);

    return 0;
}

[Back]

7.4 ポインタの配列

a7-4-1.c

次の文字列の長さを表示してください。
"red", "orange", "greenish yellow", "pink","dark green", "lemon yellow", "white"

/* a7-4-1.c */
#include <stdio.h>
#include <string.h>

int main(void)
{
    char *color_p[7] = {"red", "orange", "greenish yellow", "pink",
                        "dark green", "lemon yellow", "white"};

    for (int i = 0; i < 7; i++) {
        printf("%s : %zu文字\n", color_p[i], strlen(color_p[i]));
    }

    return 0;
}

[Back]

a7-4-2.c

擬似乱数を発生させ、「誰(who)がいつ(when)どこ(where)で何(what)をした。」と表示してください。

/* a7-4-2.c */
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define N 5

int main(void)
{
    char *who[N]   = {"鳥取君", "島根君", "岡山君", "広島君", "山口君"};
    char *when[N]  = {"朝早く", "夏休み", "食事中", "放課後", "風呂あがり"};
    char *where[N] = {"学校", "バイト先", "電車の中", "駅のホーム", "コンビニ"};
    char *what[N]  = {"宿題をした", "笑い転げた", "泣いた", "喧嘩をした", "走った"};
    int i1, i2, i3, i4;

    srand((unsigned)time(NULL));
    i1 = rand() % N;
    i2 = rand() % N;
    i3 = rand() % N;
    i4 = rand() % N;

    printf("%sが%s%sで%s\n", who[i1], when[i2], where[i3], what[i4]);

    return 0;
}

[Back]

a7-4-3.c

a7-4-1.cの文字列を逆順に表示してください。

/* a7-4-3.c */
#include <stdio.h>
#include <string.h>

int main(void)
{
    char *color_p[7] = {"red", "orange", "greenish yellow", "pink",
                        "dark green", "lemon yellow", "white"};

    for (int i = 0; i < 7; i++) {
        // 文字数を求める
        int n = strlen(color_p[i]);
        // 逆順に表示する
        while (n > 0) {
            n--;
            putchar(*(color_p[i]+n));
        }
        putchar('\n');
    }

    return 0;
}

[Back]


Copyright© 2021 Tomoko Sugawara. All Rights Reserved.