• ベストアンサー

プログラムがわからないのですが

とあるC言語の本を読んだのですが、 さっぱり分かりませんでした。 例えば、こんな感じです。 「つぎのプログラムを実行し終わったときの各変数の値を 求めよ。」との事です。 以下、このようになります。 void main() { int i,j,k,l; float p; double x; i=9.2+7.3; j=13/4*4.0; i/=j%5;-(1) p=(--i +j++)/5.0; x=j-p*2; k=i==10llj<=20;-(2) l=i(p/2<x-2);-(3) } 上記のプログラムですが、i=7,j=13,k=1(真), lは0(偽)、pは3.8、xは5.4となります。 j,p,xについてはわかるのですが、 i=7,k=1(真)lは0(偽)について、何故そうなるのか わかりません。 しかし、私なりに考えてみました。 まず、iについては、 j=13ということから、 i/=13%5; i=i/13%5; %というのは、余りのことです。 よって、13÷5=2は、余りは3 iは、整数型だから、 16.5でなく、小数点は、切り捨てて i=16 i=16/3 i=5になるのではないでしょうか。 k=i==10llj<=20;-(2) l=i(p/2<x-2);-(3) の部分ですが、恐らく k=1(真)、lはO(偽)がわからないから、 (2)、(3)がわからないと思います。 (2)は、本で調べた結果、 kとiは、10また、jは、20以下で、 (3)の条件が成り立つのでしょうか。 もし宜しければ、何故、このようなこの答えが 成立するか教えて頂けないでしょうか。 それでは、宜しくお願いいたします。

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

  • ベストアンサー
  • mitoneko
  • ベストアンサー率58% (469/798)
回答No.1

 なんだか・・・・この問題・・・引っかけの山ですね。  優先順位に、型の昇格に・・・まぁ、よりどみどりな問題ですわ。(じつに嫌らしい=^・・;=)  まず、6行目。これが終わった時点で、iは16です。  次、7行目。この時点で、jは、12です。気をつけてください。13では「ありません」。理由は、13/4が整数演算なので、答えが3となることにあります。3*4は12です。  次、8行目。この時点で、iは8です。ここの部分のあなたの考え方はあってます。ただし、jを勘違いしているので、計算が狂っているだけです。  次、9行目。この行は、i、j、pのすべての変数の数値が変わります。順に行きましょう。まず、iですが、このデクリメント演算子が適用されますから、この行が終わったときには、iは1減って、7。jは、インクリメントして、13です。さて、iは、前置で、jは後置ですからpを求める式は、「(7+12)/5.0」で3.8となります。  次の2行は、単純に計算するだけです。が、最後の行は、私にはわかりません。i(・・・)という演算がなんなのか・・・。理解できません。

noname#110303
質問者

お礼

何卒、プログラムミスがあり申し訳ございません。 丁寧な説明は、とても参考になりました。 最後になりますが、わざわざ回答してくださって 誠に有難うございました。 これからもよろしくお願いいたします。

noname#110303
質問者

補足

l=i(p/2<x-2);-(3) でなく、 l=!(p/2<x-2);-(3) です。 申し訳ございません。 もし宜しければ、アドバイスお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (1)

  • symgt
  • ベストアンサー率56% (68/120)
回答No.2

C/C++ではある条件が成立する場合、真(1)を返し、 条件が成立しない場合、偽(0)を返します。 (2)は「iが10またはjが20以下」という条件が成立しているのでkに真(1)が代入されます。 k = (i == 10 || j <= 20);と書いたほうがわかりやすいと思います。 (3)は「p/2がx-2より小さい」という条件が成立しているので「(p/2<x-2)」は真(1)なのですが 否定演算子(!)によりlには偽(0)が代入されます。

noname#110303
質問者

お礼

