誰でも分かるC言語入門
■第6話:配列と文字列
(最終更新日:2024.04.24)
(絵が小さい場合はスマホを横に)
「配列と文字列の関係を学ぼう」
第6回では、C言語における配列と文字列に焦点を当てる。
配列は同じデータ型の要素を連続したメモリ位置に格納するデータ構造で、効率的なデータ管理とアクセスを可能にする。
一方、文字列は文字の配列として扱われ、C言語でのテキスト処理の基本になる。
このセッションでは、配列の宣言、初期化、操作方法を学び、文字列を扱うための基本的な関数とその使用方法について詳しく解説する。
配列と文字列の扱いを理解することは、C言語プログラミングの基礎を固める上で非常に重要だ。
[目次]
1.配列の基礎
配列は、C言語において同一のデータ型の複数の要素を一つの名前で管理するためのデータ構造だ。
配列を使用することで、複数の変数を個別に宣言することなく、一括して扱うことができる。
これにより、データの集合を効率的に処理し、プログラムを単純化することが可能になる。
■配列の宣言
配列を宣言するには、要素の型と配列名、そして配列のサイズ(要素数)を指定する必要がある。
配列の宣言
配列は宣言と同時に初期化することができる。 個々の要素に具体的な値を割り当てることにより、初期化を行う。 下記では、要素の数を指定して割り当てた場合と自動でサイズを決定して割り当てた場合を示す。
配列の初期化
配列の要素にアクセスするには、インデックス(添え字)を使用する。インデックスは0から始まり、配列のサイズ-1までの値を取る。 下記では、インデックス0の要素と2の要素にアクセスした例と、インデックス1の要素と2の要素を0の要素に代入した場合を示している。
配列のアクセス(上)と演算(下)
■配列の制限と注意点
配列は固定サイズを持つ。一度宣言された配列のサイズをプログラム実行時に変更することはできない(静的なサイズがある)。
配列名はその配列の最初の要素のアドレスを指し示すポインタとして機能する。そのため、配列名を他の値で上書きすることはできない(配列名はポインタになる)。
存在しないインデックスにアクセスすると、未定義の動作が発生する。これはプログラムのクラッシュやデータの破損を引き起こす可能性がある(配列の範囲外アクセスはダメ)。
配列はC言語で非常に基本的かつ強力なツールであり、多くのプログラムでデータの集合を扱うために使用される。
適切に使用することで、プログラムの効率と可読性を大きく向上させることができる。上記の注意点に気を付けて使おう。
2.文字列とC言語
C言語における文字列は、基本的にはchar型の配列として扱われる。
つまり、文字列は文字の配列であり、通常は文字のシーケンスをメモリ内に連続して格納し、文字列の終端にはヌル文字('\0')を置くことで文字列の終わりを示す。
このヌル文字は非常に重要で、文字列操作を行う多くの標準ライブラリ関数がこの終端文字を基準に処理を行う。
■文字列の宣言と初期化
C言語における文字列の宣言は、単純な配列宣言と非常に似ているが、文字列の特定の初期化方法がある。
下記では、nameはchar型の配列であり、6文字分のスペースを確保している。
C言語では自動的に文字列の最後にヌル文字を追加するため、明示的には5文字の名前(Alice)を記入しているが、実際には6文字分のメモリが必要になる。
文字列の宣言と初期化
■文字列の操作
C言語の標準ライブラリには、文字列を操作するための多くの関数が含まれている。
これには、文字列のコピー、連結、長さの取得、比較などが含まれる。
これらの関数はstring.hのヘッダーファイルで定義されている。
- strcpy(destination, source): ある文字列を別の場所にコピーする。
- strcat(destination, source): 一つの文字列の終端に別の文字列を連結する。
- strlen(string): ヌル文字を除く文字列の長さを返す。
- strcmp(s1, s2): 二つの文字列を辞書順で比較する。s1の方が後なら1、先なら-1、同じは0になる。
下記の例では、strcat()を使用してgreetingにnameを連結し、strlen()で連結後の文字列の長さを計算している。
文字列の連結と長さの計算
■文字列とメモリ管理
文字列を扱う際は、配列が適切なサイズであることを確認する必要がある。
バッファオーバーフローは、文字列が想定するメモリ領域を超えて書き込まれた場合に発生し、
プログラムのセキュリティリスクを大きく高める可能性がある。
よって、安全なプログラミング習慣を身につけ、関数のセキュアなバージョン(例えばstrncpyやstrncatなど)を使用することが推奨される。
C言語における文字列操作は、これらの基本を理解し、適切に標準ライブラリ関数を活用することで、効率的かつ安全に行うことができる。
3.多次元配列
多次元配列は、C言語においてより複雑なデータ構造を表現するために使用される非常に有用なツールだ。 多次元配列を理解するには、まずその最も一般的な形態である二次元配列から始めるのが良い。 二次元配列は、行と列の概念を持つ表やグリッドとして視覚化することができる。
■多次元配列の宣言
多次元配列は、以下のように宣言される。この例では、int型の2次元配列を宣言している。
下記の例では、matrixは3行4列の要素を持ち、それぞれの要素はint型になる。
配列の各要素には、matrix[行][列]の形式でアクセスできる。
二次元配列の宣言
■多次元配列の初期化
多次元配列の初期化は、その構造に応じて行われる。
以下は、具体的な初期値を与えて2次元配列を初期化する例になる。
ここでは、各行の要素がカーリーブレース{}で囲んでおり、
全体としてもう一度カーリーブレースで囲むことで、2次元配列の形を明確にしている。
二次元配列の初期化
■多次元配列の使い方
多次元配列の主な用途は、データを表形式で管理することだ。
例えば、行列計算、画像データの処理、ゲームボードの状態管理など、多岐にわたる。
下記コードでは、2次元配列の各要素を順番にアクセスし、それをコンソールに出力している。
ループを二重に使用することで、行と列の各要素に順番にアクセスする。
二次元配列の初期化
■多次元配列の注意点
多次元配列を使用する際には、メモリの使用量に注意が必要だ。
特に、大きな多次元配列をローカル変数として宣言すると、スタックオーバーフローを引き起こす可能性がある。
また、配列のインデックスが範囲外にならないようにすることも重要だ。
多次元配列を理解し、適切に使用することで、C言語におけるデータの扱いがより柔軟かつ効率的になる。
それにより、より複雑なプログラミング課題に対応する能力が向上する。
4.配列とポインタの基本的な関係
C言語における配列とポインタの関係は非常に密接であり、理解することがプログラミングの効率と正確性を高める鍵となる。
配列とポインタはしばしば相互に使用されるため、その違いと相互作用を理解することが重要だ。
■配列とポインタの基本的な関係
配列の名前は、配列の最初の要素のアドレス、すなわちメモリのアドレスを指すポインタとして振る舞う。
これは、配列名がポインタとして使われることが多い理由だ。これは前回の第2項で説明した通りである。
■配列とポインタの関係
ポインタ演算を使用すると、配列の要素に簡単にアクセスできる。
ポインタに整数を加えることで、配列の要素間を移動することが可能になる。
下記のp[2]はポインタの最初のアドレスから2つ分進んだアドレスを指すので、arr[2]と同じになる。
また、p+=2として、*pの値を求めた場合もp[2]と同様の値になる。
ポインタと配列の関係
■文字列とポインタ
C言語の文字列もまた、char型の配列として表現される。
文字列の名前は文字配列の先頭を指すポインタとして扱われる。
これにより、ポインタ演算を使って文字列データにアクセスすることができる。
文字列とポインタ
配列とポインタの関係を理解することは、C言語のプログラムでデータを効果的に扱うための基礎になる。 配列の操作、関数への配列の渡し方、文字列の取り扱いにおいて、ポインタの知識は不可欠だ。
5.まとめ
第6回では、C言語における配列と文字列について詳しく学んだ。 配列は同じデータ型の要素を連続的に格納するデータ構造で、効率的なデータアクセスを提供する。 配列の基本的な操作、多次元配列の使用方法、および配列とポインタの密接な関係について説明した。 文字列は特殊な文字配列として扱われ、ヌル文字によって終了が示される。 文字列の操作には標準ライブラリの関数が利用され、これにより文字列のコピー、連結、長さの測定などが可能だ。 配列と文字列を理解することは、C言語で効率的なプログラミングを行う上で基礎的であり、多くの応用が可能になる。
▼参考図書、サイト
「かんたん C言語」 大川内 隆朗 技術評論社
「12歳からはじめる ゼロからのC言語ゲームプログラミング教室」 リブロワークス