前回、ポインタとは何かと、それをC言語でどう使うかを解説した。
内容は、大丈夫だろうか。
今回は、ポインタ中編ということで、この知識が関連してくる範囲をお話しよう。
…本当はそれらがポインタにどう関係するかまで今回やりたかったのだが、予想以上に長くなったので、まさかの3部構成とする。
ポインタとタイトルに入ってしまっているが、今回の内容も単純によく使うので、しっかり身に付けていこう。
今回の説明内容
今回は中編ということで、文字列と配列について解説する。
これらは、一見ポインタとは関係なさそうだが、実は密接な関係がある。
次回の後半では、これらとポインタの関係について解説する。
というわけで、今回はちょっとポインタのことは忘れて、文字列と配列についてをしっかり見て欲しい。
文字列
最初に文字列からいこう。
初回の内容とちょっと重複するが、そもそも文字列とは何なのかから解説に入る。
文字列とは
まあそのままなのだが…文字列とは、0文字以上の文字の塊だ。
通常、ダブルクォーテーションで囲ったものを文字列リテラルとしている。
Java、C言語においては、シングルクォーテーションは1文字を表すので、そこを間違えないようにしてほしい。
ただ、JavaScriptの場合はシングルクォーテーションでも大丈夫だ。
で、初回の時には、Hello World!という文字列を表示していた。
ここでは表示のみ行っていたが、リテラルということは、もちろん変数にも入れることができる。
具体的な言語で、その使い方を見ていこう。
Javaの使用例
Javaでは、文字列はString型になる。
文字列を格納する変数を用意し、それを単純に出力するプログラムを書いてみよう。
class Sample07 {
public static void main(String args[]) {
String str = "文字列";
System.out.println(str);
}
}
一つ注意。
コンパイル時に、「この文字は、エンコーディングMS932にマップできません」というエラーが発生する場合がある。
この時は、このファイルの文字コードを確認し、それをオプションで指定してあげる必要がある。
私の場合はUTF-8で書いていたため、コンパイル時のコマンドは以下のようになる。
javac -encoding UTF-8 Sample07.java
他の文字コードだった場合は、UTF-8の部分を該当の文字コードに書き換えて欲しい。
さて、元の解説に戻ろう。
ソースコードの3行目、ここで文字列を格納する専用のString型変数str
を用意し、「文字列」という文字列を格納している。
それを、一個下の出力用処理に渡して、表示している、という感じだ。
通常の変数と特に変わりないので、問題はないかと思う。
C言語の使用例
問題はここから。
C言語の文字列は、以下2つの表現方法がある。
- 文字の配列として表現する方法
- 文字のポインタとして表現する方法
…このせいで、文字列の解説がこんなタイミングになってしまった。なんて愚痴は置いておいて。
C言語においては、文字列の実体は、文字の集合だ。
1文字を表すchar型を複数まとめたもの、という認識でいいだろう。
で、まだ解説していない配列も出てきてしまっているので、先に二つ目だけ説明しておく。
使った例だけ先にお見せしよう。やっていることは、Javaの内容と同じ。
#include<stdio.h>
int main(){
char *str = "文字列";
printf("%s\n", str);
return 0;
}
解説するべき点は2点。
まず、4行目の宣言部。上にも書いた通り、char型へのポインタという形で文字列用変数を定義する。
で、5行目の出力。出力文字列の中に、以前数字を出力する場合は%d
を入れると書いた。
これが、文字列の場合には%s
となる。
一旦、使うだけならこのくらいだ。
JavaScriptの使用例
これは、特に何も考えずに使えてしまう。
var str = "文字列";
console.log(str);
これだけだ。追加で解説することもない。
文字列の連結
さて、どの言語でも大体やりたいことが、この文字列の連結だ。
これは、Java/JavaScriptとC言語で異なる。
…厳密にはJavaとJavaScriptも異なる方法があるのだが、簡単な例は同じなのでそちらを紹介しよう。
JavaとJavaScriptの文字列連結
これは、文字列同士を単純に足し算してあげればいい。
例えば、Hello
とWorld
という二つの文字列を足した場合、結果はHelloWorld
となる。
また、数値などを足した場合も、その数値が文字列として足されることになる。
C言語の文字列連結
これには、幾つか専用の処理が用意されている。
…のだが、次回後編で説明しよう。いったん保留とさせてもらう。
配列
次に、配列について説明していく。
配列とは
配列とは、複数の変数をまとめるようなものだ。
例えば、数字を100個持っておきたい場合。いちいち100個の変数を定義するのも面倒だ。
そこで、同じ変数名でまとめて100個定義し、その何番目という形でアクセスできる。
この時、共通する注意点として、何番目というものを指定するときに、ほとんどが0から数え始める。
そのため、普通に数えて3番目の数を使う場合は、0から数えると2番目になるので2を指定することになる。
よく間違えるところなので、覚えておいて欲しい。
具体的な書き方と共に見ていこう。
Javaの使用例
Javaでは、以下のように使う。
class Sample08 {
public static void main(String args[]) {
int arr1[] = {1, 2, 3};
System.out.println("arr1の一つ目の要素:" + arr1[0]);
System.out.println("arr1の二つ目の要素:" + arr1[1]);
System.out.println("arr1の三つ目の要素:" + arr1[2]);
int arr2[] = new int[3];
arr2[0] = 4;
arr2[1] = 5;
arr2[2] = 6;
System.out.println("arr2の一つ目の要素:" + arr2[0]);
System.out.println("arr2の二つ目の要素:" + arr2[1]);
System.out.println("arr2の三つ目の要素:" + arr2[2]);
}
}
先に、配列用変数の宣言方法から。二通り書き方があり、以下どちらかだ。
型[] 変数名;
型 変数名[];
型か変数名の後ろに中身の無い大括弧をつけてあげればOKだ。
次に代入方法。ここでは、二つの配列の代入方法を書いている。
まず、3行目。ここでは、中身を直接代入する形になっている。
このように、中括弧で要素をコンマ区切りにして書くと、そのままそれが配列になる。
次に、8行目。こちらでは、中身は置いておいて、とりあえずいくつの要素を持つ配列かを先に決めておく。
そして、その後に一つずつ代入を行っている。
配列の各要素へのアクセス方法は、以下の通り。
配列変数名[添え字]
このアクセス方法は大体の言語共通なので覚えておこう。
もちろん、ここに値を代入したり、この値を使ったりもできる。
C言語の使用例
C言語も、考え方はJavaと同じだ。
#include<stdio.h>
int main(){
int arr1[] = {1, 2, 3};
printf("arr1の一つ目の要素:%d\n", arr1[0]);
printf("arr1の二つ目の要素:%d\n", arr1[1]);
printf("arr1の三つ目の要素:%d\n", arr1[2]);
int arr2[3];
arr2[0] = 4;
arr2[1] = 5;
arr2[2] = 6;
printf("arr2の一つ目の要素:%d\n", arr2[0]);
printf("arr2の二つ目の要素:%d\n", arr2[1]);
printf("arr2の三つ目の要素:%d\n", arr2[2]);
return 0;
}
一つ、Javaと異なる点を挙げると、要素数で配列を宣言する部分。
C言語では、new 型[要素数]
を代入するのではなく、型 変数名[要素数];
と書くだけで問題ない。
ここで、Java、C言語共通で気を付けること。
どんな宣言方法でも、最初に必ず要素数が決定している。
この要素数について、これら2言語ではこれ以上の範囲を指定しようとするとエラーが発生する。
つまり、配列の要素数は別の処理をしないと変更できないので注意しておこう。
JavaScriptの使用例
JavaScriptの使用例は、以下の通り。
var arr1 = [1, 2, 3];
console.log("arr1の一つ目の要素:" + arr1[0]);
console.log("arr1の二つ目の要素:" + arr1[1]);
console.log("arr1の三つ目の要素:" + arr1[2]);
var arr2 = new Array(3);
arr2[0] = 4;
arr2[1] = 5;
arr2[2] = 6;
console.log("arr2の一つ目の要素:" + arr2[0]);
console.log("arr2の二つ目の要素:" + arr2[1]);
console.log("arr2の三つ目の要素:" + arr2[2]);
まず1行目。こちらでは、宣言部分に大括弧がつかない。単純に配列を代入するだけで行ける。
で、注意して欲しいのが6行目。
こちらがJavaScriptの要素数で定義するものなのだが、この右側に書いてあるnew Array()
には、色々とできることがある。
括弧の中に渡すものによって、意味が変わってくるのだ。
- new Array()だけ書いた場合、要素が0個の配列
- new Array(数字以外)を書いた場合、それを要素とし、その要素一つのみを持つ配列
- new Array(数字)を書いた場合…
- 数字が0以上の場合、空の要素をその数だけ持つ配列
- 数字が0未満(マイナスの値)の場合、エラー
- new Array(要素1, 要素2, …, 要素n)を書いた場合、そのn個の要素を持つ配列
今回は、3つ目の中の一つ目に該当する。
数字の3を入れているので、3つの空の要素を持つ配列を作成しているのだ。
逆に、これを使えば、1行目もvar arr1 = new Array(1, 2, 3);
と書き直すこともできる。
また、JavaScriptの場合には、3つの要素を用意したとしても、4つ目に値を入れることもできてしまう。
例えば、上のソースコードの下に、arr2[3] = 7;
と書けば代入できるし、それも代入した後なら表示できる。
その他は、Java, C言語と共通になる。
C言語の文字列について
上の文字列の部分で、C言語の文字列は二つの表現方法があると書いた。
そのもう一つを解説しよう。今解説した配列を使用する。
char str[最大文字数] = 文字列;
こんな感じで宣言、代入を行うことができる。
なお、最大文字数は省略することができ、省略した場合は、代入した文字列によって自動的に調整される。
では、上でやったchar型のポインタとしての文字列を、今度は配列として使ってみる。
#include<stdio.h>
int main(){
char str[] = "文字列";
printf("%s\n", str);
return 0;
}
上の例と違うのは、4行目だけだ。
最初はchar *str
だったのが、今回はchar str[]
になっているだけ。
…というのも、実はこれらは同じものを表している。
それを解説…したかったのだが、ちょっと長くなってしまった。いったんここで打ち切ろう。
まとめ:文字列と配列
今回は、文字列と配列について扱った。
文字列は0文字以上の文字の塊。多くの場合はダブルクォーテーションで囲む。
JavaではString型、C言語ではchar型の配列、もしくはポインタとして扱う。
配列は、一つの変数名で大量のデータを扱うことのできるものだ。
Java、C言語では最初に決めた要素数の範囲しか使えないので、そこも注意しよう。
次回は、これらとポインタの関係をお話しよう。
ここで、ようやくJavaやJavaScriptでもポインタの考え方が出始める。
慎重に進めていってもらいたい。
更新情報はTwitterでも呟いている。よかったら、ページ下部のTwitterアイコンから覗いていってほしい。
それでは。
コメント