【C言語/C++】配列のまとめ

公開日: : 最終更新日:2014/08/14 C/C++

スポンサーリンク

C/C++を使っていると必ず配列を使う場面が出てくると思いますが、その配列についてまとめました。C言語だけをやっている人はあまり配列を動的に作ることができるというのを知らないのではないかと思いこのような記事を書きました。(私は知らなかった)

C/C++の配列には静的なものと動的に確保するものの2通りがあり、それに加え、C++ではvectorなどの便利なコンテナも標準で備わっています

静的な配列

静的な配列を作成するときは[]の添え字を使い、呼び出すときは添え字に要素数字を指定します。

初期化の方法は要素数を直接指定するかもしくは{}内でカンマ区切りで値を指定すれば要素数は省略可能です。

int test[3]={0}; //全ての要素が0で初期化される


int test[3]; //要素への値を後から代入する
test[0]=0;
test[1]=0;
test[2]=0;


int test[3]={0,0,0}; //3つの要素を持った配列になる


int test[]={0,0,0}; //一つ上の場合は要素数を省略できる

int test[] = {1,2,3};
for(int i=0;i<3;i++)
{
	printf("%d\n",test[i]);
}
1
2
3

また静的な配列に限るようですがsizeof演算子を使うことで要素数を取得することができます。

int test[3];
int size = sizeof(test);
printf("%d\n",size);
3

次から説明する動的な配列ではこのsizeof演算子は使えません。

動的な配列

静的な配列では初めに要素数を指定する必要がありましたが、要素数がわからないような場合は大量に要素数を指定する手法がとられたりしました。

例えば

int size = 0;
~~	//sizeに値が入る
int test[ size ]={0};	//エラー

こういったことができないわけです。
なのでしかたなくこういったことをする方がいるかもしれません。

#define MAX 10000
~~
int test[ MAX ]={0};

これでいいかもしれませんが、こういった配列が大量に必要になる場合メモリが足りなくなってしまうという問題が起きてしまう可能性があります。

そこで動的に配列作成をすることでこの問題を解決します。

C++の場合

C++ではnew演算子delete演算子というのを使います。

上の例をとると

int size = 0;
~~	//sizeに値が入る
int *test = new int[ size ];
~~
test[0] = 3;	//いつも通りの配列の使い方
~~
delete[] test;

まず

int test[]

int *test

になっていますが、ここのポインタにnewを使うと指定サイズ分の領域を確保することができます。

実は静的な配列はスタック領域に格納されますが、この動的確保ではヒープ領域(メモリ)というところに格納されます。

newの使い方は

(型) *(変数名) = new (型)[ (要素数) ];

この例ではintですが(型)部分をfloatやdoubleにすればその型の領域が確保されます。

その後は通常の配列と同じように扱ってください。ただし、sizeofで要素数を得るといったことはできません。

そして大事なことがもう一つありまして最後のdeleteです。
静的な配列はスコープが切れた段階で勝手にメモリが解放されますが、newで作成したメモリは自動では消えませんので、使い終わったら自分でメモリを解放する必要があります。(メモリの解放=破棄と思ってください。)

つまり

for(int i=0;i<10000;i++)
{
	int test[10000];
}

これは毎回領域が自動で解放されるので別に問題ないですが、

for(int i=0;i<10000;i++)
{
	int *test = new int[10000];
}

こんなことするとどんどんメモリを使いつぶすので危険です。絶対やらないでください。そこでこのような動的な配列を解放するためにdeleteを使います。

int *test = new int[100];
~~
delete[] test;	//配列を使い終わったので解放する

deleteでは配列を解放するときは添え字[]を書いてください。
さっきの例はこのようにすれば問題ありません。

