重要なお知らせ

「教えて! goo」は2025年9月17日(水)をもちまして、サービスを終了いたします。詳細はこちら>

【GOLF me!】初月無料お試し

C言語の配列:「*(w+a)=・・・」という表記について


こんにちは。参考書に載っているプログラムで用いられている関数の一部が分からなかったので質問させていただきました。以下抜粋です。



wgtinit(w,sl,inival,flag)
double w[],inval;
int sl,flag;
{ int i;
double drand48();
i=0;
while(i<sl){if(flag==0) *(w+i)=inval*(drand48()-0.5)*2.0;
else *(w+i)=inval*drand48();
i++}
return(0);}



この関数に出てくる「*(w+i)=」という表記の意味がわかりません。
wが配列でiが整数なのでw[0]、w[1]、w[2]・・・と値を格納しているのではないかと思うのですが、「*」のついた配列の表記なんて見たことがないので自信がありません。あっていますでしょうか?
この表記の仕方は「c言語」じゃなくて、「c++」や「c♯」だったりするのですか?

ご教授お願いします。



ちなみにdrand48()というのは乱数です。

A 回答 (4件)

>wが配列でiが整数なのでw[0]、w[1]、w[2]・・・と値を格納しているのではないかと思うのですが、「*」のついた配列の表記なんて見たことがないので自信がありません。

あっていますでしょうか?

そのとおりです。*(w+1)はw[i]と同じ表現です。
ポインターと配列の関係は誰かが書いてくれるでしょうw
このサイトのCのカテゴリーでも相当数UPされていますから、ポインター 配列で検索してみてください。

気になったのは、そのサンプルコードです。
それは、昔のC言語のスタイルで間違いではないのですが、内容が古いのです。C言語を勉強されるのであれば、現在の標準の機能がその参考書に記載されていない可能性があり、情報技術などの試験に支障をきたす事が考えられます。参考書を現在の内容が反映されたものに交換しましょう。現在の標準規格はC99です。参考書の最後のINDEXをみて「long long」の型宣言が載っていればC99準拠です。

現在の書き方ではこうなります。

double drand48(void); …(1)

void wgtinit(double w[],double inival,int sl,int flag) …(2)
{
int i;

if(flag==0)
for(i = 0;i < sl; i++)
w[i]=inval*(drand48()-0.5)*2.0; … (3)
else
for(i = 0;i < sl; i++)
w[i]=inval*drand48();

return; …(4)
}

(1) 関数のプロトタイプ宣言の追加
(2) void型関数の明示的宣言, 引き数の宣言の変更
(3) ポインターはなるべく使わない
(4) リターンに()は不要
ということです。

(2)は、引数の順番が「dabule,int,dabule,int]の並びでは良くないのです。16bitや32bitのプロセッサーでは問題ないのですが、64bitのプロセッサーではアライメントの問題で余計な処理が掛かってしまいます。64bit,64bit,32bit,32bitにすると処理が早く、無駄が無くなります。

(3)現代のコンパイラは配列の処理を最も上手く行くようにコンパイル時に勝手に手直ししますから、普通に配列で記述した方が解りやすくて良いのです。昔ポインターが推奨されていたのは、コンパイラの能力が低かった為に配列をポインターで記述した方が高速だったためです。ただし、ポインターを使用せざるえない場合もあります。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

書き方が古いのですか!
確かに言われてみれば、今まで見たことのないような表記が他にもあり、他の言語なのか?と思っていましたが、そうゆうことなら話しがつながりますし、Ohgimachiさんに書いていただいた文法なら非常に納得できます。


違う参考書を見ていても同じようなことを思う時がしばしばありました。新しい文法だと思って焦ってはいけないのですね。

文法は少し違っていますが、言ってることはなんとなく分かるので、プログラムの流れとして参考にする程度にこの資料は使いたいと思います。



古い書き方という発想はありませんでした。ありがとうございます。

お礼日時:2010/08/27 10:03

C言語では「*(w+i)=」は「w[i]=」と同じ意味です。


で、現在では、前者でも間違いではないですが、後者の書き方をすべきです。
No.3さんのおっしゃるように、参考書が古いと思われます。
昔はC言語は「おおらか」な書き方が有効でしたが、現在では、信頼性を重んじるので。
wgtinitの戻り値の型も宣言されていませんが、整数値の戻り値ならばintと宣言して return 0; 戻り値を使わない関数ならば void と宣言してreturn; とすべきです。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。

私は大学に入ってからプログラムをやり始めたので、言語の歴史を知らず、戸惑ってしまいました。

しかし、おかげさまですっきりしました。

お礼日時:2010/08/27 10:04

配列の要素にあくせすするのは、*(w + i) のほうが本来の形です。


w[i] というのは利便性に配慮した記法(つまり、シンタックスシュガー)にすぎません。
    • good
    • 0
この回答へのお礼

なるほど、配列の本来の形なのですか。

ありがとうございました。

お礼日時:2010/08/27 09:54

* 表記はポインタ(ポインタ変数)になります (C言語から存在します)



書いてあるソースコード限定で話をすれば
*(w+i)=  と言うのは  w[i]=  と書いているのと同じです 
    • good
    • 0
この回答へのお礼

素早い回答ありがとうございました。非常に助かりました。ありがとうございます。

お礼日時:2010/08/27 09:53

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!