質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

3回答

6114閲覧

c言語の配列は、ヒープに確保できるんですか?

redhat98

総合スコア236

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2017/04/19 03:36

こんにちは

普段は.NETを書いている職業プログラマーなのですが、C言語を勉強している者です。

配列とポインタは異なる物であるという事はわかったのですが、
配列とポインタの使い分けがわかりません。

そこで、私は配列とポインタをスコープの観点で考えてみることにしました。

配列がヒープに確保できないということを前提に考えると、

配列 ----> スタックにしか確保できない。
だから、基本的にはローカル変数(自動変数)にしか使えない。
わざわざfree()しなくていいので、自動変数でスコープ的にOKな時は積極的に使う

ポインタ ---> ヒープに確保されるので、変数の寿命が長い時に使う
free()が必要になるので、ローカル変数では基本的に使わない

技術的に問題になったのが「配列はヒープに確保できるのか?」ということです。
配列はヒープに確保できますか?

ps ------------------------------------
googleで検索するとmallocで確保したメモリ領域の事を、配列って書いている記事が沢山ありました。
mallocで確保されているから厳密にはポインタだと思うのですが、面倒だから配列って呼んでいるだけですよね?

それとも、C言語では単に連続したアドレスであれば、配列って呼んでいるだけなのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

こんにちは。

C言語のポインタと配列はたいへんそっくりですので、ヒープに連続したメモリを確保すれば、それを配列的にアクセスすることが可能です。

C

1#define SIZE 100 2int* IntArray=(int*)malloc(SIZE*sizeof(int)); 3for (int i=0; i < SIZE; ++i) 4 IntArray[i]=i+1;

それとも、C言語では単に連続したアドレスであれば、配列って呼んでいるだけなのでしょうか?

その通りと言ってよいと思います。(厳密にはポイント先の型も含めます。)
C言語は、配列とポインタを同じ構文で取り扱えるようにしたことで、文字列をコア言語でサポートせず、標準ライブラリでサポートするようにしました。当時はすごいアイデアだったのですが、型に厳密なC++では黒歴史になっていると個人的には感じてます。

ところで、もし、C#を既にマスターされているのでしたら、C++の方が楽かも知れませんよ。
C#はC言語よりC++に似ています。

投稿2017/04/19 03:59

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

プログラミング用語で単に「配列」と言った場合、同じタイプのデータを連続して複数並べてインデックスでアクセスできるように管理されたデータ構造のことを指します。

C言語では、変数としてそのようなデータ構造を定義するのにint x[10];のように書きますが、これは、言語仕様としての狭い意味での配列であり、一般的な用語と区別する際は「配列型」あるいは「ネイティブ配列」などと呼びます。

配列はヒープに確保できますか?

できます。つまり、「配列」のデータ構造をヒープ上に持たせれば、それを配列として利用することができます。C言語はポインターに対してインデックス指定で要素にアクセスできるので「配列」の定義と合致します。

mallocで確保されているから厳密にはポインタだと思うのですが、面倒だから配列って呼んでいるだけですよね?
それとも、C言語では単に連続したアドレスであれば、配列って呼んでいるだけなのでしょうか?

面倒だからという理由ではなく、「配列」として利用するために確保した領域なので配列と呼んでいるのです。

投稿2017/04/19 05:07

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

C言語の仕様書(JIS X 3010:2003)では、配列型の定義として、
「要素型(element type)と呼ぶ特定のメンバオブジェクト型をもつ空でないオ
ブジェクトの集合を連続して割り付けたものを表す」
となります。
そして JIS X 0015 で配列とは「配列型を実現値とする集成式であって,各要素又は要素の適切な集まりが他とは無関係に,かつ,個別に参照されるもの。」として定義しています。

malloc で確保したメモリ領域はたいていの場合何らかの要素型(BYTE だって要素型です)の集合を連続して割りつけたもの、すなわち配列型になりますから、確保した領域のことを配列と呼んで間違いではありません。

一方で malloc が返すのは、「その確保した領域の開始位置を指し示すポインタ」であって、配列そのものを返しているわけではありません。

「malloc で配列を確保して、その領域のポインタを得る」のですから、どちらも間違いではないのです。
※malloc でポインタを確保する、だとおかしいですが

ちなみに配列だって普通にスタックに積まれることはあります。コンパイラの挙動なので実装依存ですが。

投稿2017/04/19 04:08

tacsheaven

総合スコア13703

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

redhat98

2017/04/19 09:28

回答有り難うございます。 > 確保した領域のことを配列と呼んで間違いではありません。 C言語は、連続した領域を配列と呼んでいるという事は理解できました。 そこで、さらに質問なのですが int array[10]; と宣言した時に、C言語ならではの落とし穴/文法的制約って無いのでしょうか? C#/Javaだと、グローバルな領域、引数、戻り値などあらゆる所に配列を書くことが出来ます。 私はC言語では引数にvoid hellow(int test[])と、書くことができないくらしか制約を知りません。 C言語ならではの、落とし穴ってあるのでしょうか?
tacsheaven

2017/04/24 07:30

C言語では仕様上 ・配列型を返すこと ・引数として配列型を渡すこと(暗黙の変換で先頭を示すポインタが渡る) ができません。 ということは、関数に対して「配列の要素数を渡すためには、別の引数で渡す必要がある」ということになります。 上で書かれた array を自作の関数に渡す場合等、array の要素数も渡すようにしないと、どこまで array を見ればよいのか分からなくなるのでメモリ破壊しかねませんね。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問