C言語
前回、C言語での文字列のポインタを学んでみました。
今回はC言語での配列を勉強していきたいと思います。
それでは始めていきましょう。
Pythonでの配列
まずは比較のためにPythonでの配列を確認していきましょう。
Pythonでの配列は「配列名 = [要素1, 要素2, 要素3, …]」という形で指定できました。
また要素を取り出す場合は「配列名[インデックス番号]」で取り出すことができます。
文字列でも数値でも同じ操作で配列を作成、要素を取得することができます。
str_array = ['str1', 'str2', 'str3', 'str4', 'str5']
int_array = [1, 2, 3, 4, 5]
print(str_array)
print(str_array[2])
print(int_array)
print(int_array[2])
実行結果
['str1', 'str2', 'str3', 'str4', 'str5']
str3
[1, 2, 3, 4, 5]
3
また文字列の場合は、さらに文字列中のインデックス番号を指定することで特定の文字を取得することも可能です。
str_array = ['str1', 'str2', 'str3', 'str4', 'str5']
print(str_array[2][3])
実行結果
3
文字列=文字の配列
それではC言語での配列を学んでいきますが、先に文字列の配列を見てみましょう。
ということでこのプログラム。
どこかで見覚えないでしょうか?
#include <stdio.h>
int main(void)
{
char array1[7] = "array1";
printf("%s", array1);
}
実行結果
array1
実はこれ文字列の定義の仕方を学んだ時に出てきた書き方です。
Pythonだとあまり意識していなかったのですが、文字列自体がすでに「文字の配列」だということに気付かされました。
またC言語だから「文字列=文字の配列」ではなく、先ほどPythonでもやったように文字列の中の文字をインデックス番号で指定できることから、Pythonでも「文字列=文字の配列」としてプログラム内ではしっかり認識されているようです。
ということで「文字≠文字列」、「文字列=文字の配列」というのはC言語を学んだおかげで明確になった部分かなと思います。
ということで話を戻しましょう。
C言語での文字列は文字の配列なのですが、先ほどの書き方では配列としての書き方になっていません。
C言語での配列の定義は「データ型 配列名 = {要素1, 要素2, 要素3, …}」です。
ということで先ほどの文字列を配列の書き方に変えてみましょう。
#include <stdio.h>
int main(void)
{
char array2[7] = {'a', 'r', 'r', 'a', 'y', '2'};
printf("%s", array2);
}
実行結果
array2
変換指定子を「%s(文字列)」ではなく「%c(文字)」に変えて、一つずつ出力してみるとこんな感じ。
#include <stdio.h>
int main(void)
{
char array2[7] = {'a', 'r', 'r', 'a', 'y', '2'};
printf("%c %c %c %c %c %c", array2[0],array2[1],array2[2],array2[3],array2[4],array2[5]);
}
実行結果
a r r a y 2
文字列は「文字の配列」だってことが実感できるかと思います。
ちなみに変換指定子に関してはこちらの記事をどうぞ。
C言語での文字列の配列
先ほど文字列は文字の配列だとお話ししましたが、今回やりたいことはそうではなく、「文字列の配列」を作りたいわけです。
ということで先ほどの文字の配列を、単純に「文字列の配列」にしてみました。
#include <stdio.h>
int main(void)
{
char array3[3] = {"strA", "strB", "strC"};
printf("%s %s %s", array3[0],array3[1],array3[2]);
}
実行結果
array4.c:5:23: warning: initializer-string for char array is too long [-Wexcess-initializers]
char array3[3] = {"strA", "strB", "strC"};
^~~~~~
array4.c:5:31: warning: excess elements in char array initializer [-Wexcess-initializers]
char array3[3] = {"strA", "strB", "strC"};
^~~~~~
array4.c:7:24: warning: format specifies type 'char *' but the argument has type 'char' [-Wformat]
printf("%s %s %s", array3[0],array3[1],array3[2]);
~~ ^~~~~~~~~
%c
(以下略)
ただしこれではエラーになります。
ではどうするかというと、「文字列=文字の配列」なので「文字の配列の配列」、つまり2次元配列にする必要があります。
コマンドとしては「char 配列名[要素数][文字列の長さ] = [要素1, 要素2, 要素3, …]」という書き方になります。
#include <stdio.h>
int main(void)
{
char array3[3][5] = {"strA", "strB", "strC"};
printf("%s %s %s", array3[0],array3[1],array3[2]);
}
実行結果
strA strB strC
これで文字列の配列を作成することができました。
もちろんこの場合でもさらにインデックス番号を指定することで文字列中の文字を取得することが可能です。
#include <stdio.h>
int main(void)
{
char array3[3][5] = {"strA", "strB", "strC"};
printf("%c %c %c", array3[0][3],array3[1][3],array3[2][3]);
}
実行結果
A B C
C言語での数値の配列
次に数値の配列を学んでいきます。
配列の作成の仕方は先ほどの文字列の配列の作成の仕方と同じで「データ型 配列名[要素数] = {要素1, 要素2, 要素3, …}」です。
ということでint型(整数)の配列はこんな感じ。
#include <stdio.h>
int main(void)
{
int array4[5] = {1, 2, 3, 4, 5};
printf("%d %d %d %d %d", array4[0],array4[1],array4[2], array4[3], array4[4]);
}
実行結果
1 2 3 4 5
数値の場合は文字列とは違い2桁以上の数値でも「数値列」ではない、つまり2桁の数値でも一つの値(11でも’1’と’1’を連結したものではない)ため、2桁以上の数値でもそのまま扱うことができます。
#include <stdio.h>
int main(void)
{
int array4[5] = {11, 12, 13, 14, 15};
printf("%d %d %d %d %d", array4[0],array4[1],array4[2], array4[3], array4[4]);
}
実行結果
11 12 13 14 15
小数とする場合は、データ型にfloatを指定します。
#include <stdio.h>
int main(void)
{
float array5[5] = {0.1, 0.2, 0.3, 0.4, 0.5};
printf("%f %f %f %f %f", array5[0],array5[1],array5[2], array5[3], array5[4]);
}
実行結果
0.100000 0.200000 0.300000 0.400000 0.500000
異なるデータ型が混ざった配列
ここでふと思った疑問。
Pythonでは複数のデータ型が一つの配列中に存在していても扱うことができます。
arrays = ['str1', 2, 0.3]
print(arrays)
実行結果
['str1', 2, 0.3]
C言語では配列を作成する際にデータ型を指定するので、同じように複数のデータ型が入った配列は作れないと考えられます。
ということで試してみました。
#include <stdio.h>
int main(void)
{
char array6[3][4] = {"str1", 2, 0.3};
printf("%s %d %f", array6[0], array6[1], array6[2]);
}
実行結果
array10.c:5:37: warning: implicit conversion from 'double' to 'char' changes value from 0.3 to 0 [-Wliteral-conversion]
char array6[3][4] = {"str1", 2, 0.3};
~ ^~~
array10.c:7:35: warning: format specifies type 'int' but the argument has type 'char *' [-Wformat]
printf("%s %d %f", array6[0], array6[1], array6[2]);
~~ ^~~~~~~~~
%s
array10.c:7:46: warning: format specifies type 'double' but the argument has type 'char *' [-Wformat]
printf("%s %d %f", array6[0], array6[1], array6[2]);
~~ ^~~~~~~~~
%s
3 warnings generated.
str1 -1285709360 0.000000
ということでやっぱりダメでした。
int型(整数)とfloat型(小数)くらいならいいだろう、指定するデータ型はより制限の厳しいfloat型にしておけばいいだろう、と思って試してみたのがこちら。
#include <stdio.h>
int main(void)
{
float array7[2] = {1, 0.2};
printf("%d %f", array7[0], array7[1]);
}
実行結果
array11.c:7:21: warning: format specifies type 'int' but the argument has type 'float' [-Wformat]
printf("%d %f", array7[0], array7[1]);
~~ ^~~~~~~~~
%f
1 warning generated.
-1342409960 1.000000
指定変換子を両方float型にすれば表示はできますが、これは単に小数の配列を扱っているだけ(入力が整数に見えるだけ)です。
#include <stdio.h>
int main(void)
{
float array7[2] = {1, 0.2};
printf("%f %f", array7[0], array7[1]);
}
実行結果
1.000000 0.200000
ということでPythonと比べるとデータ型を明確にして配列を作成するというのが特徴のように捉えられました。
配列を勉強したら、次はその配列から要素を順々に取得していきたくなります。
ということで次回は繰り返し関数に関して勉強していくことにします。
ではでは今回はこんな感じで。
コメント