ポインタを使う時がわかりません
いろんなところで使えるとは、聞いたことがありますが、例えばどんなプログラムを使う時なんですか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答7件
0
ベストアンサー
-
配列や構造体を関数に渡す場合に、値で渡してしまうと、別のメモリー領域にコピーする無駄が発生します。ポインターで渡すと、ポインターだけがコピーされて無駄が無くなります。C言語ではほとんどの場合、配列や構造体はポインターで渡します。
-
関数の結果を、戻り値以外で取得したい場合。呼び出し側で配列や構造体のメモリー領域を確保しておき、関数側ではその領域に書き込むと、戻り値を返さなくても結果を呼び出し元に渡すことができます。
-
scanfのように可変長のパラメーターに対して結果を返したい場合、可変長の戻り値というのは無いので、ポインターで渡します。
-
関数をパラメーターにしたい場合、関数ポインターとして渡すことができます。
-
コンパイル時にサイズが決まっていない配列を使う場合は、malloc関数などによる動的なメモリーの確保を行います。その場合、確保した領域の参照先のポインターが返されます。
投稿2015/10/18 07:54
総合スコア9388
0
例えば,foo45さんの挙げていたソースの中で,scanf("%d", &num);っていう関数ありますよね.
これなんかはまさに,ポインタを使ってscanf関数が実装されているということです.
この関数内ではnumという変数用の領域が確保されたアドレスに,32ビット幅の整数が書き込まれます.
ポインタを使わないとそんなことはできません.
c
1#include <stdio.h> 2void assign1(int *num, int val) 3{ 4 *num = val; 5} 6void assign2(int num, int val) 7{ 8 num = val; 9} 10int main(int argc, char *argv[]) 11{ 12 int num1 = 0, num2 = 0; 13 assign1(&num1, 5); 14 assign2(num2, 3); 15 printf("num1 = %d, num2 = %d\n", num1, num2); 16 return 0; 17}
こんな例で試していただければわかりますが,
値渡しと参照渡し(C言語ではポインタを使用)では全然意味が違います.
関数の返り値を2つ以上にしたい場合にもポインタは有用です.
returnでは2つの値を返すことはできません.(構造体を返すという例外はありますが)
その場合は引数にポインタをもらっておいてそれらに書き込むやり方が主流だろうと思います.
C言語で書かれたオープンソースOSであるLinuxはポインタだらけです.
投稿2015/10/18 06:26
総合スコア751
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/10/18 13:44
0
使いどころは想像以上に多いので、この回答欄で手短に説明するのは困難ですが・・・
一言で言えば データの保存場所を意識した方が都合が良い場合 となります。
どういうことかというと、そもそも ポインタ変数 ではない、通常の変数 がどういうものかを振り返ってみれば分かります。
現在主流のノイマン型コンピュータは、どこまで進歩しても メモリ上の特定のアドレス と CPU の間でデータをやり取りしながら処理を進めるという基本原理は変わりません。
しかし、人間が常にメモリ上のアドレスを意識しながらプログラムを書くのはしんどいので、プログラミング言語の 変数 が登場しました。つまり、人間にとって分かりやすい名前を自由に付けることができて メモリ上のアドレスを意識することなく アクセスできる、というのが変数を使う意義です。
通常は変数だけで事足りるのですが、メモリ上での データの格納場所 もしくは データの並び順 を気に掛けてプログライミングした方が、
- 高速化できる
- メモリを節約できる
- 実装が簡単になる
- 特定のアドレスに意図的にアクセスする必要がある
などの場合に ポインタ型変数 を使用します。ポインタ型変数の素晴らしい点は、一般的な変数と同様、人間にとって分かりやすい自由な名前を使用しつつメモリ上の特定の位置へアクセス出来るという点です。
さて、前半の幾つかについては、下記のようなとても分かりやすい解説が既にありますので、そちらをご参照ください。
C 言語にポインタがある理由は省メモリ化・高速化・開発作業の省力化です
C言語のポインタを要点を絞って解説してみる
最後の「特定のアドレスに意図的にアクセスする必要がある」という点については、特に 組み込み系 の世界では日常的に発生する場面です。
これは、メモリマップドI/O と呼ばれる技術で、ハードウェア制御用のレジスタを通常のメモリ空間の特定アドレスに割り当てるというものです。
こうした技術は、通常のPCでも、たとえばハードウェアをコントロールするような場面(デバイスドライバの開発)で使用されており、結構身近なところで活躍しています。
以上、理解のご参考になれば幸いです。
投稿2015/10/18 07:46
総合スコア5936
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/10/18 13:44
0
プリミティブ型という類、つまり基本的な単品の値(int, float, charのような)はその値が直接的に受け渡しされることが多いです。(変数への代入や関数の引数など)
この場合、値が都度新しい領域へコピーされます。
しかし構造体や配列などを用いてプリミティブな値を複合的に扱うと情報量が大きくなるので、その塊を変数への代入や関数の引数に渡す際などに都度コピーをすると効率が悪いです。
なのでその「情報の塊」が置いてある場所を受け渡しする方法がよく取られます。この場所を指すのがポインタです。
ちなみにプリミティブ型をポインタで指すこともできます。
これはコーディングを効率よく行うために行われたりします。
プリミティブ型を値渡しすることに関して効率はどうなのかと言いますと、ポインタというアドレス番地を表す数値もプリミティブ型1個分で、参照渡しであってもこちらコピーされることになるので結局はプリミティブ型1個分のコピーは避けられないからだと思います。
投稿2015/10/18 07:24
総合スコア40
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/10/18 13:44
0
ポインタを使う目的は、
[1.] メモリの消費量を減らし、ディスクやCPUの負担を減らす。
[2.] 様々な場所で値を読めるようにする
の2点です。
例えば、1つのプログラムで3MBの同じ画像データを100回使うとします。
使う度にファイルから読み込んで違うメモリ位置に配置すれば、
メモリは300MB消費し、
300回のディスクから読み込みを行うコードを書き、
300回のファイルIO負担がディスクにかかり、
300回分のコピーに関わるCPU負荷がかかります。
これを、1回読み込んだデータをポインタ型でそれぞれから読み込んだ場合、
最初に読み込んだデータを全てのコードで参照するようになりますので、
メモリは3MB消費し、[1.]
300回の参照だけ行うコードを書き、[2.]
1回のファイルIO負担がディスクにかかり、[1.]
1回分のコピーに関わるCPU負担がかかります。[1.]
これがポインタを使う意義です。
投稿2015/10/18 05:33
総合スコア654
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/10/18 13:45
0
c
1#include <stdio.h> 2 3void show0(void); 4void show1(void); 5void show2(void); 6 7int main() { 8 void (*pM[3])(void); 9 int num; 10 11 pM[0] = show0; 12 pM[1] = show1; 13 pM[2] = show2; 14 15 printf("0:車, 1:レーシングカー, 2:飛行機"); 16 scanf("%d", &num); 17 18 if (0 <= num && num <= 2) 19 (*pM[num])(); 20 21 return 0; 22} 23 24void show0(void) { printf("車です"); }; 25void show1(void) { printf("レーシングカーです"); }; 26void show2(void) { printf("飛行機です"); };
例えばこのプログラムでは、ポインタを使わなかったらswitchやifなどで0~2番を条件分岐させる必要が出てくる。
投稿2015/10/18 04:57
総合スコア106
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/10/18 13:45
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
退会済みユーザー
2015/10/18 13:44