Tips

C言語 配列2 【基礎 第13回】

配列2

■メモリ上での配置

前回、関連のあるデータを1まとめに同じ名前で扱うために使用する配列の基本について書きました。
個々のデータを別々の変数で扱うよりもひとまとめにすることで、連続した処理を行わせるときなどに
処理が楽になります。
今回はその配列がメモリ上にどう配置されているのかをまず見てみましょう。
以下のコードを入力してみて下さい。

#include <stdio.h>
int main(void){
	int num[5] = { 1, 2, 3, 4, 5};
	int i;
	for(i = 0; i < 5 ; i++){
		printf("%Xn", &num[i]);
	}
	return(0);
}

~~~~実行結果~~~~
39F770
39F774
39F778
39F77C
39F780
~~~~~~~~~~~~

この実行結果はOSがメモリ上にデータを配置する際割り当てられるアドレスなので毎回変わります。

今回printf文で書式指定子として「%X」というものを使用しています。
これは16進数表示にするためのものです。そして後ろの引数には「&」がついています。これはscanfのところでも
軽く言いましたが、メモリ上の変数の値が格納されている場所を表すアドレスを意味しています。
イメージとしては以下のように配置されている感じです。

c13-1

今回はint型の配列なので2個目の変数が格納されている部分のアドレスは先頭のアドレスからintのサイズ(今回の環境では4バイト)
後ろからになっています。このように配列はメモリ上にひと続きの領域が確保される形となります。
その前後の領域は他の変数などの値が格納されている可能性があります。そのため添え字に要素数を超える値を
格納したり負の数を指定するとコンパイルエラーにはなりませんが、何が入っているか不明な領域を参照して
しまう形となります。
前回も書きましたが添え字には気を付けなければならないということになります。

■配列のコピー

配列を扱うときに気を付けなければならないこととして、要素外へのアクセスはどんな結果になるか
わからないというのは述べましたが、それ以外にもコピーする際に気を付ける必要があります。
配列をコピーするときには以下のようなコードは使用できません。
コンパイル時にエラーが発生します。6行目の書き方ができません。

#include <stdio.h>
int  main(void){
	int i;
	int num[5] = { 1, 2, 3, 4, 5};
	int num2[5];
	num2 = num;
	for( i = 0; i < 5; i++){
		printf(“num2の要素番号%dは%dn", i, num2[i]);
	}
	return(0);
}

配列ではコピーの時に丸ごと代入するということができません。
そのため配列の内容をコピーしたい場合、次のように繰り返し文を使用する必要があります。

#include <stdio.h>
int main(void){
	int i;
	int num[5] = { 1, 2, 3, 4, 5};
	int num2[5];
	for( i = 0; i < 5; i++){
		num2[i] = num[i];
	}
	for( i = 0; i < 5; i++){
		printf("num2の要素番号%dは%dn", i, num2[i]);
	}
	return(0);
}

このように手間かもしれませんが、配列の中身をコピーするにはforなどの繰り返し処理を使用するか
memcpyという関数を使用する必要があります。

■配列の長さ

配列のコピーや配列の要素にアクセスする際に配列の長さ(要素数)が必要になることがあります。
こういったときにはC言語 演算子 【基礎 第8回】に出てきたsizeof演算子を使用します。
sizeof演算子を使用することで配列のサイズを求めることができます。ただしそれは全サイズなので要素数ではありません。
例えば要素数10のint型(4バイトとします)配列numの場合、「sizeof(num)」とすることで
40という値が出てきます。
このままでは要素数ではないのでデータ型のサイズをsizeof演算子で求め、出てきた値で配列サイズを割ります。そうすることで要素数がでてきます。

上のコードを変えてみましょう。

#include <stdio.h>
int main(void){
	int i;
	int num[5] = { 1, 2, 3, 4, 5};
	int num2[5];
	for( i = 0; i < sizeof(num) / sizeof(int); i++){
		num2[i] = num[i];
	}
	for( i = 0; i < sizeof(num2) / sizeof(int); i++){
		printf("num2の要素番号%dは%dn", i, num2[i]);
	}
	return(0);
}

このようにして配列の要素数を出すことができます。

実践力が身につくC言語講座 連載リンク

競技プログラミングをイメージしたライブラリ活用講座
競技プログラミング風-標準Cライブラリ入門 連載

アルゴリズムをマスターして技術力アップ!
実践アルゴリズム講座 連載

パズルゲームの解析をテーマにしたC++講座
ゲーム解析プログラミング 連載

Recent News

Recent Tips

Tag Search