• ベストアンサー

int型のポインタ

int型のようなメモリを大量に使用しないものでも、ポインタで変数宣言しているのをよく見かけますが、 なぜでしょうか? 私はCに慣れていないため、int型くらいのサイズだったら、なるべくならポインタを使わないで書いてもらった方が可読性が良いので、ポインタにするメリットがあまり感じられません。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.3

redimと書いてあるのでVisualBasicに慣れているのだと思いますが、 C言語では配列の大きさを後から変更することはできません。 ですので、実行時まで必要なサイズがわからないデータについては、 最初はポインタだけを用意して、そこに後からmallocなりcallocなりreallocなりで 確保した領域のアドレスを入れておくしかないのです。

TeferiMage
質問者

お礼

ありがとうございます。 都度、メモリを確保となるのですねー

その他の回答 (4)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.5

> ◆非ポインタ版 > l_arr = a[0]; > ... > show_msg(a[index]); 済みませんが、元と等価なコードでないと、比較する意味が無いのですが。 全然違うコードで「intの方がいい」と言われても、「そのコードにはintがいいですね。で?元のコードはどうなんですか?」ってことになります。 px = x ; /* a[x] の添字をpxとして記憶 */ ... a[px] +=7 ; /* 上で記憶した a[px]へアクセス */ と、ポインタ使わずに書く方法もあるかもしれません。 ただ、この場合は、整数pxがポインタの代りをしているからできることです。 また、元が ポインタ→実体 と1ステップだったものが 配列の先頭→ 添字の分の計算 →実体 とステップが増えます。省メモリのつもりが、コードが増える可能性があります。 (また、実装や最適化によって違ってきますが) 単純すぎてピンと来ないなら、こんな例ではどうでしょうか。 int x,y,z,mode ; int * p ; ... /* 状態によって、次のいずれかになる */ if( mode==3 ) { mode=1; p = & x ; } else if ( mode==4 ) { mode=2; p = & y ; } else { mode=2; p = & z ; } /* x,y,z,mode はここで使用する */ image_out(x,y,z,mode); /* 上で選ばれた変数を +7する */ *p += 7 ; これ、int *pを使わずに、同じ動作をするコードにできますか? そのコードは、これより「わかりやすい」ですか? > redim l_arr[x]; Cに無い命令を使われても、エラーになるだけですけど。

TeferiMage
質問者

お礼

まちがって補足のところにお礼を書いてしまいました 改めましてありがとうございます

TeferiMage
質問者

補足

ありがとうございます

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.4

// ◆論点:int型くらいのサイズだったら、 // わかりやすさ > メモリの必要量の節約 ポインタ使うのは、メモリ必要量の節約のためではないと思いますが、どこからそのような話が出てきたんでしょう?

TeferiMage
質問者

お礼

もっと調べてみます ありがとうございます

回答No.2

> 配列サイズが動的な場合でも、以下のようにした方が私は把握しやすいです。 > > l_arr = a[0]; > ... > x = SQLで取得した結果件数など > redim l_arr[x]; redim ってなんですか? Cにそんなのないんですけど。

TeferiMage
質問者

お礼

ありがとうございます。 Vbで配列のサイズを変えるときに使います。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

具体例があれば、説明しやすいのですが。 ・特定の変数、配列の要素等を別の名前で記憶させる p = &( a[x] ) ; /* a[x] をpとして記憶 */ ... *p +=7 ; /* 上で記憶した a[x]へアクセス */ ・malloc等で動的に確保した領域を記憶される int *p = malloc( length * sizeof(int) ) ; ・関数の引数としてポインタを使用する場合、他言語の「参照渡し」にあたる操作を行う 以下のプログラムの結果がどうなるか、理解していますか? #include <stdio.h> void swapA(int a, int b ) { int t =a ; a= b; b=t ; } void swapB(int * a, int * b ) { int t =*a ; *a= *b; *b=t ; } int main(){ int a=3; int b=5; printf("a:%d, b:%d\n", a,b) ; swapA(a,b); /* またはswapB */ printf("a:%d, b:%d\n", a,b) ; }

TeferiMage
質問者

お礼

ありがとうございます

TeferiMage
質問者

補足

//***************************************** // ◆論点:int型くらいのサイズだったら、 // わかりやすさ > メモリの必要量の節約 //***************************************** 上述の例では、 メモリの使用量が大きく変わらないと考えます。 ポインタを使わずに書いたとき、 1個のint のメモリ使用量に対して、約x倍になる認識ですが、 そもそも、intのメモリ量はたかがしれているため、 ポインタで変数宣言すべきではないと考えます。 大きなオブジェクトに対しては、ポインタを使うべきと考えますが、 intのようなメモリ使用量が小さいものは、 わかりやすさ > メモリの必要量の節約 と考えます。 //************************************ // メモリを大量に使用しないため、 // ポインタで変数宣言したくないケース //************************************ ◆ポインタ版 p = &( a[x] ) ; /* a[x] をpとして記憶 */ ... *p +=7 ; /* 上で記憶した a[x]へアクセス */ ◆非ポインタ版 l_arr = a[0]; ... show_msg(a[index]); わかりやすさ > メモリの必要量の節約 のため、後者にすべきと考えます。 //********************* // ◆補足 //********************* 配列サイズが動的な場合でも、以下のようにした方が私は把握しやすいです。 l_arr = a[0]; ... x = SQLで取得した結果件数など redim l_arr[x]; i = 0; show_msg(a[i]); i = i + 7; show_msg(a[i]); の方が断然わかりやすいです。 //******************************* // 大きなサイズのオブジェクト //******************************* ポインタを使うべきです。 メモリを大量に必要とさせたくないためです。

