C言語入門講座

トップ>コンテンツ>C言語>2.変数・配列

 当講座はメールマガジン「Cプロダクション」の2000年5月10日から2002年7月31日までの記事を再編集したものです。

2.変数・配列

2-1. 変数の説明と宣言
2-2. 文字型の取り扱い
2-3. 実数を扱うには
2-4. データ型の拡張
2-5. 定数
2-6. 配列を使う

2-1. 変数の説明と宣言

◆変数とは

 数学で変数といえば未知数であったり、ある関数の要素だったりします。

とにかく、使う変数を宣言することから事は始まります。
ということで変数の宣言の仕方

int a ;  /* 整数型の変数 a を宣言 */

これで a という変数が宣言されました。これでこの変数を使うことが出来ます。
次に、どうやって使うか。

a = 10 ;

はい、ここでは変数 a に10を『代入』しました。C言語では(=)は右の数字を
左に代入する記号として使われています。
ですから、

a = 3 + 5 ;  /* a に 8 が代入されます。*/
a = 10 ;

としても何ら問題はないのです。
これを理解するのに1年間かかりました。(小学3年の時ですけど...)

こうやって変数に計算結果や定数を代入できますが、これだけでは画面に表示
されないので『見えません』

そんなわけで、今日は変数を表示させるところまで行きましょう。
下のプログラム

#include<stdio.h>
main()
{
    int a = 1;          /* 初期値1の整数 a */
    printf("%d\n",a);
}

実行すると画面に1と表示されます。

解説:
 ここでprintf関数は新たな使い方をしています。%dは10進整数を表示する
変換指定です。そして、文字列の後、(,)カンマで区切って変数名を書きます。
もちろん文字列と組み合わせて表示することが出来ます。 その例を以下に示
します。

#include<stdio.h>
main()
{
    int a = 1;
    printf("変数 a の値は%dである\n",a);
}

出力結果:
変数 a の値は1である

となります。%dの位置にちょうど数値が入っていることがわかります。
また、複数の変数を表示することが出来ます。

#include<stdio.h>
main()
{
    int a = 1, b = 2, c = 3;
    printf("各変数の値は a = %d, b = %d, c = %d である\n",a,b,c);
}

出力結果:
各変数の値は a = 1, b = 2, c = 3 である

%dと変数の順番が対応しているのがわかります。
このようにprintfを使うことで変数の中身も表示できます。


◆変数を宣言します

 まず、基本的な変数の宣言から

    int a;

これは、整数型の変数 a を宣言するという意味になります。
intはinteger(整数)の意味になります。
また、複数の変数を宣言する場合

    int a, b, c ;

このように、同じ型の変数はカンマで区切ることにより続けて宣言できます。
 よって上の変数宣言の形式は、

    データ型 変数名1,変数名2,・・・ ;

となっています。
 それでは、変数の宣言はどこにすればよいのでしょうか?
 変数はプログラム中すべての領域で宣言できますが、宣言をしたブロック内
の範囲でしか使用できません。
 これは、共同作業でプログラムを組んだ場合、同名の変数が存在する時があ
ります。そのとき違う目的で宣言された変数が共有されてしまうと処理がうま
くいかなくなります。
 そのためC言語では変数の有効な領域に制限が設けられています。

●変数名に使える名前(識別子)
A〜Z,a〜z,0〜9,_が使用できます。ただし先頭の文字には数字が使えません。
 また、変数名や後に出てくる関数名など自分で定義するものの名前は識別子と
呼ばれこの規則が適用されます。

◆データのいろいろ

 変数のデータ型について基本的なものを以下に示します。[]で囲まれた部分は
省略可能であることを示しています。

    文字型 char
    整数型 int
    実数型 float
 倍精度実数型 double

 この4つが基本的なデータ型です。intについては上でも少し書いていますが
もっと詳しくすると、

整数型(int)
 データ長:16または32ビット
 扱える値:16ビットの場合        -32,768〜32,767
      32ビットの場合 -2,147,483,648〜2,147,483,647
