C言語では、文字列はポインタを使って扱うことが多く、初心者がつまずきやすいポイントでもある。
そこで、今回は、文字列とポインタの関係を扱う。
1. 文字列の基本:配列との違い
C言語では、文字列は次のように「配列」としても「ポインタ」としても扱うことができる。
char str1[] = "Hello";
char *str2 = "World";
str1
は 配列として文字列を保持しています。これは書き換え可能である。str2
は 文字列リテラルの先頭アドレスを指すポインタである。この領域は通常「読み取り専用」となるため、変更はできない。
2. ポインタで文字列を1文字ずつ取り出してみよう
次のコードは、ポインタを使って文字列を1文字ずつ表示する例である。
#include <stdio.h>
int main(void) {
char *str = "Hello";
while (*str != '\0') {
printf("%c ", *str);
str++;
}
return 0;
}
実行結果
H e l l o
このコードでは、ポインタ str
が文字列 "Hello"
の先頭(’H’)を指している。*str
によって現在指している文字を1文字ずつ取り出して表示し、str++
によってポインタを次の文字へ進めている。('H'
→ 'e'
→ 'l'
…)
文字列の終端 '\0'
に達するまで、文字が1つずつ出力される。
(補足)初心者向けに役立つポイント
char *str = "Hello";
は「文字列リテラルの先頭アドレス」を受け取る。*str
は「ポインタが指している先の値(1文字)」。str++
は「ポインタ自体を次の文字の位置へ進める」操作。
3. 文字列の「変更できる・できない」の境界とは?
char *str = "Hello"; // 変更不可
char str2[] = "Hello"; // 変更可能
str[0] = 'h';
のように変更しようとすると 未定義動作(例:セグメンテーションフォルト)になる。- 一方、
str2
は配列で確保されており、文字列の変更が可能である。
( 参考)読み取り専用領域とは?
C言語では、文字列リテラル(例:"Hello"
)は多くの実行環境で「読み取り専用領域」に配置される。ここはプログラムが書き換えできない領域であり、以下の理由で読み取り専用になっている。
- 安全性:意図しない書き換えを防ぐため
- 最適化:同じリテラルを共有してメモリ効率を向上
- 移植性:OSやコンパイラ間で挙動を安定させる
宣言方法 | メモリ領域 | 書き換え可能 | 備考 |
---|---|---|---|
char *str = "abc"; | 読み取り専用領域 | ❌ | 書き換えは危険・未定義動作 |
char str[] = "abc"; | 書き換え可能な領域 | ✅ | 安全に変更できる |
4. 練習問題:このコードの出力は?
次のコードを見て、出力を予想してみよう。
#include <stdio.h>
int main(void) {
char str[] = "C Language";
char *p = str;
p += 2;
printf("%s\n", p);
return 0;
}
5. 答えと解説
このコードでは、ポインタ p
を "C Language"
の3文字目(インデックス2)へ進めている。
つまり、p
は 'L'
を指すようになる。
したがって、printf("%s", p);
により表示されるのは次の通り。
Language
おわりに
C言語の文字列操作において、「char *
」の理解はとても重要である。ポインタの仕組みを知ることで、より柔軟かつ効率的なコードが書けるようになる。
配列とポインタの違いをしっかり理解して、安全で読みやすいプログラムを目指してみよう。
コメント