• 締切済み

プログラムについて

2進数を文字としてgets()関数を使って入力し,入力された値と宣言している変数(初期値は0)とのビット演算和を取り,2進数に変換し直すという3つの動作を繰り返すプログラムを作成しようとしています。 現在は,現在は最後の出力の部分が前回演算和した値が反映されずに出力してしまうのでこまっています。現在作成しているプログラムを添付します。ここを直したほうがよい,または,このプログラムの方がよいのではと思う方は返信願います。 int main(void) { char a[100],e[100]; int len,k,p,g; int c=0,d; int nisin[16]; int i; printf("2進数を入力:"); gets(a); while(a[1]!=0){ len=strlen(a); for(k=0;k<=len-1;k++){ e[k]=(a[k]-'0')<<(len-(k+1)); } g=0; for(p=0;p<=len-1;p++){ g+=e[p]; } printf("10進数は:%d\n",g); c|=g;/**/ printf("演算和:"); /*変換*/ for(i=0; i<16; i++){ nisin[i] = c % 2; c = c / 2; } /*出力*/ for(i=16-1; i>=0; i--){ printf("%d",nisin[i]); } printf("\n"); printf("2進数を入力:"); gets(a); } return 0; }

みんなの回答

  • yama5140
  • ベストアンサー率54% (136/250)
回答No.5