となります。(32ビットになると普通の電卓の範囲を越えてますね〜)

いま、『ビット』という単語が出てきましたがここでちょっと説明します。
ビットと呼ばれるのは2進数の1桁に相当します。細かいことは省きますが
16ビットというときは10進数(普段使う進法)になおすと、
2の16乗=65536になります。つまり16ビットは65536種類の
数値が扱えるので正と負と0を含むと上のような範囲になるわけです。

またintが16ビットなのか32ビットなのかはコンピューターの処理系によっ
て異なります。(現在のコンピューターは大抵32ビットです)

int a=1000;

さて、変数aを上で宣言しました。今までと違うのは宣言と同時に値を代入して
います。これは、

int a; a=1000;

と同じになります。このように変数は宣言と同時に初期値を代入することが出
来ます。

なお、intは整数型なので整数以外のものは代入してはいけません。

int a=10.2 ; /* 小数を代入している */

このような代入をした場合コンパイラによって『警告』がでるか、小数点以下
が切り捨てられるという事故が起きます。

そのほか注意すべきなのは数値が範囲の外に出ないことです。(オーバーフロー)
具体的に電卓だと E マークつくような計算をしないことです。

2-2. 文字型の取り扱い

『文字型の取り扱い』というテーマでchar型を宣言します。
宣言の仕方はintのときと同じように

char c;

のように宣言します。
文字のデータ型なので次に文字を代入してみます。