関連するQ&A

  • 【なぜポインタを使うのか】

    私は、ポインタのメリット・デメリットを以下のように考えています。 ◆メリット メモリを多く確保しなければならないオブジェクトについて、コピー処理を行うことなく省メモリでインタフェースできる。 ◆デメリット ・関数内でしか使用しない非ポインタのローカル変数に比べ、  アクセス可能な場所が多くなってしまい、色んな箇所から値が変更されうる。(影響範囲の限定がしずらい) ・可読性が低くなる。(若いエンジニアはCの経験者は少なくっていくと思われるため、保守コストが若干割高になる) そのため、よっぽどメモリを多く使うようなオブジェクトでなければ、 (もしくは速度を重視する必要があるプログラムでなければ) 値渡しにしても良いのではと考えています。 しかし、度々目にするソースは、何でもかんでもポインタで処理しているものも多々見受けられます。 特に、int型のようなメモリを大量に使用しないものでも、ポインタで変数宣言しているケースもよく見ます。 なぜなのでしょうか? (熟練のC言語プログラマが、昔ながらの記述を踏襲しているというのはあるのかなと考えていますが)

  • ポインタの宣言

    ポインタを宣言するとメモリ上に、ポインタ変数を格納するための領域が確保されます。ポインタ=アドレスというのは大丈夫なのですが、 int *b のようにどうして、ポインタに型があるのでしょうか?単に変数のアドレスを表示するだけならば型はいらないと思うのですが。 またこのとき宣言された変数は *b ではなくて b であってますよね?

  • ポインタ

    ポインタの勉強をはじめたばかりの者なのですが、たとえば int *p などでポインタを宣言する場合には、メモリ上で変数pにはアドレスを格納するだけの領域が与えられます、このとき何バイトの領域が与えられるのでしょうか?

  • ポインタのポインタが引数にある関数の使い方。

    ポインタのポインタが引数にある関数の使い方。 現在、このポインタのポインタが引数にある関数の動きがわからず困っています。 int test(int ** head) { int * pTail = (int *)*head; pTail = pTail + 1; } もし、この関数を呼び出して使用した場合どのような動きをするのでしょうか? int * comm_msg; これをグローバルポインタ変数として宣言させて、 test((void **)&comm_msg); このように呼び出したとした場合とさせていただきます。

  • ”int *a,*b”というポインタ変数宣言した値でa=&bということ

    ”int *a,*b”というポインタ変数宣言した値でa=&bということはできる? ”int *a,*b”このような変数をグローバル宣言した場合、 a=&bというようなことはできるのでしょうか? ”int *a,*b” この宣言で、 aが10番地 bが20番地に定義されたと仮定しています。

  • ポインタ変数を変数に渡す方法

    (int * 型)ポインタ変数に代入されたアドレスを、(普通の)int 型変数に代入したいのですが、どのようにするのが正しいのでしょうか。 想定しているケースは、与えられたメモリ番地に対して、アドレスオフセットを加えるなどの操作を施して「補正アドレス」を生成し、メモリアクセスを行う、というような特殊な操作を実現するような場合です。 ※ メモリ番地がポインタ宣言で与えられる、という制約があります。 以下サンプルプログラムを書きました。組み込み系のプログラムを記述していますが、これで正しいでしょうか。 unsigned int *p, *p1; // ポインタ変数宣言 unsigned int value; p= (unsigned int *)0x00001F00; // メモリの0x1F00番地 value = p; // <-- ここが心配 value |= 0xCC << 16; // 与えられたアドレスから value &= 0x4 << 12; // 「補正アドレス」生成 p1 = (unsigned int *)value; *p1 = 0xA5A5_A5A5; // 「補正アドレス」にA5A5... をライト C言語初心者で、いろいろなサイトを見てみたのですが、説明されているページが見つからず質問させていただきました。どうぞよろしくお願いします。

  • int

    猫でもわかるプログラミングを見ていましたら次のような命令がありました。 int は変数宣言ということですがどのように宣言しているのでしょうか。 int takestone(int *, int, int, int); int main()

  • (int *)の意味

    しょーもない質問すみません。 C++を独学中のプログラミング自体初学者です。 今読んでる教科書に、malloc関数の説明として、 指定された大きさの領域をヒープに割り当て、その領域の先頭のポインタを返す関数であるとあり、 例には、 .... int *x; x=(int *)malloc(sizeof(int)); *x=100; ..... などとあるのですが、malloc関数の前の(int *)は xはあくまで変数、malloc関数で帰ってくるのはpointerなので、 *でポインタから変数にした上で、その変数の型をintに強制的にしているという理解で合っているでしょうか?? どうも*がついている分、xはポインタのような気もして、混乱しています。

  • C言語初心者です。ポインタについて教えて下さい。

    ポインタの宣言で次のように宣言します。 int *p1,p2; p1はポインタですが、p2はポインタになるのでしょうか。 それとも普通のp2という変数になるのでしょうか。 友人との間で意見が分かれています。

  • const int&の戻り値について

    const int&の戻り値について c++で「const int&(const int a)const{...」についてのメンバ関数がありますが、そのconst int&はどういう意図に使われるのでしょうか。 &があるので、アドレスを返すと思いますので、ポインタ変数に入れるだけでしょうか。それでもポインタ変数とメンバ関数の戻り値のアドレスは違うのはどういうことでしょうか。 主な使い用途がありましたら、教えてください。

専門家に質問してみよう