・2進数表記文字列を、gets()関数を使って入力し、それを数値化する。 ・数値化した値と、ある変数(初期値は0)との論理和を求める。 ・これを2進数表記する。 これが「3つの動作」で、  ・「ある変数」は入力以降は初期化せず、1桁の2進数表記文字列が入力されるまで「3つの動作」を繰り返す。 ではないですか。 この解釈が間違っている場合は、以降無視して下さい。 --------------------------------------------------- 過去の質問しかり、今回の質問でも、なにか大きな勘違いされていませんか?。 ★パソコンは、文字にしろ数値にしろ、0か1でしか扱えませんよ。  ここを押さえておけば、「2進数に変換し直す」という記述はしないかと・・。 --------------------------------------------------- 《プログラム構造》 >3つの動作を繰り返すプログラムを作成しようとしています。  「繰り返す」ためと思われる、while( a[1] != 0 ){ は、「2進数1桁の入力でない間」を表すかと思います。  printf( "2進数を入力:" ); と gets( a ); が2組有る無駄を考えると、    while( 1 ){       printf( "2進数を入力:" );       gets( a ); 1つ目の動作の前半(入力)       if( '\0' == a[ 0 ] ) break; // ENTER のみの入力で終了(おまけ)       if( '\0' == a[ 1 ] ) break; // 1桁の入力で終了       ・・(1つ目の動作の後半(数値化))       ・・(2つ目の動作)       ・・(3つ目の動作)    }   がよろしいかと。 《1つ目の動作の後半》  int Str2Value( char a[] ) のような関数を作り、  呼び出し元では、g = Str2Value( a ); とすればよいのでは・・。  具体的には、    for(k=0;k<=len-1;k++){    e[k]=(a[k]-'0')<<(len-(k+1));    }    g=0;    for(p=0;p<=len-1;p++){    g+=e[p];    }  の部分を、一体化すればよいかと( e[], p が不要となります)・・。    g = 0;    for( k = 0; k <= ( len - 1 ); k++ ){      g += ( ( a[k] - '0' ) << ( len - ( k + 1 ) ) );    }    return( g ); 《2つ目の動作》  これは、c |= g; ですよね。 《3つ目の動作》  これも関数にすれば、「値を壊すようなこと」を気にする必要がありません。  void Value2str( int c )  で、呼び出し元は、Value2str( c ); です。  関数の中で、c をどのように料理しようが、呼び出し元の c には影響有りません。  具体的なソースは、質問者様の /*変換*/ と /*出力*/ 部分を、Value2str() に入れるだけ・・。

  • xi_fjw_ix
  • ベストアンサー率100% (2/2)
回答No.4

「質問者:02031988」さんのプログラムの作成意図とか、目的は考慮していません。あくまでも「c = c / 2; で値を壊すようなこと」をしない事だけを考えた提案です。 for(i = 0; i < 16; i++){ nisin[i] = c % 2; c = c / 2; } の個所を以下のように変更してください。 mask = 1; for(i = 0; i < 16; i++){ if((c & mask) != 0){ nisin[i] = 1; }else{ nisin[i] = 0; } mask <<= 1; } それから、変数の定義を1行追加してください。 unsigned int mask;

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.3

論理和を求めた結果について - 2進数化するために変数の値を壊す必要がある - 次の論理和で使うために変数の値を保持する必要がある の両方を満たすには、変数を2つ用意して、片方は2進数化のときに、もう片方は値を保持するために使えばいいだけです。

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.2

括弧が不足していました。正しくは g = (g<<1) + (a[i] - '0'); です。

  • salsberry
  • ベストアンサー率69% (495/711)
回答No.1

「演算和」って珍しい表現ですね。「(ビットごとの)論理和」というのが普通だと思います。 e[k]=(a[k]-'0')<<(len-(k+1)); lenが大きいときに右辺の値がchar型の範囲を超えてしまいます。 ついでに書くと、e[]に各ビットの値を入れてからgに足し込むのは、他の用途でe[]を使うのでなければ無駄です。 試してはいませんが、e[]は使わずこんなのでどうでしょう。 g=0; for (i=0; i<len; i++) { g = g<<1 + (a[i] - '0'); } 本当は、a[i]が'0'または'1'であることのチェックが必要ですが。 「前回演算和した値」がcに残っていることを期待しているのでしょうが、/*変換*/のループの中で c = c / 2; を実行して値を壊してしまっています。 あと、a[]やe[]は2進数100桁 (99桁) 分用意しているのに、nisin[]はなぜ16桁分だけなのでしょうか。

02031988
質問者

補足

salsberryさんへ for(k=0;k<=len-1;k++){ e[k]=(a[k]-'0')<<(len-(k+1)); } 上記の部分を提案された部分と書き直せばよいのでしょうか?? それとも、 for(k=0;k<=len-1;k++){ e[k]=(a[k]-'0')<<(len-(k+1)); } g=0; for(p=0;p<=len-1;p++){ g+=e[p]; } の部分を上記に書き直せばよいのでしょうか? 後、/*変換*/と/*出力*/の部分で10進数から2進数に直そうとしています。このプログラムではc = c / 2;で値を壊すようなことをせずに値を保持したままループさせたいと考えています。お手数ですが、どのようにすればよいかいい案はございませんか?

関連するQ&A

  • マージソートのプログラム

    ↓が自分の作ったマージソートのプログラムなのですが、コンパイルするとエラーが起きてしまいます。 mergesort()にポインタを引数として渡してる、引数の数が足りない、ということが書いてありますが…。 ちゃんとint型を渡してるし、引数の数も合ってるように思います。 どこがおかしいのでしょう? #include<stdio.h> #include<stdlib.h> #include<time.h> #define Max 255 int A[Max]; main(){ int n,k; n=inputdata(); int w=1; mergesort(w,n); printdata(n); return(0); } inputdata(){ //配列に乱数を要素として入れていく int n,i; printf("n= "); scanf("%d",&n); //使用者にいくつの要素を入れるか指定してもらう srand(time(NULL)); for(i=1; i<=n; i++){ A[i]=1+rand()%30; } printf("A[%d]={%d,",n,A[1]); for(i=2;i<n;i++) printf("%d,",A[i]); printf("%d}\n",A[n]); return(n); } void mergesort(int p, int r){ int q; if(p<r){ q=(p+r)/2; mergesort(p,q); mergesort(q+1,r); merge(p,q,r); } } void merge(int p, int q, int r){ int i,j,k,B[Max]; i=p; j=q+1; for(k=p;k<=r;k++){ if((j>r) || ((i<=q)&&(A[i]<=A[j]))){ B[k]=A[i]; i++; }else{ B[k]=A[j]; j++; } } for(k=p; k<=r; k++) A[k]=B[k]; } printdata(int n){ int i; printf("A[%d]={%d,",n,A[1]); for(i=2; i<n; i++) printf("%d,",A[i]); printf("%d}\n",A[n]); } ・エラーメッセージ merge1.c: In function ‘main’: merge1.c:12: warning: passing argument 1 of ‘mergesort’ makes pointer from integer without a cast merge1.c:12: error: too few arguments to function ‘mergesort’ merge1.c: At top level: merge1.c:31: error: conflicting types for ‘mergesort’ /usr/include/stdlib.h:294: error: previous declaration of ‘mergesort’ was here merge1.c:41: warning: conflicting types for ‘merge’ merge1.c:37: warning: previous implicit declaration of ‘merge’ was here

  • ガウスのの単純消去法のプログラムです。

    ガウスのの単純消去法のプログラムです。 前進消去の第k段階が終わった段階でaij,biが表示されるようにしたいんですがどうすればいいでしょうか↓ よろしくお願いします。 #include<stdio.h> #include<stdlib.h> #include<math.h> #define ERROR -1 #define EPS 1.0e-15 int gausssimp(double *, double *, double *, int); int main(void) { double *a,*b,*x,val; char s[32]; int i,j,n,result; printf("Input size n="); gets(s); sscanf(s,"%d",&n); if((a=(double *)calloc(n*n,sizeof(double)) ) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((b=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } if((x=(double *)calloc(n,sizeof(double))) == NULL){ fprintf(stderr,"Memory allocation error\n"); exit(-1); } /* A,b の成分を入力 */ printf("----- A -----\n"); for(i=0; i<n; i++){ for(j=0; j<n; j++){ printf("a(%2d,%2d)=",i+1,j+1); gets(s); sscanf(s,"%lf",&val); a[n*i+j]=val; } } printf("\n----- b -----\n"); for(i=0; i<n; i++){ printf("b(%2d)=",i+1); gets(s); sscanf(s,"%lf",&val); b[i]=val; } /* Gaussの単純消去法による求解 */ result = gausssimp(x,a,b,n); /* 解の表示 */ if(result == ERROR){ printf("ERROR occurs. pivot 0\n"); } else { printf("\n----- solution -----\n"); for(i=0; i<n; i++){ printf("x(%2d)=%.8e\n",i+1, x[i]); } } free(a); free(b); free(x); return 0; } int gausssimp(double *x, double *a, double *b, int n) { int i,j,k; double tmp,p,sum; /* step 1: 前進消去 */ /**** 追加 ****/ /* 前進消去の各段階を終えるごとに,式がどのように変化しているかわかるように表示する */ /**************/ for(k=0; k<n-1;k++){ if(a[n*k+k] == 0.0) { /* ピボットの値が0.割り算でエラーが起きる.*/ return ERROR; } else { /* k+1番目以降の式から x[k] の項を消去 */ for(i=k+1; i<n; i++){ p=a[n*i+k]/a[n*k+k]; for(j=0; j<n; j++){ a[n*i+j]=a[n*i+j]-p*a[n*k+j]; } b[i]=b[i]-p*b[k]; printf("a[%d %d]=%d b[%d]=%d",i,j,a[n*i+j]-p*a[n*k+j],i,b[i]-p*a[n*k+j]); ↑これではできませんでした。。。 } /**********************************/ } printf("k=%d\n",k); } /* step 2: 後退代入 */ for(k=n-1; k>=0; k--){ if(fabs(a[n*k+k]) < EPS) return(ERROR); sum=0.0; for(j=k+1; j<n; j++) sum+=a[n*k+j]*x[j]; x[k]=(b[k] - sum)/a[k*n+k]; } return 0; }

  • C言語プログラム 配列

    C言語プログラム初心者です。以下のプログラムに対して、実行結果がなぜそうなるかがわからないので、詳しく教えてください。 #include<stdio.h> int func(int a[ ],int b[ ],int n); main(){ int i,k; static int a[12] ={1,2,3,4,5,(省略)・・・,12};  static int b[12] ={21,22,23,24,(省略)・・・,32}; k = func(a,b,6); k = func(b+3,a+3,6); printf("a = "); for(i=0;i<12;i++)printf("%d",a[i]); printf("\n = b"); for(i=0;i<12;i++)printf("%d",b[i]); printf("\n k = %d\n",k); } int func(int a[ ],int b[ ],int n){ int i,x=0; for(i=0;i<n;i++);{ a[i] = b[i]; x = x+a[i]; } return(x); } 結果: a = 21 22 23 .... 26 7 8 9 10 11 12 b = 21 22 23 .... 26 7 8 9 30 31 32 k = 99

  • このプログラムみてもらえますか?

    課題は標準入力から正整数aを読み込み、aが素数であるか否か判定するプログラムを作れ、です。 #include <stdio.h> int main(void) { int a,b,c; for(;;){ printf("正整数を入力して下さい。\n"); scanf("%d",&a); c=a%b; for(b=2;b=a-1;b=b+1){ if(c==0) printf("素数でない。\n"); break; } printf("素数です。\n"); break; return(0); } } コンパイルはできますが、実行すると9が「素数です」と表示されます^^; よろしくおねがいします。

  • 関数化について

    何度も質問しているんですがまた行き詰ってしまいました 以前解答をいただき自分なりに進めていき以下のことができるようになりました 1、多項式の係数を入力し、多項式(A)をつくる。 2、それを微分したもの(A’)で割る。→A÷A’=商・・・余りB 3、出てきた余り(B)を割る数、ひとつ前の作業で割る数だったもの(A’)を割られる数にする。 4、割る数(B)の最高次の係数の2乗をしたもの(a^2)を割られる数(A’)にかける。(擬除法) 5、割り算を行う。→(a^2)×A’÷B 6、余りが0になるまで3~5を繰り返す。(0にならなければ終わり) 7、割り切れたときの割る数がAとA’の最大公約数Dとなる(正確には最大公因数?) とここまでできるようになりました。 で、次にさらにまた 8、A÷D=E 9、DとEでユークリッドの互除法により最大公約数Gを求める 10、E÷G=P→PがAのi次の平方因子 11DをAとしDが無平方になるまで1~10を繰り返す。 といったことをやらなければいけないんですが、 いい加減関数を使わないと長すぎるので同じ作業を簡略化するため関数化することにしました。 で、微分のプログラムは関数化できたんですが、ユークリッドの互除法のプログラムが難しくて関数化できません。 わかる方お願いしますm(_ _)m 以下プログラム #include <stdio.h> #include <math.h> int main(void){ int m,m2,i,j,k,l,n,p,q; int a[1000],b[1000],c[1000],d[1000],e[1000]; puts("何次の多項式ですか?"); printf("何次:"); scanf("%d",&m); puts("多項式の係数を入力してください。"); for(i=m;i>=0;i--){ scanf("%d",&a[i]); //e[i]=a[i]; //printf("e[i]=%d\n",e[i]); } derivative(&m,a,&m2,b); printf("微分された多項式は:"); for(i=m2;i>=0;i--){ printf("%dx^%d+ ",b[i],i); } printf("\n\n"); q = 1; l = 0; while(q == 1){ printf("割られる数は:"); for(i=m;i>=0;i--){ a[i]=a[i]*(b[m2]*b[m2]); printf("%dx^%d + ",a[i],i); } q = 0; printf("\n上のは割る数の最高の次数の係数の2乗をかけたもの:b[m2]=%d\n",b[m2]); printf("--\n"); printf("%d回目の商は\n",l+1); for(k=m-m2;k>=0;k--){ c[k] = a[m - (m - m2 - k)] / b[m2]; printf("%dx^%d + ",c[k],k);//商の表示 j = m2; for(i = m - (m - m2 - k);i>= m - (m - m2 - k) - m2 ;i--){ d[i]=a[i]-c[k]*b[j]; a[i] = d[i]; j = j - 1; } } printf("\n"); for (k = m2;k >=0 ;k--){ a[k] = b[k]; } printf("余り:"); for (k = m2-(m-m2);k >=0 ;k--){ b[k] = d[k]; printf("%dx^%d + ",b[k],k); if (d[k] != 0){ q = 1; } } for (k = 0;k <= 1000;k++){ d[k] = 0; } printf("q:%d\n",q); p = m2 - 1; m = m2; m2 = p; l = l + 1; printf("\n"); while(b[m2] == 0){ m2 = m2 - 1; } if (m2 <= 0){ break; } } if (q == 0){ printf("割り切れた"); }else{ printf("割り切れなかった"); } return(0); } int derivative(int *m, int a[],int *m2, int b[]) { int i; for(i=*m;i>0;i--){ b[i-1]=i*a[i]; } *m2=*m-1; return(0); }

  • C言語で多項式の割り算のプログラム

    C言語で多項式の割り算のプログラムを作っているんですができません 以下プログラム #include <stdio.h> int main(void) { int m,m2,i,i2,j,k; int a[1000],b[1000],c[1000],d[1000]; puts("何次の多項式ですか?"); printf("1つめ:"); scanf("%d",&m); printf("2つめ:"); scanf("%d",&m2); puts("1つめの多項式の係数を入力してください。"); for(i=m;i>=0;i--){ scanf("%d",&a[i]); } puts("2つめの多項式の係数を入力してください。"); for(i=m2;i>=0;i--){ scanf("%d",&b[i]); } k=m-m2; c[k]=a[m]/b[m2]; printf("商の次数は%dです。\n",k); j=m2-1; for(k=m-m2;k>=0;k--){ for(i=m-1;i>=0;i--){ d[i]=a[i]-c[k]*b[j]; a[i]=d[i]; c[k-1]=a[i]/b[m2]; j=j-1; } printf("%d ",c[k]); } return(0); } 原因は  for(k=m-m2;k>=0;k--){ for(i=m-1;i>=0;i--){ d[i]=a[i]-c[k]*b[j]; a[i]=d[i]; c[k-1]=a[i]/b[m2]; j=j-1; } printf("%d ",c[k]); } で、iのfor文が終わった後kのfor文が更新され、またiのfor文が始まったときにa[i]が最初に入力された値に変わってしまうからだと思うんですが直せません 誰か教えてくださいm(_ _)m

  • ネイピア数(e)のプログラム

    テイラー展開によってネイピア数の近似値を求める プログラミングが全くわかりません。 e = 2.71828 18284 59045 23536 02874 71352 … を計算したいのですが。 #include <stdio.h> #include <math.h> int kaijou(int p) { int cnt; int val=1; for(cnt=1 ; cnt<=p ; cnt++){ val=val*cnt; } return(val); } double napier(int p) { printf("eを計算します。E = (1+(1/k))^k\n"); printf("k=いくつまで計算しますか ?\n"); scanf("%d", &n); double E[n]; E[1] = 1; for (j = 1; j <= n; j++){ E[j] = E[j] + 1; } for (k = 1; k <= n; k++) { K = K + 1; A = 1 / K; // printf("A = %e, ",A); B = 1 + A; // printf("B = %e\n",B); for ( i = 1; i<=k; i++){ E[k] = E[k] * B; // printf("E[%3d]= %e\n",k,E[k]); } void main(void) { int n; int cnt; double answer; printf("計算する最大の項nを入力してください:"); scanf("%d",&n); for(cnt=1 ; cnt<=n ; cnt++){ answer=napier(cnt); printf("第%d項までの近似値:%f 真値:%f 差:%f\n",cnt,answer,exp(1),answer-exp(1)); } }

  • 2×2行列の掛け算をするプログラム

    タイトルのプログラムなんですが、授業で例題としてソース渡されたんですが、学校のUNIXのやつだと動くんですけど、自分の使ってるVC++だと動かないんですよ。 その理由と、VC++で動くようにするにはどうしたらいいかおしえてください。 ソースは、 #include<stdio.h> void get_data(); void write_data(); void product(); main() { double a[2][2],b[2][2],c[2][2]; get_data(a); get_data(b); write_data(a); write_data(b); product(a,b,c); write_data(c); } void get_data(double p[][2]) { int i,j; printf("Input elements\n"); for(i=0;i<2;i++) for(j=0;j<2;j++){ printf("(%d,%d)-th element=",i,j); scanf("%lf",&p[i][j]); } } void write_data(double p[][2]) { int i,j; printf("\n"); for(i=0;i<2;i++){ for(j=0;j<2;j++) printf("(%d,%d)-th element=%lf\t",i,j,p[i][j]); printf("\n"); } printf("\n"); } void product(double u[][2],double v[][2],double w[][2]) { int i,j,k; for(i=0;i<2;i++) for(j=0;j<2;j++){ w[i][j]=0.0; for(k=0;k<2;k++) w[i][j]+=u[i][k]*v[k][j]; } } です。 よろしくおねがいします。

  • 文字の表示なのですが

    int i; int len = length[n]; for( i = 0; i <= len; i++ ){ printf("%c ", path[n][i] + 'A' ); } printf("%c\n", goal + 'A' ); } このままだと、 ABCDEFGHIJ・・・の順に表示されてしまいます。 SABCDEFGHI・・・と表示したいのですがどのようにすればいいのでしょうか。

  • ポインタ スペースを数えるプログラム

    入力した文章のスペースを数えるプログラムを作ってみました. ポインタをまだしっかり理解していないのですが,ポインタを使用 する場合,以下のようなプログラムで正しいですか? (オーバーフローなどについては対処していません.) #include<stdio.h> int main(void) { char str[80],*p; int i,count=0; gets(str); p=str; for(i=0;i<80;i++) { if(p[i]==' ') { count++; } } printf("%d",count); return 0; }

専門家に質問してみよう