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

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

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

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

Q&A

解決済

4回答

1675閲覧

C言語 配列とポインタの使い方

redhat98

総合スコア236

C

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

0グッド

0クリップ

投稿2017/05/13 04:38

普段は.NETを仕事で使っている者です。

C言語を勉強していて、配列とポインタの使い分けがわからずに困っています。
色々調べてみたのですが「配列を使うシチュエーションは、かなり限定されているのではないだろうか?」という事に気が付きました。

色々考えてみた結果、下のようになりました。

私が色々考えてみた所

  1. 基本的に配列は使わないで、全部ポインタで操作する
  2. ただし、ローカル変数 かつ 配列の要素数 を確定出来るときだけ、配列を使う
  3. ただし、グローバル変数 かつ 配列の要素数 を確定出来るとき(明示的に指定したい場合)は配列を使う

その他
4. 入門書では文字は基本的に配列に代入してますが、実際プログラム組むと配列を使うって事はありえないですよね?
だって、プログラムで扱う文字列はユーザが入力したデータだったり、ファイルを読み込んだりって感じですから
精々、配列で扱うのはリテラルとか定数じゃないのかなって思います。

というイメージです。
このイメージで正しいでしょうか?

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

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

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

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

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

guest

回答4

0

一言で言えば、誤りだと思います。
入力の長さが分からない、これは間違っていません。しかし、だからと言って静的配列で扱えないとは限りません。入力を一度に読み込む必要がなく、細かく分けることができれば、固定長の静的配列であっても処理することは可能です。
C言語はオーバーヘッドを可能な限り少なくする方針で設計されているので、メモリを確保するための命令すらありません。
そもそも、基本的にメモリだけでよいのであれば、配列という機能は用意されないのではないでしょうか?
ちなみに私は、バリバリ固定配列を使うC++プログラマーです。

投稿2017/05/13 04:57

majiponi

総合スコア1720

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

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

mugicya

2017/05/13 05:47

固定のほうが、assert とか設置しやすいので僕も好きです。
redhat98

2017/05/13 08:45

回答、ありがとうございます。 > 入力を一度に読み込む必要がなく、細かく分けることができれば、固定長の静的配列であっても処理することは可能です これって、ファイルから読み込む場合のバッファの事を指し示していますか バッファに溜め込んだだデータは、最終的にmallocで確保した領域へ入れるってイメージですか?
guest

0

仰るとおり、コンパイル時までに要素数が確定しない場合であれば固定長配列を使うことはできません。ただし、要件を整理すると結局コンパイル時に要素が確定することは多々あります。また、再コンパイルの手間や時間が十分小さいならば配列長を定数としておくという方法もあります。

少なくともハードウェアによる制約があるわけですし、ユーザ側と仕様を事前に相談することも必要ですのでこの際に長さを決めておくといいと思います。

投稿2017/05/13 09:23

HogeAnimalLover

総合スコア4830

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

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

redhat98

2017/05/13 12:35

> 再コンパイルの手間や時間が十分小さいならば配列長を定数としておくという方法もあります。 勉強になりました。 ありがとうございます。
guest

0

ベストアンサー

こんにちは。

びっくりする程正確な見解と思います。
「配列の要素数 を確定出来るとき」が最大要素数として確定できる場合も含むのであれば、majiponiさんが言われている状況も含みますし。

精々、配列で扱うのはリテラルとか定数じゃないのかなって思います。

多くのケースではその通りと思います。
レアですが、下記のようなケースでも固定長を使います。

超小型CPU等でメモリをギリギリまで節約するケースでは、ヒープを使えないし、スタックも余裕がないので、グローバル変数として固定長で確保します。

例えば、ISO 3166-1で規定されるような国名コードは固定長ですし、高々数バイトなので固定長配列を使うケースは多いでしょう。


しかし、malloc/freeが使えるような環境でC言語を使うのは正直ナンセンスな時代と思います。
素直にメモリ管理に長けたC++を使った方がかなり楽できます。メモリ・リークを避けるために必要な注意力の桁が違います。

投稿2017/05/13 09:05

Chironian

総合スコア23272

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

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

redhat98

2017/05/13 12:49

> びっくりする程正確な見解と思います。 ありがとうございます。 > しかし、malloc/freeが使えるような環境でC言語を使うのは正直ナンセンスな時代と思います。 なるほど、そいう考え方もあるのですね JNIを使いたいと思い、C言語を勉強してみることにしたんです
Chironian

2017/05/13 13:32

なるほど。確かにJNIはC言語I/Fを使うような話を聞いた記憶が有ります。 しかし、↓を見る限りJNIはC++でも使えそうですよ。 https://ja.wikipedia.org/wiki/Java_Native_Interface 実際の内容は知らないのですが、JNIEXPORTがextern "C"を含んでいるのではないかと思います。 つまり、I/FはC言語だけど内部的にはC++を使えるように工夫されているのだろうと思います。 ところで、C++ならWikiのケースではコンストラクタでGetStringUTFCharsを呼び、デストラクタでReleaseStringUTFCharsを呼ぶようなヘルパークラスを作り、そのインスタンスをローカル変数として確保することで事実上メモリ・リークしないようにできます。(コンストラクトされたローカル変数は関数終了時に開放されますが、その時デストラクタが事実上必ず呼ばれます。) C++は確かに学習コストが高いのは事実です。でも、C言語の配列についてあんなに正確に言い当てることができ、かつ、Javaに慣れているのであれば、後はデストラクタを悟れば使えると思いますよ。 C++の全てを使おうとしないことです。理解できた部分を使うだけでも十分有用ですから。 C言語で文字列処理は正直地獄です。C++のstd::stringを使うとたいへん幸せになれます。
guest

0

.Netを使って作っているようなアプリケーションをCで実装するという話ならイメージ通りだと思います。

ただしCの使われるところは組み込みよりなのでlibcすらない(mallocが使えない)環境もあるので配列がないと困ります。
仕様上最大値が決まるなら固定長のほうが早いですし、いちいち確保と開放しなくていいので楽ですよね。
またハードウェアに近づくにつれて一度に処理できる単位(パケットサイズ, フレームサイズ, ブロックサイズ, キャッシュサイズ, etc...)が決まってくるため、そっちに合わせて逐次処理をするということもあります。

投稿2017/05/13 06:15

nullbot

総合スコア910

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

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

redhat98

2017/05/13 08:39

なるほど、勉強になりました。 ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問