C言語の配列:「*(w+a)=・・・」という表記の意味とは?

このQ&Aのポイント
  • C言語の配列で出てくる「*(w+i)=」という表記の意味を教えてください。
  • この表記はC言語特有のもので、配列wのi番目の要素に値を代入する意味です。
  • 「*」はポインタ演算子で、配列の要素を指すポインタを間接参照するために使われます。
回答を見る
  • ベストアンサー

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

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()というのは乱数です。

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

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

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

thjki6624
質問者

お礼

回答ありがとうございます。 書き方が古いのですか! 確かに言われてみれば、今まで見たことのないような表記が他にもあり、他の言語なのか?と思っていましたが、そうゆうことなら話しがつながりますし、Ohgimachiさんに書いていただいた文法なら非常に納得できます。 違う参考書を見ていても同じようなことを思う時がしばしばありました。新しい文法だと思って焦ってはいけないのですね。 文法は少し違っていますが、言ってることはなんとなく分かるので、プログラムの流れとして参考にする程度にこの資料は使いたいと思います。 古い書き方という発想はありませんでした。ありがとうございます。

その他の回答 (3)

noname#130082
noname#130082
回答No.4

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

thjki6624
質問者

お礼

回答ありがとうございます。 私は大学に入ってからプログラムをやり始めたので、言語の歴史を知らず、戸惑ってしまいました。 しかし、おかげさまですっきりしました。

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.2

配列の要素にあくせすするのは、*(w + i) のほうが本来の形です。 w[i] というのは利便性に配慮した記法(つまり、シンタックスシュガー)にすぎません。

thjki6624
質問者

お礼

なるほど、配列の本来の形なのですか。 ありがとうございました。

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.1

* 表記はポインタ(ポインタ変数)になります (C言語から存在します) 書いてあるソースコード限定で話をすれば *(w+i)=  と言うのは  w[i]=  と書いているのと同じです 

thjki6624
質問者

お礼

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