c = 'A';

 いま変数cに文字Aを代入しました。(')シングルクォーテーションで囲むこ
とが重要です。そうでなければ

c = A ;

変数cに変数Aの値を代入の意味になってしまうからです。
最初の例で変数cに文字Aが代入されましたが確認のためprintf()で表示してみ
ましょう。

#include<stdio.h>
main()
{
    char c;
    c = 'A';
    printf("%c\n",c);
}

このプログラムを実行すると画面にAと表示されたはずです。ここでprintf()は
新しい使い方をしています。intのとき%dだったのが%cを使っています。

この%cは文字として表示すると言う意味です。

実を言うと文字型の変数も中身はただの数値です。ただし、上のプログラムの
例のように文字を代入した時、その文字に対するコード番号が代入されます。

逆にいえば、変数cに直接数値を代入し文字を表示させることが出来ます。

#include<stdio.h>
main()
{
    char c;
    c = 65;
    printf("%c\n",c);
}

このプログラムは結果として前のプログラムと同じになります。
今度は、文字からコードを導いて見ましょう。

#include<stdio.h>
main()
{
    char c;
    c = 'A';
    printf("%d\n",c);
}

これを実行すると65と表示され文字Aがコード番号65であることがわかると思い
ます。

最後にchar型について前回と同じく詳細を説明します。

データ長  8ビット(=1バイト:半角1文字)
数値の範囲 -128〜127 (開発環境によって違うかもしれません)

これらを見るとcharは小さな整数型としても使うことが出来ます。

2-3. 実数を扱うには

◆実数を扱うには

 整数型も終わり『実数型』に突入します。

実数型の最初はfloatです。

データ長の長さは開発環境によって違いますが現在は32ビットが多いと思い
ます。

気になる方は以下のプログラムを実行してみてください。
(今回はこのプログラムについての解説はありません)

#include<stdio.h>

main()
{
    printf("char   = %d byte\n",sizeof(char));
    printf("int    = %d byte\n",sizeof(int));
    printf("float  = %d byte\n",sizeof(float));
    printf("double = %d byte\n",sizeof(double));
}

ちなみにVC++4.0では
char   = 1 byte
int    = 4 byte
float  = 4 byte
double = 8 byte

と表示されました。1byte = 8bit よりそれぞれ
char   =  8 bit
int    = 32 bit
float  = 32 bit
double = 64 bit

になります。

前置きが長くなりましたが宣言の仕方はいつもどうりに、

float f;

でよいのですが今度は数値の代入の仕方に気をつけることがあります。

f = 2133.3123;

とするのはいいのですが、整数を代入した場合コンパイラによっては警告が出
されますので。

f = 10.0;

と言うかんじに.0を付けることをオススメします。

とういうことで、代入した値をprintf()で表示させましょう。

#include<stdio.h>

main()
{
    float f;
    f = 2133.3123;       /* コンパイラによってはここでも警告が出る */
    printf("f = %f\n",f);
}

実行すると

f = 2133.312256

と表示されました。どの開発環境でも代入によって誤差が発生するこ
とがあります。

※2進数と10進数の間で割り切れない数値に違いがあり、
 10進→2進→10進と変換したときに切り捨てられた端数が誤差として
 発生するためです。

また、printf()では%fが使われています。これは小数として表示する働きがあ
ります。


◆もう一つの実数型

 上記でfloat型を取り扱いましたが、さらにもう一つ実数型が存在します。
それはdoubleという倍精度実数型(倍長実数型と呼ぶ場合もある)です。

倍精度(倍長)の名の通りfloatの約2倍の指数(2倍長の小数)を扱うことができ
ます。

データ長もfloatの2倍になり、64ビットになります。
(処理系に依存しますが...)

 floatでは固定小数として表示しましたが実数型の変数は浮動小数なので、
floatもdoubleも実際に代入されている値は、

1.234e+12   1.234×10の12乗

のようになっています。

ということで、double型の変数を宣言して、指数形式で表示します。

#include<stdio.h>

int main()      /* 今回 int main() にしましたが気にしなくて結構です */
{
    float  f;
    double d;

    f = 1234.567f;  /* 数値の後の f に注目 */
    d = 0.000123;

    printf("変数 f = %e\n",f);
    printf("変数 d = %e\n",d);

    return 0;  /* int main() にしたので付加しています */
}

どうなりましたか?
前回のプログラムで警告が出た方も今回のは出てきてないと思います。

画面には

変数 f = 1.234567e+003
変数 d = 1.230000e-004

と表示されていると思います(上の例はVC++4.0)

e-004 は10のマイナス4乗の意味です。

ここでもprintf()の新しい使い方をしています。

%e は変数(定数)を指数形式に表示する意味を持ちます。

今まで紹介してきた %d %f %c %e はprintfの変換指定子とよばれます。
変数のデータ型に依存しないので使い方を間違えてもコンパイルエラーになり
ませんし計算結果にも影響は起きません。

ただ、小数を%dで整数として表示すると小数点以下は四捨五入されます。

2-4. データ型の拡張

◆データ型の拡張

 今までやってきたデータ型に修飾子を付けてもっと詳しくやって行きたい
と思います。

 まずは、unsigned から、

修飾子を付ける時の書式は

[修飾子][データ型][変数名];

となります。unsigned の意味は符号無しでわかりやすく言うと負の数がないこ
とをいいます。

unsigned int i;

とした場合、変数iは正の整数になりデータの範囲は、0〜65,535(16bitの場合)
になります。

ここで補数の解説はしませんが、負の数を使わないぶん正の数の範囲が倍にな
ったと考えていただいて結構です。

ちなみにintの場合、unsignedだけでintの記述を省略することができます。

unsigned int i;
unsigned     j;  /* これでも良い */


◆int型の拡張

1.short

 単純に短いの意味です。大抵データ長が16ビットになります。
 16ビットシステムではshortを付けなくても16ビットですが、32ビット
システムでshortを使うときは付ける必要があります。
(基本的に移植性を考えれば面倒でもshortをつけるべき)
 shortを使う理由としては大きな数値を使わない場合にメモリの節約になるか
らです。
 特に配列になると差がわかります。(そういえば配列の説明をしてない...)

では宣言の例を

short int i;
short     j;

上のとおり int は省略できます。

昨日紹介したunsignedと併用する時は

unsigned short int i;

のように使います。


2.long

 今度はshortの反対でlongです。
longを使用するとデータ長が倍になり32ビットになります。
ただし、32ビットシステムではlongを使用してもしなくても32ビットです。

宣言の仕方はshortの時と同じく

long int i;
long     j;
unsigned long int k;

のようになります。

3.singed

 unsignedに対する修飾子としてsignedがあります。

通常、データ型のほとんどは符号付が標準になっているのでわざわざ使うことも
少ないと思います。

これを上の宣言文に加えてみると、

signed short int i;
signed short     j;

signed long int k;
signed long     l;

となります。

それでは、表示させましょう。

#include<stdio.h>

main()
{
    int c;
      signed short int i=1;
    unsigned short int j=1;

      signed long int k=1;
    unsigned long int l=1;

    printf(" sint=%d\n",sizeof(signed short int));
    printf("usint=%d\n",sizeof(unsigned short int));
    printf(" lint=%d\n",sizeof(signed long int));
    printf("ulint=%d\n\a",sizeof(unsigned long int));
    for(c=1;c<430;i+=100,j+=100,k+=10000000,l+=10000000,c++){
        printf("%8d %8u %12d %12u\n",i,j,k,l);
    }
}

特にプログラムについて解説はしません。結果だけを確認してください。
signed の変数には負になることがありますが unsigned は負になりません。


4.const

 これは宣言したオブジェクトを定数として扱うものです。

const によって宣言されたオブジェクトは以後、値の変更ができません。

よって、宣言時に初期化するきまりがあります。

const int i = 10 ;  /* 良い例 ○ */
const int i ;       /* 初期化してないので × */
i = 10 ;            /* 宣言以後の代入不可 × */

constによって書き換えの禁止ができるのでプログラムの安全性があがります。

5.volatile

 これは const に対して値が変更できるものです。
代入が行われたとき値の変更が行われ、呼び出しのとき常にメモリへアクセス
し現在値を読み込みます。

......volatile について何もつけないデフォルトの時と同じように思うのですが
どうなんでしょう?(自分もvolatileが特別なものかどうかがわからない)

2-5. 定数

◆定数とは?

 定数とはなんでしょう?と突然聞かれても意外と答えるのは難しいです。

未知数、既知数関係なしに一定で変わらない数ならば『定数』です。

 それでは定数にはどんな種類があるか?(もちろんC言語での種類)

1.整数(int型)
2.実数(float,double型)
3.文字(char型)

基本的にはこの3種類ですが細かくするとデータ型の種類と同じくらいです。

ということで今日は整定数を取り上げたいと思います。

接尾語 l,u,U,L

たとえば、

1234, 0, -45

これらは、int型の整定数です。次に

1234L, 0L, -45L

接尾語としてL(小文字でも良い)をつけるとlong型になります。

1234u 0u

接尾語がuの場合はunsigned int型になります。

これらを組み合わせて、

1234ul 0ul

として、unsigned long int型の整定数を記述することが出来ます。


接頭語 0x, 0

接頭語に0xを付けると16進数表記になります。

0x0000, 0x1234, 0xff3a

また接頭語が0の時は8進数表記になります。

0123, 0567

これまでが、整定数の表記の紹介です。
これから整定数を表示するプログラムを作ります。

#include<stdio.h>

main()
{
    printf("10進数int            %d %d %d\n",1234,0,-45);
    printf("10進数long           %d %d %d\n",1234L,0L,-45L);
    printf("10進数unsigned       %u %u %u\n",1234u,0u);
    printf("10進数unsigned long  %u %u %u\n",1234ul,0ul);
    printf("16進数int            %d %d \n",0x1234,0x0);
    printf("16進数long           %d %d \n",0x1234L,0x0L);
    printf("16進数unsigned       %u %u \n",0x1234u,0x0u);
    printf("16進数unsigned long  %u %u \n",0x1234ul,0x0ul);
    printf(" 8進数int            %d %d \n",01234,00);
    printf(" 8進数long           %d %d \n",01234L,00L);
    printf(" 8進数unsigned       %u %u \n",01234u,00u);
    printf(" 8進数unsigned long  %u %u \n",01234ul,00ul);
}

結果、次のように表示されたと思います。

10進数int            1234 0 -45
10進数long           1234 0 -45
10進数unsigned       1234 0
10進数unsigned long  1234 0
16進数int            4660 0
16進数long           4660 0
16進数unsigned       4660 0
16進数unsigned long  4660 0
 8進数int            668 0
 8進数long           668 0
 8進数unsigned       668 0
 8進数unsigned long  668 0

16進数で1234は10進数で4660、
8進数で1234は10進数で668になるのでこのようになります。

今回uとLの意味があまり無いようなプログラムを組んでしまいましたが、
通常のintではオーバーフロー(数値が範囲を超えて溢れ出す)するような
数値を代入する時につかうといいでしょう。
(別に使わなくても32ビットシステムではエラーにならないと思いますが)


◆浮動小数(実数)定数

 今日は浮動小数(実数)定数の記述について、

 基本的には小数点が必要です。小数点を付け忘れると整数とみなされ、
実数型の変数に代入する時にデータ型が合わないと『警告』が出る場合があり
ます。

それでは通常に小数点を付けた数値を記述した場合、

1234.5678

上の場合通常double型とみなされます。このままfloat型変数に代入すると
『警告』が出されることがあります。先週のプログラムで『警告』がでるのは
これが原因です。

じゃあfloat型変数に代入するためには?
接尾語としてf,Fを付けます。

1234.5678f

これでOKです。

また、浮動小数を記述するのに指数形式で表現したい時もあります。
そんなときは、e,Eをつかって

1.001e13
6e4
-2.345e-12

のように表せます。
1番目は1.001×10の13乗
2番目は6.0×10の4乗
3番目は−2.345×10の−12乗

です。

ただし、1つ注意点があります。

それは、

1234.5678L

のように小数点付きの定数にLをつけるとlong doubleになるということです。
long doubleというデータ型はシステムによっては無いと思われるのでメルマガ
では紹介していませんが、doubleのさらに高精度のデータ型です。

ということで今日のおさらい

#include<stdio.h>

main()
{
    printf("double %f\n",1234.5678);
    printf("float  %f\n",1234.5678f);
    printf("double %f\n",1.001e13);
    printf("double %f\n",6e4);
    printf("double %f\n",-2.345e-2);
    printf("long double %f\n",1234.5678L);
}

このプログラムを実行すると次のように表示されます。
(システムによって違うかも...)

double 1234.567800
float  1234.567749
double 10010000000000.000000
double 60000.000000
double -0.023450
long double 1234.567800


◆文字定数

ところで文字が定数であると言うのはどういう意味でしょうか?

文字はコンピューターの中で『文字コード番号』に基づいて処理されています。

というわけで、文字定数は最終的に文字コード番号のことをさします。

しかし、文字を入力するのにいちいち文字コードを使うのは現実的ではありま
せん。

そこで、C言語では対象とする文字の両脇に(')クォーテーションを付けること
によって、文字定数を記述することが出来ます。

たとえば、

'A'  't'  '8'  'f'

これらはすべて文字定数です。(8も数値ではなく文字として扱われます)
ただし、次のものは文字定数にはなりません。

'ABCDEFGH'
'漢'

上の'ABCDEFGH'は文字列なので文字定数になりません。また'漢'も文字列にな
ります。

なぜ?

文字定数はchar型変数1つ分のデータ長でなければいけません。
もちろん、全角文字はchar2つ分のデータが必要なので文字定数にはならない
のです。

そういうことで使えるのは1バイト文字だけになります。
ASCIIコードと1バイトのJISコードだけが使用可能です。
それでもJISコードを使用するときは、unsigned char型である必要があります。
それは半角カタカナ等が(161〜223)に定義されているためです。

では早速表示させて見ましょう。

#include<stdio.h>

main()
{
    printf("%c",'A');
    printf("%c",'B');
    printf("%c",'C');
    printf("%c",'D');
    printf("%c",'E');
}

これを実行すると

ABCDE

と表示されたと思います。次は ' を表示させて見ましょう。

しかし、両端に'を使用するので通常の方法では'を表示できません。
文字コードで表示させる方法もありますが、ここでは前にやったエスケープシ
ーケンスを使って表示させましょう。

#include<stdio.h>

main()
{
    printf("%c",'\'');
}

これでOKです。

               ◇───────────────────◇
               │文字定数にはエスケーシーケンスが使える│
               ◇───────────────────◇

ということです。

あと文字列定数と呼ばれているものもありますが、『配列』の時にしようと考
えています。

2-6. 配列を使う

◆配列を使う

まずは定義から、

int i[10];

これはint型の変数を10個配列にして定義すると言う意味になります。

データ型 配列変数名[要素数];

こんな感じになります。もちろん修飾子つけることもできます。

次に配列の初期化の仕方、

int i[10]={24,64,32,78,35,23,85,77,12,76};

これは宣言時に初期化する時の書き方です。10個の要素をカンマ区切りで記
述します。

また、宣言時に初期化する時は要素数を省略することが出来ます。
そのときは、初期化した要素の数により要素数が決定されます。

次に宣言時以外での代入(初期化)の仕方を示します。

i[0]=24;
i[1]=64;
i[2]=32;
i[3]=78;
i[4]=35;
i[5]=23;
i[6]=85;
i[7]=77;
i[8]=12;
i[9]=76;

とこんな感じです。ここで注目すべき点は要素番号が0から始まることです。
宣言時と違うのはカッコの中は要素番号になっていることです。

float double型の配列に関しても同じことです。

#include<stdio.h>

main()
{
    int i[10]={24,64,32,78,35,23,85,77,12,76};
    int count;
    for(count=0;count<=9;count++){
        printf("i[%d]=%d\n",count,i[count]);
    }
}

このプログラムを実行すると

i[0]=24
i[1]=64
i[2]=32
i[3]=78
i[4]=35
i[5]=23
i[6]=85
i[7]=77
i[8]=12
i[9]=76

と表示されたとおもいます。プログラムと合わせ見るとて配列全体と要素の
対応がわかると思います。


◆文字の配列

char型の配列、文字列の表示をします。

宣言時のフォーマット

char mojiretu[10]={'A','B','C','D','E','F','G','H','I','\0'};

とまあこんな感じで初期化できますが余り実用的ではないですね。
そんなわけで(本当にそんなわけなのか?)特別な初期化法があります。

それは、(")ダブルクォーテーションをつかうことでもっと簡単にできます。

char mojiretu[10]={"ABCDEFGHI"};

上の例では\0の記述が見られませんが、ダブルクォーテーションで囲まれた文
字列には終端記号として自動的に\0が付加されます。

これが重要で文字列を表示する時に文字列の終わりの記号として\0を検出する
と文字の出力を終了するようになっています。(でなければ暴走する)

もちろん\0の分のメモリは確保しなくてはなりませんので最低でも格納する文
字数+1の要素数が必要です。(全角文字1つはは2文字で計算)

ついでですがダブルクォーテーションを使って文字列の初期化する時は、
{}中括弧を省略することが可能です。

char mojiretu[]="ABCDEFGHIJ";

このように要素数を省略したときは初期値によりメモリの確保が行われます。
(必ず宣言時に初期化する必要があります)

char zenkaku[]="漢字";

もちろん、全角文字を格納するときはダブルクォーテーションを使わないと大
変です。


◆二次元配列

 それでは、二次元配列に移りましょう。とりあえず見た目から...

int matrix[3][4]={ { 1,  2,  3,  4 },
                   { 5,  6,  7,  8 },
                   { 9, 10, 11, 12 } };

これは3×4の行列です。

初期化するとき、列ごとに中括弧で囲んでいますが特になくてもかまいません
(ただし、見栄えは悪くなります)

int matrix[3][4]={ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 };

 確かに、見栄えが悪いですね... でもメモリに格納される順番は同じなので
両方ともまったく同じ配列として使用できます。

アクセスするときは今まで同じように行・列ともに0番目より始まります。

matrix[0][0]=1;
matrix[0][1]=2;
matrix[0][2]=3;
matrix[0][3]=4;
matrix[1][0]=5;
matrix[1][1]=6;
matrix[1][2]=7;
matrix[1][3]=8;
matrix[2][0]=9;
matrix[2][1]=10;
matrix[2][2]=11;
matrix[2][3]=12;

実際は上のように対応しています。


◆配列を使いこなそう

さっきは、二次元配列の宣言について少し触れてみました。

int matrix[3][4]={ { 1,  2,  3,  4 },
                   { 5,  6,  7,  8 },
                   { 9, 10, 11, 12 } };

通常上のとおりですが、ここで要素数の省略をやってみます。

int matrix[ ][4]={ { 1,  2,  3,  4 },
                   { 5,  6,  7,  8 },
                   { 9, 10, 11, 12 } };

これは、コンパイル可能です

int matrix[3][ ]={ { 1,  2,  3,  4 },
                   { 5,  6,  7,  8 },
                   { 9, 10, 11, 12 } };

int matrix[ ][ ]={ { 1,  2,  3,  4 },
                   { 5,  6,  7,  8 },
                   { 9, 10, 11, 12 } };

しかし、上の2つはコンパイル時にエラーが出ます。要素の中で列数が入力さ
れていないといけないようです。

これが三次元配列になると、

int matrix[3][4][5]=...(省略)

のように宣言しますがこれも要素の省略は一番左端の括弧の中だけになります。

int matrix[ ][4][5]=...(省略)

それでは、文字列の配列になるとどうでしょう。
(注:昨日やったのは文字の配列=文字列)

char str[][12]={
               "あはよう",
               "こんにちは",
               "こんばんは"
              };

ざっとこんな感じです。
『文字列』が『3行』こちらのほうが行列の意味を理解しやすいと思います。

2次元配列のときは
データ型 配列名[行][列]={{ , , , },   縦…行
                          { , , , },   横…列
                          { , , , }};
です。

しかし、ここで少し疑問が出てくると思います。
上の文字列の場合、各行の列数が違うことです。
たぶん、これが列数をあらかじめ指定しなければならないわけだと個人的に考
えていますが...


◆二次元配列のまとめ

 昨日の続きで、もし配列の要素数が各行で異なっていたらどうなるか?

int matrix[3][4]={{1,2,3,4},
                  {5,6,7  },
                  {8,9    }};

となっていた場合、初期化されなかった要素は0で埋められます。
実際にそうなっているかprintf()で表示してみましょう。

#include<stdio.h>

main()
{
    int i,j;
    int matrix[3][4]={{1,2,3,4},
                      {5,6,7  },
                      {8,9    }};
    for(i=0;i<3;i++){
        for(j=0;j<4;j++)printf("%d ",matrix[i][j]);printf("\n");}
}

結果、

1 2 3 4
5 6 7 0
8 9 0 0

と表示され初期化してないところは0で埋められていることが確認できます。

それでは、文字列の場合どうなるのでしょう?

#include<stdio.h>
main()
{
    int i,j;
    char str[3][12]={
                    "ABCDEFGH",
                    "abcde",
                    "ABC"
                   };
    for(i=0;i<3;i++){
        for(j=0;j<12;j++)printf("%c",str[i][j]);printf("\n");}
}

これを実行すると

ABCDEFGH
abcde
ABC

と表示され初期化されていない要素は表示されませんでした。
つぎに10進数で表示するために%cを%dに換えます。すると、

65666768697071720000
9798991001010000000
656667000000000

と表示されちゃんと初期化していないところは数値の0が入っていることがわ
かります。とくにNULL文字も数値は0なので文字表示のとき初期化されていな
い部分は、表示されなかったのでしょう。

要素の初期化は一部の省略も可能な事から、列の要素数が未指定だと最初の行
をメモリに記憶するときに全体が収まる列数がどれだけ必要化がわからないか
らではないかと思うので列の要素数が省略できないのではないかと思っていま
す。(かなり個人的な意見なので間違っていたらごめんなさい...)

Copyright© 2000-2009 C-Production All Rights Reserved.