for(int i=0;i<10000;i++)
{
	int *test = new int[10000];
	delete[] test;
}
C++編(言語解説) 第12章 new/delete(http://www.geocities.jp/ky_webid/cpp/language/012.html)

ヒープメモリ(http://www.curiocube.com/mikata/hello/ch11_heap.php)

C言語の場合

C言語の場合はmalloc関数free関数を用います

new→malloc
delete→free

と考えてください。

mallocの使い方は

(型) *(変数名) = (型*)malloc((領域確保サイズ));

です。

領域確保サイズは『その型の大きさ×要素数』のことで、例えばint型で100個の要素が必要であれば

sizeof(int)*100

を引数に代入してください。ちなみにsizeof(int)は4なので始めから4としてしまってもよいです。

そして最後にfreeで解放するのですが、ここで気を付けてほしいのはnewで確保したものはdeleteで解放、mallocで確保したものはfreeで解放してください。逆にすると失敗してしまいます。

先ほどの例をmallocで書き換えると下のようになります。

for(int i=0;i<10000;i++)
{
	int *test = (int*)malloc(sizeof(int)*10000);
	free(test);
}

vectorなどのコンテナ

ここまでで静的な配列、動的な配列の扱い方について言及しましたがいずれの方法でも配列数は任意のタイミングで固定していました。

使い方によっては配列を使っている途中で要素数をちょっと増やしたいなんてことが起きると思うのですが実は、C++ではそういったことを可能にしてくれるコンテナという便利なものが用意されています。

コンテナにはvectorlistなどいくつか種類がありそれぞれ特徴があるのですがとりあえず簡単なvectorを取り上げます。
vectorは可変長の配列で値の取り出し方などは従来の配列と大差はないです。

それでは使い方について簡単に説明します。まずvectorをインクルードしてください。

#include<vector>

そしてvectorを宣言します。今回はint型とします。

std::vector<int> test;

『std::』はstd名前空間へのスコープですがよくわからにという方はおまじないと思ってください。

次に要素を追加するときはpush_backというメソッドを使います。これにより指定の値が末尾の要素に追加されます。

test.push_back(2); //2という値が追加された

また、あらかじめ要素数を確保したい場合はresizeメソッドを使います。

test.resize(100);

実は要素数も取得することができます

int size = (int)test.size();

格納した値を参照したいときは通常の配列と同じように添え字を使ってください。

printf(“%d\n”,test[0]);

例えばこんな風に使います

std::vector<int> test;
for(int i=0;i<3;i++)
{
	test.push_back(i);
}
int size = (int)test.size();
for(int i=0;i<size;i++)
{
	printf("%d\n",test[i]);
}
0
1
2

vectorは自動でメモリを解放してくれますがクラスのメンバなどでvectorを使っていて任意のタイミングでいったんメモリを解放したいという場合はswap技法というのを使うとできます。

clearというメソッドもありますが、これは要素数を0にリセットするだけでメモリは解放されていません。

スポンサーリンク
Amazon
  • このエントリーをはてなブックマークに追加

関連記事

CSS85_keywosousasruop20131019500-thumb-500xauto-4249

【C言語/C++】配列をシャッフルしてランダムに入れ替える

C言語・C++で配列をシャッフルする方法 Fisher–Yatesシャッフルアルゴルズムにより配列

記事を読む

PAK15_notepenhikkiyougu20140312500-thumb-500xauto-4327

【C言語/C++】fgetsを使ってファイルを読み込む

fgetsで単純にファイルを読み取る C言語、C++でfgetsを使ってファイルを読み込む方法です

記事を読む

0533f0e24573da8dbd68f5c6e7d452d7_s

【C++】ファイルの読み込みまとめ

C++におけるファイル読み込みのまとめ ファイルの開き方 値の取得方法 >>演算子

記事を読む

フォルダ画像

【C言語/C++】フォルダ作成を行う

C言語、C++でフォルダを作成するには『direct.h』にある『_mkdir』関数を使うことで実現

記事を読む

Window Command Line

【C言語/C++】関数の宣言・定義まとめ

1 関数プロトタイプ宣言・定義 1-1 プロトタイプ宣言 1-2 定義 2 ファイ

記事を読む

PAK86_codeing20140517500-thumb-500xauto-4601

【C言語/C++】余りを求める剰余演算子(%)を使う

基本的なことかもしれませんが、C言語やC++などであまりを出すには剰余演算子である『%』を使います。

記事を読む

question

【C言語/C++】はてなの演算子の三項演算子について

C言語などのサンプルにたまに出てくるはてな(?)の演算子は 『?』と『:』の2つで1つの演算子であ

記事を読む

darts-102919_640

【C++】多次元ベクトルクラスを作る

3次元ベクトルクラスや2次元ベクトルクラスを作るときは内部のデータとして静的な配列を使えば問題ありま

記事を読む

childish_File

【C言語/C++】ファイルをCSV形式でfprintfを使って保存・書き込みする

数値計算などをC言語でプログラミングするとき、その演算結果をファイルとして保存する必要性がでてくるこ

記事を読む

PAK23_husentomemo20140313500-thumb-500xauto-4376

【C言語】printfのような関数を作る

C言語でよくつかわれるprintfでは例えば int a,b,c; … printf(

記事を読む

encodingtype
【PHP】headerでContent-Typeを指定したのに効かない場合の対処法

PHPでサイトマップを作ろうと思い、XML形式のファイルを出力しようと

_rtm0919_tp_v
スマホ向け幅固定サイトの回転時の幅対応方法

幅固定サイトでのスマホ回転時Webサイトの横幅を合わせる方法のメモ。

rssimage
【PHP】特定のURLからそのAtomやRSSのフィードを抽出する方法

特定のURLからRSSやATOMのフィードを抽出する方法をメモ。 流

rssimage
フィード抽出ツール(RSS1.0、RSS2.0、atom)

任意URL サイト名 サイトURL RSS1.0

computer_server
格安プラン限定レンタルサーバー機能比較表(2016年)

はじめに  最近新しい共用サーバーをレンタルしようと思い調査およびそ

school_toshokan_hondana
kindle unlimitedが便利だったのでお勧めの使い方など感想メモ

 kindle unlimitedというサービスが8/3からAmazo

TAKEBE055122558_TP_V
寝る前にスマホを見ると斜視になる可能性とその対策

はじめに  寝る前などスマホを横になりながら見続けると斜視になる可能

→もっと見る

  • Author : ががんぼ
    プログラミングやWeb関係で気付いたことについてメモしていく予定。だいたいが備忘録ですが、自分でサンプルを作って動かしてみたりしています。
PAGE TOP ↑