関連するQ&A

  • C言語 配列を交えた関数

    C言語にて配列を絡めた関数を作っています 配列には後にそれぞれの値を与えるのですが double total(int n){ int i; double total = 0; int y[NUMBER] ={0}; for (i = 0 ; i < n ; i++) { tota = tota + (combination(n,i) * power(i) * y[n - i]);} return (tota); } combinationは順列nCi powerは-1^iを表してあり 別々に表示させた場合問題なく出力されます printf("%lf\n" , res + combination(1,0) * power(0) * y[1] + combination(1,1) \ * power(1) * y[0] のようにして実行した場合もただしくでます しかしこれだとtotalを出力させたとき0となり(関数内で配列を初期化させているため?)={0}を消すと出力時に恐ろしい桁の数になってしまいます この関数をうまく作動させるための改善案をご指導願えませんか?情報不足で判断できない場合補足にて追加させていただきます 当方C言語初心者のため詳しくお願いいたします

  • C言語プログラミングについて

    「要素数10の配列を準備する。 配列の各要素に0.0~1.0の乱数を入れる。 各配列に入力された乱数を出力する。 配列をオリジナル関数hanteiに渡す。 数hantei内において,各要素の値が0.5以上であれば1 , 0.5未満であれば0を出力する。」 C言語でこのような問題があるのですがどのように作ればよろしいのでしょうか? ちなみに以下のように作ってみて、「argcは一度も使用されていない」「argvは一度も使用されていない」とエラー(警告)が出てしまいました。修正、もしくは正しいプログラムを教えてくれませんか? #include <stdio.h> #include <time.h> #include <stdlib.h> #define SIZE 10 int hantei(double num) { return num>=0.5; } int main(int argc,char *argv[]) { double number[SIZE]; int i; srand((unsigned)time(NULL)); for(i=0;i<SIZE;i++) number[i]=(double)rand() / RAND_MAX; //手抜き乱数 for(i=0;i<SIZE;i++) { printf("%f %d\n",number[i], hantei(number[i])); } return 0; }

  • c言語 配列

    関数の中で複数の値を配列で返したいのですが,どうすればいいでしょう? 配列を関数に渡す時にはアドレスが渡されるので,ポインタと同様関数内で値を変えればmain関数の値も変わるのではないかと思ったのですが,上手くいきません. 知りたいのは,main関数の中の配列(できれば2次元配列)の値を他の関数から値を変更する方法です.下のプログラムはためしに書いてみたものです.質問を理解するうえで役立てば幸いです. #include<stdio.h> void func(double aaa[][3] ,double bbb[]); void main(void){ double array_a[3][3]={{1,2,3},{4,5,6},{7,8,9}}; double array_b[3]={0}; func(array_a,array_b); } void func(double aaa[][3] ,double bbb[]) { int i,j; for (i=0;i<3;i++) { for (j=0;j<3;j++) { bbb[i]=bbb[i]+aaa[i][j]; } } }

  • C言語について

    C言語初心者です。 今、プログラミングをしていてわからない箇所があるので質問させていただきます。 自作の関数へ配列を送る際、多重配列の途中の配列の値を関数に送りたい場合どのようにすれば よいのでしょうか? 文ではわかりづらいと思うので、例を書きます。↓ /* 関数 */ int sum(int data[],int N){ int i,temp=0; for(i=0;i<N;i++){ temp=temp+data[i]; } return(temp); } /* 本文 */ int output; int a[10][20][30]={適当な数字が入ってるとします。} // この時、配列の左と右に値を指定して、真ん中の配列を関数に送りたいです。 output=sum(???,20); //ちなみに現在はもう一つ1次元配列を作り、そこに一旦コピーしてから関数に送っています。 //なにか良い方法があればご教授ください。

  • C言語:配列の最大値

    こんにちは。 プログラミングの講義の課題で、 1.100未満の整数20個からなる配列を作成する 2.for文を使って20個の整数の中で最大値を求める 3.その結果を出力する というC言語の課題が出されました。完成はしたのですが、何度実行してもビルドエラーが発生して正常に作動しません。どうすれば正常に作動しますか? #include <stdio.h> int main(void){ int i; int max=0; int num[20] = {4,83,71,90,7,33,62,51,98,21,18,20,75,49,69,14,80,22,8,50}; for( i=0 ; i < 20 ; i++ ) { if (num[i] > max) max = num[i]; } printf("%d,",max); return (0); }

  • C言語で内積、、、わかりません。

    C言語で内積、、、わかりません。 /* double配列 vecter1 のデータと double配列 vecter2 のデータ、 および、 vecter1,vecter2 の「要素数」を関数 naiseki_f に 引数として渡す。 関数 naiseki_f 内では、 vecter1 と vecter2 とによる 「double型の内積値」を計算し、その結果を戻り値とするものである。 main関数内では、関数naiseki_fで計算した「内積値」を printf表示させるプログラムを作成せよ。 */ /* 配列の合計を求める */ #include<stdio.h> double naiseki_f(const int vecter1[],const int vecter2[]); int main(void) { int i,kosuu=10; double vecter1[10]={0.5,0.48,0.54,0.32,0.32,0.46,0.88,0.45,0.90,0.23}; double vecter2[10]={0.24,0.34,0.26,0.78,0.43,0.67,0.88,0.95,0.45,0.75}; double a; a=naiseki_f(vecter1,vecter2); /* ベクトルの内積計算 */ for(i=0; i<kosuu; i++) printf("%5.3f %5.3f\n",vecter1[i],vecter2[i]); printf("内積=%8.3f\n",a); return (0); } /* 内積を計算 */ double naiseki_f(const int vecter1[],const int vecter2[]) { int i; double ###; ############; for(i=0 ; i<10 ; i++) ################# ; return (######); } かれこれ2時間くらい悩んでいるんですが 内積をどうやって計算するのか資料をみてもわかりません、、。 main関数内は自分が入力した部分もあるので多少間違ってるかもしれません。 よろしくお願いします。

  • C言語のことで…

    C言語のポインタの勉強をしているのですが、 9×9の整数型2次元配列を格納する関数kuku_makeを作成。 結果確認はmainで上記関数を呼び出して結果を表示。 void kuku_make(int kuku[][9]) 方向性だけでもいいので教えてください。

  • C言語の2次配列

    4行5列の配列を用意し、その配列の要素をtij(i=1~4, j=1~5)とするとき、tij=i×j となるように配列に値を入れ、 それを表の形で画面に表示するプログラムを作りなさい。  という問題なんですが、自分は下の様に組みましたがうまく動きません。どこが悪いのか教えてください。よろしくお願いします。あまりC言語を理解していないので申し訳ないですが、なるべく簡単に教えて頂ければ幸いです。 #include<stdio.h> int main(void) { int i,j; int t[4][5]; for(i=0;i<=3;i++) { for(j=0;j<=4;j++) t=i*j; printf("%5d",t); printf("\n"); } return 0; }

  • C言語から質問です。

    C言語から質問です。 /* main関数の中で初期化した配列 data[10]={60,30,70,25,20,9,92,55,20,10}; を関数 keisan() に引数として渡して、関数keisan()内で 平均値、最大値,最小値 を求め、その結果をmain関数に戻し、main関数内で 平均値、最大値,最小値を表示させるプログラムを作成せよ。 int keisan(const int data[], int data_kosuu, double answer[]) { return 0; } とする。 (注) プロトタイプ宣言を用いよ。 ヒント:平均値,最大値,最小値の3つの値を main関数に戻すやり方として、配列answer[]を使うとよい。 data_kosuu は、配列の要素数を与えるものです。 ヒント: (int型の変数)/(int型の変数)=int型の値です。 int型同士の割り算の答えANSWERをdoubleにしたい場合は、  ANSWER=(double)(int型の変数)/(int型の変数);    と(double) キャストという操作をする必要がある */ #include <stdio.h> int keisan(const int data[], int data_kosuu, double answer[]); int main(void) { int i; int a[10]={60,30,70,25,20,9,92,55,20,10}; // この値を使ってください double ans[3]; keisan(a,10); /* keisan関数に配列と配列要素数を引数で与える */ for(i=0; i<10 ; i++) printf("a[%d]=%d\n",i,a[i]); printf("平均=%lf 最小値=%d 最大値=%d\n",ans[0],ans[1],ans[2]); return 0; } /* 合計・最大値・最小値を求める関数 */ int keisan(const int data[], int data_kosuu, double answer[]) { int i; int sum; int min,max; min=10; /* min の初期化 */ max=10; /* max の初期化 */ sum=0; /* 合計値の初期化 */ for (i=0; i<10 ; i++){ sum = sum+data[i]; if(data[i] > max) max=data[i]; if(data[i] < min) min=data[i]; } sum=sum/10; answer[0]=sum; answer[1]=min; answer[2]=max; } エラー error C2198: 'keisan' : 呼び出しに対する引数が少なすぎます。 とでて先に進めません。 教科書などを見ても間違いがわかりません; 虫食いになってるところを自分なりにやってみたため、 根本的に間違ってるかもしれませんが、 どうかアドバイスや指摘などをお願いします。

  • c言語

    int kexnsakusuu(int n[30], int c[30],int g){ int y = 0; int h = 0; int flag = 0; int flag_1; int i=1; int u; while(c[i]>0){ h++; u = 0; flag_1=0; while(n[u]>0 && flag_1==0){ if(abs(n[u] - c[i]) <= g){y++;flag_1++;}; u++; } i++; } if(y == h)flag = 1; return flag; } n[30]に12 18 3 3 0 0 0 0 以下0 c[30]に3000 12 3 0 0 0 0 以下0 c[1] c[2]とn[]の絶対値が2以下(gは2)で調べたいのですが、上記だとf‘lagは1を返したいです。 9000件のn[]を調べると誤動作があるみたいです。

専門家に質問してみよう