私は、ポインタのメリット・デメリットを以下のように考えています。
◆メリット
メモリを多く確保しなければならないオブジェクトについて、コピー処理を行うことなく省メモリでインタフェースできる。
◆デメリット
・関数内でしか使用しない非ポインタのローカル変数に比べ、
アクセス可能な場所が多くなってしまい、色んな箇所から値が変更されうる。(影響範囲の限定がしずらい)
・可読性が低くなる。(若いエンジニアはCの経験者は少なくっていくと思われるため、保守コストが若干割高になる)
そのため、よっぽどメモリを多く使うようなオブジェクトでなければ、
(もしくは速度を重視する必要があるプログラムでなければ)
値渡しにしても良いのではと考えています。
しかし、度々目にするソースは、何でもかんでもポインタで処理しているものも多々見受けられます。
特に、int型のようなメモリを大量に使用しないものでも、ポインタで変数宣言しているケースもよく見ます。
なぜなのでしょうか?
(熟練のC言語プログラマが、昔ながらの記述を踏襲しているというのはあるのかなと考えていますが)
No.4
- 回答日時:
C言語の関数では、そのアウトプットを返却値でしか受け取れないのです。
なので、関数が複数のデータを出力させたい場合は、
(1)書き込み先アドレスを渡してそこに書き込んでもらうか、
(2)構造体にまとめて一つの変数としてリターンしてもらうか、
(3)おぞましくもグローバル変数に書き込んでもらうか、
そんなところになるかと思います。
そして関数の返却値は、たいていは処理が正常に終了したかどうか等のコードで
使用されてしまいますから、それ以外のデータを受け取る場合は、
(1)の手段、つまり関数の引数にポインタを使用することになります。
>C言語の関数では、そのアウトプットを返却値でしか受け取れないのです。
なんと!そうだったのですか!
他の回答者様の内容なども、しっくりきました。
だからポインタ渡し、参照渡しをよく見かけていたのですね。。
No.3
- 回答日時:
>特に、int型のようなメモリを大量に使用しないものでも、ポインタで変数宣言しているケースもよく見ます。
あなたの「よく見かける」というのは
関数内の変数でint型1個分のために
int *a = malloc(sizeof(int));
のようなポインタを使ってるのをよく見かけるということでしょうか?
私はintオブジェクトを簡易的にあらわすのに使うときもありますが、そういうケース以外でただ1個分のint型を使うのにわざわざポインタで扱うのを私は見たことありませんけど。
もしかして変数といってるのは仮引数のことで
void foo(int *a);
のようなものを、よく見かけるだったりしませんか?
この回答への補足
int *a = malloc(sizeof(int));
のケースも見ます。
ただこれに関しても、理由はあまりわかっていません。
intは、32767 ~ -32768 と決まっているのだから、サイズの確保のため、なぜわざわざmallocで書くのでしょうか?
宜しくお願いいたします。
No.2
- 回答日時:
たとえばこんなの↓、ポインタなくては書けません。
#include <stdio.h>
/*
*nに1を加える関数
*/
void increment(int* n) { ++(*n); }
int main() {
int n = 123;
increment(&n);
printf("%d\n", n);
return 0;
}
この回答への補足
※まだ勉強中の身なので、自信はないのですが、
void increment(int &n) { n = n + 1; }
int main() {
int n = 123;
increment(n);
printf("%d\n", n);
return 0;
}
でも可能ですか?
また、ポインタで書く場合と、参照で書く場合で、どのようなメリット・デメリットの差があるのでしょうか?
とりあえず、私が参画するようなプロジェクトは、
期間内・予算内で、企業の利益につながるシステムを作ることが目的であるため、
インクリメント等は、別に1行でなくてもよかったり、
多少、使用メモリが多くても、まったく問題ないため、
このケースに関してはですが、ポインタにこだわる必要はないさそうです。
しかし、ポインタを使うと、色々簡潔にかけたりするのでしょうね。
ありがとうございます。
No.1
- 回答日時:
ここで述べられているのは、関数の引数としてポインタを使う場合のことですね?
> ・関数内でしか使用しない非ポインタのローカル変数に比べ、
> アクセス可能な場所が多くなってしまい、色んな箇所から値が変更されうる。(影響範囲の限定がしずらい)
> ・可読性が低くなる。(若いエンジニアはCの経験者は少なくっていくと思われるため、保守コストが若干割高になる)
関数にポインタを渡しても、アクセス可能な場所は限られます。
funcA(&x) としたら、xにアクセスできるのは funcAと、funcAの中で呼ばれる関数だけです。無関係な関数まで気にする必要はありません。
funcAの中でfuncBに渡され...となるとわからなくなる、というのなら、まずは、関数の仕様だけに注目することです。
funcBの実装はとりあえず置いといて、期待通りに動作したら、ポインタとその実体がどう変化するか、それだけを考えて
funcAを作成.確認します。
*x += 3 ;
とあったら、 実際にどんなアセンブリコードになっているか、なんて考えないですよね?それと同様に
funcB(x)
とあったら、funcBの中身を考えずに、funcBの動作だけを考えます。
また、Cとポインタだけで発生することではなく、他の言語でも同じことが起きます。
例えば、Javaのオブジェクトは、メソッドの引数で渡すときには、「参照値」というポインタのような値が使われます。
JavaでmethodA(Object objA) の中で methodB(objA)を実行している
のと
Cで funcA(int * p) の中で funcB(p) を実行している
のとで、参照値/ポインタの扱いはまったく一緒です。
他にも
・Cには、いわゆる「参照渡し」がありません。ポインタ(の値)渡しで代用します。
・Cでは、配列とポインタは密接に関係しています。
例えば、void func(int * a) ; と void func(int a[]) ; は等価です。
この回答への補足
回答ありがとうございます。
>関数にポインタを渡しても、アクセス可能な場所は限られます。
>funcA(&x) としたら、xにアクセスできるのは funcAと、funcAの中で呼ばれる関数だけです。
funcAの中で呼ばれる関数に、そのまま&xを渡したら、内部の関数の、さらのその内部の関数内でポインタ渡しになっていたとき、アクセスは不可能という解釈で良いでしょうか?
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# 関数ポインタの高速化のメリット 7 2023/05/05 20:15
- その他(Microsoft Office) オフィス365のエクセル 3 2023/06/29 13:10
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- その他(自然科学) 論文のまとめに関して(小論文)添削お願いします。 6 2023/07/16 14:24
- C言語・C++・C# C言語 配列とポインタについて 2 2022/06/02 11:53
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、写真のプログラムをどう直せ 2 2022/07/09 21:13
- Visual Basic(VBA) VBA リボンののリカバリーでオーバーフローエラーになります 2 2023/07/04 19:07
- iPhone(アイフォーン) iCloudのデータをiPhoneメモリに移動したい 1 2022/10/24 22:11
- C言語・C++・C# C言語 ポインタ 配列 2 2022/06/02 17:29
- その他(悩み相談・人生相談) 小学校教員として働く都道府県についての相談。男です。 地元での就職は考えていません。働く場所の候補と 1 2022/09/16 06:01
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
セグメントエラー
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
Run-Time Check Failure #3とい...
-
C言語のポインタに直接アドレス...
-
LPSTR型の初期化について
-
アプリを32bitから64bit移行
-
Cで作成したDLL関数をVBから呼...
-
コンストラクタでnewを失敗した...
-
参照型で受け取った引数をポイ...
-
DLL<->VB間での受け渡し(文字...
-
fopne で失敗する原因
-
->記号って?
-
ReadFileの読み込みエラーについて
-
NASMかNASKの文法の本
-
ハンドル、アドレス、ポインタ...
-
【C言語】戻り値が構造体の関数
-
sizeofについて
-
関数ポインタの高速化のメリット
-
画像の処理について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
セグメントエラー
-
C言語のポインタに直接アドレス...
-
init関数の意味
-
戻り値で構造体を返すことは可...
-
fopne で失敗する原因
-
C言語の関数と配列に関する質問
-
Run-Time Check Failure #3とい...
-
LPSTR型の初期化について
-
ExcelVBAでのkernel32(64bit)
-
main(int argc,char **argv[])...
-
アプリを32bitから64bit移行
-
ハンドルはポインタか
-
連結リスト 要素の入れ替え
-
C言語でのconstを返す関数
-
Cで作成したDLL関数をVBから呼...
-
NULLとブランクの違い
-
エラーの意味
-
ハンドル、アドレス、ポインタ...
-
DLL<->VB間での受け渡し(文字...
-
【C言語】戻り値が構造体の関数
おすすめ情報