第10章の3 ポインタと文字列

1. ポインタで文字列リテラルを指す

普通ポインタを用いるときには、配列などのアドレスをポインタに設定して用いますが、 文字列の場合には、配列を使わずにメモリ上に取られた文字列リテラルのアドレスを直接ポインタに指定することができます。

(1) 1つの文字列をポインタで指す

// 例1
char *p = "ABC";

// 例2
char *p;
p = "ABC";

(2) 複数の文字列をポインタの配列で指す

char *mnthp[3] = {
    "January",
    "February",
    "March"
};

for (int i = 0; i < 3; i++) {
    printf("%s\n", mnthp[i]);
}

【実行結果例】
January
February
March

  • まずメモリ上のどこかに文字列リテラル “January”、”February”、”March” がとられ、 それぞれの先頭番地がポインタの配列の mnthp[0]、mnthp[1]、mnthp[2] に設定されます。
  • 各文字列は隙間無くメモリ上に格納されるため(但し、連続して格納されるとは限りません)、 サイズの大きな文字列と小さな文字列が混在する場合には、2次元配列で文字列を扱うより、ポインタの配列で指す方が効率よくメモリを使用することができます。
  • ただし、ポインタで指す場合にはポインタの領域が余分に必要になります。

〇 演習問題

問1

実行結果例のようになるようにプログラムの空欄部を埋めて完成させなさい。

#include <stdio.h>

int main(void)
{
    char *p;
    ________ = "Winter";
    
    printf("%s\n", ________);
    
    return 0;
}

【実行結果例】
Winter

問2

実行結果例のようになるようにプログラムの空欄部を埋めて完成させなさい。

#include <stdio.h>

int main(void)
{
    char *p1, *p2;
    _____ = _____ = "Winter";
    
    while (*p1) {
         _____;
    }
    while (_____) {
        _____;
        putchar(*p1);
    }
    putchar('\n');
    
    return 0;
}

【実行結果例】
retniW

問3

“one”,”two”,”three”,”four”,”five”,”six”,”seven”,”eight”,”nine”,”ten” の10個の文字列をポインタの配列を用いて宣言し、ASCIIコードで昇順に並び替えなさい。

【実行結果例】
eight five four nine one seven six ten three two

解答例

// 問1
#include <stdio.h>

int main(void)
{
    char *p;
    p = "Winter";
    
    printf("%s\n", p);
    
    return 0;
}
// 問2
#include <stdio.h>

int main(void)
{
    char *p1, *p2;
    p1 = p2 = "Winter";
    
    while (*p1 != '\0') {
         ++p1;
    }
    while (p1 > p2) {
        --p1;
        putchar(*p1);
    }
    putchar('\n');
    
    return 0;
}
// 問3
#include <stdio.h>
#include <string.h>
#define N 10
    
int main(void)
{
    char *p[N] = {
        "one", "two", "three", 
        "four", "five", "six", 
        "seven", "eight", "nine", 
        "ten"
    };
    char *temp;
    int min;

    for (int i = 0; i < N - 1; i++) {
        min = i;
        for (int j = i + 1; j < N; j++) {
            /* 文字列の比較 */
            if (strcmp(p[min], p[j]) > 0) {
                min = j;
            }
        }
        /* ポインタの配列の入れ換え */
        temp = p[i];
        p[i] = p[min];
        p[min] = temp;
    }
    for (int i = 0; i < N; i++) {
        printf("%s ", p[i]);
    }
    printf("\n");

    return 0;
}

問3の解説図

コメント