C言語って、PASCALと違って、 文法がややこしいですね。 1歩1歩成長していきたいです。 ご回答有難うございました。 これからもよろしくお願いいたします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 浮動小数点をXの倍数(整数)に丸める方法

    浮動小数点数Fを、Fにより近いX(整数)の倍数(整数)に丸める方法を教えてください。 自分なりにコード化しましたが、イマイチ美しくないです^^; もっとスッキリした方法があれば教えてください。 よろしくお願いします。 ※Fは正の浮動小数点数に限定します。 long L, mod ; L = (long)F ; //キャストして小数点以下を切り捨てて整数化 mod = L%X ; //Xで除算して余りを求める if ( mod ==0 ) { //既にXの倍数なので何もしない ; } else if ( mod <= X/2 ) { //余りがX/2より等しいか小さい時 L -= mod ; //余りを減算する } else { //mod > X/2の時 L += X-mod ; //Xに満たない分を加算 }

  • プログラムの間違いを教えてください。

    VBAのFFTのプログラムをCで書き直しています。 C言語ではうまく動作しません。間違いを教えていただけないでしょうか? よろしくお願いします。 (1)動くVBAのプログラム(参照 http://tsuyu.cocolog-nifty.com/blog/2007/03/publi.html) Option Explicit Public Sub fft() Dim g, h, i, j, k, l, m, n, o, p, q As Integer i = 0 j = 0 k = 0 l = 0 p = 0 h = 0 g = 0 q = 0 'データ数nを指定(2の整数乗である必要あり) n = 1024 m = Log(n) / Log(2) 'xr,xiはデータ数以上、s,cはデータ数の半分以上を指定しておく Dim xr(1024), xi(1024), xd, s(512), c(512), a, b As Single 'データの読み込み 1列目を実数部、2列目を虚数部とする For i = 1 To n xr(i - 1) = Cells(i, 1) xi(i - 1) = Cells(i, 2) Next i 'FFTの計算 a = 0 b = 3.14159265359 * 2 / n For i = 0 To n / 2 s(i) = Sin(a) c(i) = Cos(a) a = a + b Next i l = n h = 1 For g = 1 To m l = l / 2 k = 0 For q = 1 To h p = 0 For i = k To l + k - 1 j = i + l a = xr(i) - xr(j) b = xi(i) - xi(j) xr(i) = xr(i) + xr(j) xi(i) = xi(i) + xi(j) If p = 0 Then xr(j) = a: xi(j) = b Else xr(j) = a * c(p) + b * s(p) xi(j) = b * c(p) - a * s(p) End If p = p + h Next i k = k + l + l Next q h = h + h Next g j = n / 2 For i = 1 To n - 1 k = n If j < i Then xd = xr(i) xr(i) = xr(j) xr(j) = xd xd = xi(i) xi(i) = xi(j) xi(j) = xd End If k = k / 2 Do While j >= k j = j - k k = k / 2 Loop j = j + k Next i 'データの出力 For i = 1 To n '4列目に実数部、5列目に虚数部、6列目に絶対値を表示 Cells(i, 4) = xr(i - 1) Cells(i, 5) = xi(i - 1) Cells(i, 6) = (xr(i - 1) ^ 2 + xi(i - 1) ^ 2) ^ 0.5 Next i End Sub (2)上記のプログラムの書き換えている箇所 For i = 1 To n xr(i - 1) = Cells(i, 1) xi(i - 1) = Cells(i, 2) Next i 'FFTの計算 a = 0 b = 3.14159265359 * 2 / n For i = 0 To n / 2 s(i) = Sin(a) c(i) = Cos(a) a = a + b Next i l = n h = 1 For g = 1 To m l = l / 2 k = 0 For q = 1 To h p = 0 For i = k To l + k - 1 j = i + l a = xr(i) - xr(j) b = xi(i) - xi(j) xr(i) = xr(i) + xr(j) xi(i) = xi(i) + xi(j) If p = 0 Then xr(j) = a: xi(j) = b Else xr(j) = a * c(p) + b * s(p) xi(j) = b * c(p) - a * s(p) End If p = p + h Next i k = k + l + l Next q h = h + h Next g j = n / 2 For i = 1 To n - 1 k = n If j < i Then xd = xr(i) xr(i) = xr(j) xr(j) = xd xd = xi(i) xi(i) = xi(j) xi(j) = xd End If k = k / 2 Do While j >= k j = j - k k = k / 2 Loop j = j + k Next i (3)書き換えたけど変な値が発生するプログラム #include <stdio.h> #include <conio.h> #include <string.h> #include <stdlib.h> #include <math.h> FILE *fp; FILE *fa; char a[100]; double b[1200]; double c[1200]; double d[1200]; double e[1200]; double f[1200]; char str[100]; char *p; double h; long i; long j; long k; long l; int m; long n; long o; int q; double x[25]; long s; double t; double u[1200]; double v[20][1200]; double v2[20][1200]; double v3[20][1200]; double w[25]; double intercept[10]; double slope[10]; double frequency[12]; double dtime; double dtime2; double theta1; double theta2; double co[1200]; double si[1200]; double xd; long l2; long l3; long n3; long h3; long g3; long m3; long k3; long p3; long q3; long i3; long j3; long x3; double y3; double a3; double b3; double c3; double d3; double f3; double w2[25]; x3=0; y3=0; i3=0; j3=0; k3=0; l3=0; p3=0; h3=0; g3=0; q3=0; a3=0; b3=0; c3=0; d3=0; theta1=0; theta2=3.14159265359*2/1024; for(l=0; l<=512; l++){ si[l]=sin(theta1); co[l]=cos(theta1); theta1=theta1+theta2; } n3=1024; m3=10; l3=n3; h3=1; for(g3=1; g3<=m3; g3++){ l3=l3/2; k3=0; for(q3=1; q3<=h3; q3++){ p3=0; for(i3=k3; i3<(l3+k3); i3++){ j3=i3+1; theta1=c[i3]-c[j3]; theta2=d[i3]-d[j3]; if(p3==0){ c[j3]=theta1; d[j3]=theta2; } else{ c[j3]=theta1*co[p3]+theta2*si[p3]; d[j3]=theta2*co[p3]-theta1*si[p3]; } p3=p3+h3; } k3=k3+l3+l3; } h3=h3+h3; } j3=n3/2; for(i3=1; i3<n; i3++){ k3=n3; if(j3<i3){ xd=c[i3]; c[i3]=c[j3]; c[j3]=xd; xd=d[i3]; d[i3]=d[j3]; d[j3]=xd; } k3=k3/2; while(j3>=k3){ j3=j3-k3; k3=k3/2; } j3=j3+k3; } for(i3=0; i3<n3; i3++){ c[i3]=c[i3]/1024; d[i3]=d[i3]/1024; } (1)中の(2)箇所を(3)のように書き換えました。 どうしてもうまく動作しません。 教えていただけないでしょうか? よろしくお願いいたします。

  • 位数を求めるプログラム

    a^e≡1(mod n)を満たす最小の正の整数eを 法nに関するaの位数です。 これを法31における1、2,...、30の位数を求めるプログラムを以下のように作ったのですが 位数は31が素数なので30の約数であるはずなのですが11とか12などが出てきてしまいます。 問題のある箇所を教えてください。 #include <stdio.h> int main(void) { int h,i,j,k,n; //法31 n=31; //1の位数は1 printf("1:1\n"); for(j=2;j<n;j++){ k=1; for(i=1;i<=(n-1)/2;i++){ //j^iを求める。 k=j*k; for(h=2;h*n<k;h++); //余りが1になるものを位数とする。 if(!((k-1)%((h-1)*n))){ printf("%d:%d\n",j,i); break; } } //i<=(n-1)/2までに余りが1あまるものがなければn-1(30)を位数とする。 if(i>(n-1)/2)printf("%d:%d\n",j,n-1); } return 0; }

  • ガウスの消去法のプログラムがどうしてもうまく動きません。

    こんにちは。あまりにも困ってしまったので質問させていただきました。 よろしければご回答をよろしくお願い致します。 さて、今ガウスの消去法のプログラムを作っているのですが、 どうしてもどうしても、正しい解を得ることができません。 今日はほぼ徹夜でずっとパソコン画面とにらめっこしていたのですが、 何をしてもどこをいじってもさっぱり上手く行かず、正直嫌気が差し始めているところです(泣) Cの詳しい知識などは皆無に近い人間ですが、 こんなド素人を助けていただけませんか? ↓が僕の書いたソースコードです。間違いだらけで非常に見苦しいと思いますがお許し下さい。 #include<stdio.h> #include<stdlib.h> #include<math.h> int main(){ float a[3][3] = { {-2, 4000000, -6000000}, {-2, 0.03, -0.2}, {1, -0.2, -0.05} }; float b[3] = {5000000, 0.1, 0.1}; float max[3]; float maxp; float temp; float x[3]; float m; int pivot = 0; int i,j,k; for( k = 0; k < 3; k++ ){ /* scaling */ for( j = 0; j < 3; j++ ){ max[j] = 0; for( i = 0; i < 3; i++ ){ if( max[j] < fabs(a[j][i]) ) max[j] = fabs(a[j][i]); } } for( j = 0; j < 3; j++ ){ for( i = 0; i < 3; i++ ){ a[j][i] = a[j][i] / max[j]; } b[j] = b[j]/max[j]; } /* pivoting */ for( j = k; j < 3; j++ ){ if ( maxp < fabs(a[j][k]) ){ pivot = j; maxp = fabs(a[j][k]); } } for( i = k; i < 3; i++ ){ temp = a[k][i]; a[k][i] = a[pivot][i]; a[pivot][i] = temp; } temp = b[k]; b[k] = b[pivot]; b[pivot] = temp; /* forword elimination */ for( j = k+1; j < 3; j++ ){ m = a[j][k] / a[k][k]; for( i = k; i < 3; i++ ){ a[j][i] -= a[k][i] * m; } b[j] -= b[k] * m; } /* backward substitution */ for( j = 1; j >= 0; j-- ){ for( i = j+1; i > 3; i++){ m += a[j][i] * b[i]; x[j] -= m; x[j] = x[j] / a[j][j]; } } } for( j = 0; j < 3; j++ ){ for( i = 0; i < 3; i++ ){ printf("%f ", a[j][i]); } printf("\n"); printf("%f", x[j]); } return(0); } ご回答お待ちしております。 改めて、お見苦しいソースコードだったとは思いますが、ご容赦下さい。

  • ループの終了条件について。

    すいません。もう1問質問したかったのですが 800字以上になってしまいましたので再度質問します。 2つの整数i,jを入力し、iをjで割った商と余りを出力するプログラム。 条件1・・・jに0が入力された場合は"0では割れません"と表示し、割り算を実行しないようにする事。 条件2・・・余りが0の時は商のみを表示すること。 条件3・・・このプログラムはi,jともに0を入力するまで繰り返されるようにすること。 #include <stdio.h> main() {      int i,j,k,l;      do      {           printf("整数i:");           scanf("%d",&i);           printf("整数j:");           scanf("%d",&j);           if(j==0)                printf("%d/%d=0では割れません \n",i,j);           else           {                k=i/j;                l=i%j;                if(i%j==0)                     printf("%d/%d=%d \n",i,j,k);                else                     printf("%d/%d=%d余り%d \n",i,j,k,l);          }      }while(!(i==0) && !(j==0)); } これで実行してもiかjのどちらかに0を入力したら終わってしまいます。 両方0の時だけループ終了するとしているつもりなのですが・・・。 長々と質問してすいません。 教えていただけると助かります。m(-_-)m

  • こんにちは!高校一年生の数Iの質問です。

    こんにちは! 数Iで分からない問題がありましたのでできれば教えていただきたいです。 (1)nは整数とする。nを3で割った余りは1、5で割った余りは4、7で割った余りは2であるとする。 nを105で割った余りrを求めよ。 (2)以下の命題が真であるか偽であるかを答え、真の場合は証明を、偽の場合は反例を示せ。 nが2以上の自然数ならば、1+2+・・・・・・・・・+nの約数の中に3以上の奇数がある。 (1)はn=3a+1=7b+2と表す所まで、 (2)は1+2+3+・・・・+n=1/2n(n+1)と表すと教えてもらいましたがそこからが分からないです。 よろしくお願いします。

  • 画像の合成プログラム

    現在、飛行機の羽の左側と、右側の羽で撮った2枚の航空写真を合成するプログラムを作っています。これらの画像には若干のずれがあり、合成するには、左の写真に写っている場所と対応する同じ点を右側の写真から探索する必要があります。今の段階で作っているプログラムでは全ての点を走査することができず、画像の一部だけしか走査されません。 以下のプログラムをどのように変更したら、画像全体を走査できるかアドバイスください。お願いします。 /*対応点の探索*/ for (x = 0; x < 512; x+=25) { for (y= 0; y < 512; y+=25) { for (i = 0; i < 30; i++) { for (j = 0; j < 30; j++) { block1[i][j] = image1[x - 30 / 2 + i][y - 30 / 2 + j]; } } min = 99999; x1 = x*2; if(x1 > 512){ x1 = 512; } y1 = y*2; if(y1 > 512){ y1 = 512; } for (i = 30 / 2; i < x1 - 30 / 2; i++) { for (j = 30 / 2; j < y1- 30 / 2; j++) { sa = 0; for(k = 0; k < 30; k++) { for(l = 0; l < 30; l++) { sa += abs(block1[k][l] - image2[i - 30 / 2 + k][j - 30 / 2 + l]); } } if (min > sa) { min = sa; min_i = i; min_j = j; } } } if(x-15 < min_i && min_i < x+15){ if(y-15 < min_j && min_j < y+15){ printf("File_1の座標点( %d, %d )の対応点は ( %d, %d ) である。\n",y,x, min_j, min_i); } } } } return 0; }

  • Cプログラムによる画像の高速フーリエ変換FFT

    Cプログラムにる画像処理について教えてください。逆高速フーリエ変換(IFFT)によって周波数領域から実空間領域に変換する際、周波数帯域を(低周波数領域に)制限してIFFTを実行できるという文献があるのですが可能でしょうか?通常の逆離散フーリエ変換(IDFT)では可能でした。 以下のコードの修正で可能でしょうか? 例) 512*512の空間周波数領域データを212*212(仮に)の低周波数領域に帯域制限してIFFTで画像に戻したいのです。 以下の以下の一次元FFTコードを用いてX方向とY方向にIFFTしたいと考えています。 void FFT(int ir, int nx, float *xr, float *xi, float *si, float *co, unsigned short *brv) // 1次元フーリエ変換 // int ir; 順変換(1)と逆変換(-1) // int nx; 1次元FFTのデータ数 // float *xr; 実部のデータ xr[nx] // float *xi; 虚部のデータ xi[nx] // float *si; FFT用のサインデータ si[nx/2] // float *co; FFT用のコサインデータ co[nx/2] // unsigned short *brv; FFT用の入れ替えデータ brv[nx] { int i, j, n1, n2=nx, j3, j4, k, l, ll, d=1, g; float a, b, c, s; for(l = 1; l <= nx/2; l *= 2, d += d) { g = 0; ll = n2; n2 /= 2; for(k = 1; k <= n2; k++) { n1 = k-ll; c = co[g]; s = -ir*si[g]; g += d; for(j = ll; j <= nx; j += ll) { j3 = j+n1-1; j4 = j3+n2; a = xr[j3]-xr[j4]; b = xi[j3]-xi[j4]; xr[j3] += xr[j4]; xi[j3] += xi[j4]; xr[j4] = c*a+s*b; xi[j4] = c*b-s*a; } } } 通常のDFTでの帯域制限はこのように行い可能でした。 void fourier1d(int ir, float *fr, float *fi, int nx) { int i, j, n = 1; float *gr, *gi; double u, x; gr = (float *)malloc((unsigned long)nx*sizeof(float)); gi = (float *)malloc((unsigned long)nx*sizeof(float)); for(i = 0 ; i < nx ; i++) { u = i-nx/2; gr[i] = gi[i] = 0; for(j = 150 ; j < 362 ; j++) { x = j-nx/2; gr[i] += (float)( fr[j]*cos(2*PI*u*x/nx)+ir*fi[j]*sin(2*PI*u*x/nx)); gi[i] += (float)(-ir*fr[j]*sin(2*PI*u*x/nx)+fi[j]*cos(2*PI*u*x/nx)); } } if(ir == -1) n = 212; // 逆変換はデータ数で割る for(i = 0 ; i < nx ; i++) { fr[i] = gr[i]/n; fi[i] = gi[i]/n; } free(gr); free(gi); }

  • 配列プログラムのバグ

    入力した正の整数を読み込み、小さい順に並べ替える配列のプログラムを作りたいのですが、以下のプログラムで結果がくるってしまいます。 色々な数値を入力してみたところ、入力した数字のうち、どれかが0に なってしまうようなのですが、いまいち理解できません。 どこを修正すればいいのでしょうか? #include<stdio.h> int main(void){ int a[255],b,i=0,j,k; while(i<255){ printf("正整数:\n"); scanf("%d",&a[i]); if(a[i]==0) break; else if(a[i]<0){ printf("正の整数ではありません"); return 0; } i++; } for(k=0;k<=i;k++){ for(j=0;j<=i;j++){ if(a[j]>a[j+1]){ b=a[j]; a[j]=a[j+1]; a[j+1]=b; } } } printf("入力された整数は小さい順に"); for(j=0;j<=i;j++){ printf("%d,",a[j]); } printf("です。"); return 0; }

  • 命題の真偽

    命題P⇒Qが真となるのは (1) Pが真でQも真 (2) Pが偽であって、Qは真か偽かはどちらでもよい の2パターンがありますよね? 命題P⇒Qが真であることを示せ。といった問題は、 上の(1)・(2)の2つとも成り立つことを示さなくてはならないのですよね? 例えば、高校の数学の教科書にあるような a>b,c>d ⇒ a+c>b+d を証明せよ という問題は、「a>b,c>d ⇒ a+c>b+d」が真であることを証明せよと言っていると思うのですが, 解答では,a>b,c>dが真であることを仮定してa+c>b+dを導いています。 a>b,c>dが偽である場合は考えていませんが、 これは、a>b,c>dが偽の場合、a+c>b+dが真であろうが偽であろうが、いずれにせよ「a>b,c>d ⇒ a+c>b+d」は真となるので、 解答に書く必要がなく、a>b,c>dが真の場合だけを解答に書けばよいからということなのでしょうか? 例えば、 -k<x<k ⇒ x≧-1 が真となるようなkの値の範囲を求めよ。 といった問題があった場合、 (i) k≦0のとき    -k<x<kを満たすxは存在せず(つまり偽であり)、    -k<x<k ⇒ x≧-1 は真 (ii)k>0のとき    -k<x<kを満たすすべてのxが、x≧-1を満たせばよく、    -k≧-1  ∴0<k≦1 以上より、  k≦1  といった具合になると思います。 こういった場合は、Pの部分が偽であることも考慮しますから、 やはり先の証明問題ではPの部分(a>b,c>dが偽の場合)が偽であるときは省略されていると考えるのが妥当なのですかね?

MFC-J960DWNの電話子機の交換
このQ&Aのポイント
  • MFC-J960DWNの電話子機を交換したい場合の手順と注意点について解説します。
  • Windows10を使用している場合のMFC-J960DWN電話子機の交換方法についてまとめました。
  • MFC-J960DWNの電話子機の交換に関する疑問やトラブルについて、具体的な解決策を紹介します。
回答を見る