• ベストアンサー

ビット列を走査するプログラムの関数化

char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムをCで書きたいと思っています。 他のプログラムでも使いまわし、かつ見やすくするためにこの部分を関数化したいのです。ソースにはbreakを使っているのですが、当然ながらbreakはforかwhile内で使わないとダメだと思いますが、ソース作成の都合上、for文は関数内に入れたくないのです。 (つまり、条件分岐を関数化したものをfor文内で用いたい) うまい方法が思いつかずに困っています。もし良い方法をお気づきの方がおられたらご助力下さい。 //===============================================// //=================以下ソース====================// //===============================================// //ビット配列correct_ciphertextとPbinを比較するプログラム //LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める //Pbinは固定値を与えている #include <stdio.h> #include <string.h> unsigned int mes[2]; unsigned int key[2]; char Pbin[64]; char Kbin[64]; char ciphertext[64] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; void ConvertPtextToBin_ForHost(unsigned int mes[]){ unsigned int tmp_mes[2] = {mes[0], mes[1]}; int i, j; for(j=0;j<=1;j++){ for(i=0;i<=31;i++){ Pbin[j*32 + 31-i] = tmp_mes[j] % 2; tmp_mes[j] = tmp_mes[j] / 2; } } } int main(int argc, char *argv[]){ //initialize mes[0] = 0x00000000; mes[1] = 0x00000000; int i, j, k; int x=0, y=0; while(1){ printf("mes[1] = %d\n", mes[1]); ConvertPtextToBin_ForHost(mes); for(i=0; i<64; i++){ printf("%d", Pbin[i]); if((i+1)%8 == 0) printf(" "); } printf("\n"); //************************* //ビット走査 //************************* for(k=0; k<64; k++){ if( (ciphertext[63-k] == Pbin[63-k]) ){ //同じビットであれば、次のビットを走査する }else{ printf("Error\n");//後ろから走査していって、1ビットでも違うものがあれば違うビット列と判断する break; } } //ここに来たら違うビット列だったということ if(k != 64){ mes[1]++; printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", k); printf("This was %d*%dth Search...\n\n", y, x); x++; if(x>=65535){i=0; y++;} }else{ //k=64つまり、最後のビットまで同じビットだったということ⇒つまり、「発見」 printf("Match ciphertext\n"); printf("This was %d*%dth Search...\n\n", y, x); break; } //*********************** //ビット走査の終了 //*********************** } }

  • g47040
  • お礼率55% (125/226)

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

  • ベストアンサー
  • BLK314
  • ベストアンサー率55% (84/152)
回答No.5

こんな感じでどうでしょうか 一応動作確認はしてあります //// ソースはここから /////////////////////////////////////////// // ChkBit.cpp : コンソール アプリケーションのエントリ ポイントを定義します。 // #include "stdafx.h" //ビット配列correct_ciphertextとPbinを比較するプログラム //LSBからMSBまで順に走査を行い、違うビットが出てきた時点でbreakし、走査を止める //Pbinは固定値を与えている #include <stdio.h> #include <string.h> // 扱う最大ビット長 #define MAX_BIT_LENGTH 64 // ブロック化するビット長 #define BLOCK_LENGHT 8 unsigned int mes[2]; unsigned int key[2]; char Pbin[MAX_BIT_LENGTH]; char Kbin[MAX_BIT_LENGTH]; char ciphertext[MAX_BIT_LENGTH] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}; // 指定された配列(bitをエミュレート)の指定ビットに値を設定する static void SetBit(char Dest[], int Pos, int Bit) { Dest[Pos] = Bit; } static void ConvertPtextToBin_ForHost(unsigned int mes[]) { unsigned int tmp_mes[2] = {mes[0], mes[1]}; int i, j; for(j = 0;j <= 1;j++) { for(i = 0;i <= 31;i++) { SetBit(Pbin, j * 32 + 31 - i, tmp_mes[j] & 0x01); tmp_mes[j] >>= 1; } } } // 8ビットを1ブロックとして区切りながら表示する static void FmtDisp(char sec[]) { int i; for (i = 0; i< MAX_BIT_LENGTH; i++) { printf("%d", Pbin[i]); if (!((i+1) % BLOCK_LENGHT)) printf(" "); } printf("\n"); } // ビットパターン配列(char配列)を比較し // 配列[0]がMSB 配列[MAX_BIT_LENGTH - 1]がLSBとする // LSBから順にサーチするものとする // 最初に違いが見つかったビットの番号(MSB = 0)を返す // 全ビット一致した場合はLengthを戻す static int FindDiffBitNumber(char buf1[], char buf2[], int Length) { int i; for (i = 0; i < Length; i++) { int n; n = Length - 1 - i; // LSBを基準としたビット位置 if (buf1[n] != buf2[n]) return i; } return Length; } // ビット走査を行う // 違うなら0, 同一なら0以外を戻す static int SearchBit(char buf1[], char buf2[], int Length, unsigned int mes[], int* x, int* y) { long n; n = FindDiffBitNumber(buf1, buf2, Length); if(n < Length) { // 違うビットが検出された場合 mes[1]++; printf("Not match ciphertext... %dth bit didn't match. (0bit:LSB)\n", n); printf("This was %d*%dth Search...\n\n", *y, (*x)++); if (*x >= 65535) { (*y)++; } return 0; } else { // 同一だった場合 printf("Match ciphertext\n"); printf("This was %d*%dth Search...\n\n", *y, *x); return 1; } } int main(int argc, char *argv[]) { int x = 0, y = 0; //initialize mes[0] = 0x00000000; mes[1] = 0x00000000; do { printf("mes[1] = %d\n", mes[1]); ConvertPtextToBin_ForHost(mes); // 8ビットを1ブロックとして区切りながら表示する FmtDisp(Pbin); } while (!SearchBit(ciphertext, Pbin, MAX_BIT_LENGTH, mes, &x, &y)) ; } /// ソースはここまで /////// x, yはSearchBit()関数内のstatic変数として、 パラメータから除くことも考えました。 しかし、 SearchBit()が使いまわされることを考えると、 x, yのリセット処理が必要になります。 この辺は単なる関数化だけでなく、 "モジュール化"も考えたほうがいいかとも思います。 (C++のクラス化も大いにありです) そして x, yはstatic変数(C++ではメンバ変数)とし、 SearchBit()のパラメータから除く。 代わりにx,yをリセットする関数を設ける こちらのほうが使いやすいと思います。

その他の回答 (4)

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

>char型の変数に0or1を入れて擬似的にビット列にした配列をLSBからMSBまで走査し、一致したらループを抜け終了するプログラムを  ソースをみると、一致するかの変数 mes は0からインクリメントしているだけですよね。  乱数でもなく・・。  それに要する時間を計測する訳でもなく・・。  「走査し、一致したら」とは、取りも直さず、なにもせず、 ☆ ciphertext をそのまま8桁区切りで出力するだけ、ではないですか。 >他のプログラムでも使いまわし、  どのような利用用途があるのでしょうか、補足願います。 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 質問者様の意図をくみ取れないままに・・。 ・下の関数を main 関数の while 文内で呼び出したら如何でしょう。   1 で戻ったら while を break すればよろしいかと・・。 char ciphertext[ 128 ] = {   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   0, 0, 0, 0, 0, 0, 0, 0,   1, 0, 0, 0, 0, 0, 0, 0,   9 // ストッパー }; int Check64( void ) {  char *pP, *pC;  pP = Pbin;  pC = ciphertext;  while( 1 ){    if( 9 == *pC ) return( 1 );    if( *pP != *pC ) return( 0 );    pP++;    pC++;  }  return( 1 ); }

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.3

判定部を関数化してそれを呼び出す側の親ループを関数の中で制御したいってことですか? それって無理でしょ .... while( TRUE ) {   myFunc(...); } n++; といった具合で myFuncの中から n++へ直接行きたい ってことでしょうか 質問からその主旨がいまいち明確に見えないんですが 一般的な実装ならmyFuncの戻り値で成否の判定をしてことではないかと while( TRUE ) {   if ( myFunc(...) ) {     break;   } } n++;

  • BLK314
  • ベストアンサー率55% (84/152)
回答No.2

プログラムの"仕様"の理解不足かもしれないですが memcmp() では用は足りないのでしょうか? 1ビット比較する都度、結果を出力しなくていけない仕様とか.... 単にビットパターン比較の結果だけが得たいなら memcmp() で実装すれば、ループなんか不要になり、 ずっと高速だと考えますが....

  • redfox63
  • ベストアンサー率71% (1325/1856)
回答No.1

int CheckBit( int nBit, char* bitSrc, char* bitDes ) {   return bitSrc[nBit] != bitDes[nBit]; } メイン側で int bFlag; bFlag = FALSE; for(k=0; k<64; k++ ) {   if ( bFlag = CheckBit( 63-k, ciphertext, Pbin) ) {     break;   } } if ( bFlag ) {   // 違うと判定された } else {   // 同一 } ってことですか? # どの部分を関数かしたいのか明示しましょう

g47040
質問者

お礼

回答有難う御座います。 どこの部分を関数化したいか明示するのを忘れていました、失礼しました。 上記のソースはだいたい下のような構造になっていますが、関数化したいのは、「ビット走査」から「ビット走査の終了」までです。この中でbreakが2回使われていますが、2回目のbreakが問題でなっているのです(1回目のbreakはfor文内なので問題ない) 処理の途中に条件判定が発生していて、もしある条件に一致したら強制的にwhileループを抜ける、というプログラムなのでbreakが必要なのですが、while(1)を含まない部分を関数化したいのです。 また、書いていただいたソースはだいたいその通りです。「//同一」と書いてある部分でbreakを挟みたいのです。 よろしくお願いします。 <上記ソースの構造> int main(int argc, char *argv[]){ while(1){ ... for(i=0; i<64; i++){ ... } //************************* //ビット走査 //************************* for(k=0; k<64; k++){ if( (ciphertext[63-k] == Pbin[63-k]) ){ ... }else{ printf("Error\n"); break; } } if(k != 64){ ... }else{ ... break; //←ここのbreakが問題 } //*********************** //ビット走査の終了 //*********************** }

関連するQ&A

  • ラベリング処理プログラム

    画像のラベリング処理プログラムを作っているんですが どうもうまく実行できません。よければ教えていただけないでしょうか。 #include<stdio.h> #include<stdlib.h> int column, row; unsigned char val[4] = {0,0,0,0}; unsigned char tmp[255]; int pos_y[4] = {-1, 0, 1, 0}; int pos_x[4] = {0, 1, 0, -1}; int i, j, x, y, label, level, label1; int label_count = 1; unsigned char *in, *out; void labeling_main(); void labeling_search(); void labeling_main() { for(i = 0; i < y; i++){ for(j = 0; j < x; j++){ printf("aaa\n"); if(out[i * x + j] == 255){ printf("bbb\n"); fflush(stdout); out[i * x + j] = label_count; labeling_search(label_count, i, j); label_count++; } } } } void labeling_search(int label_count, int x, int y) { for(i = 0; i < 4; i++){ if(out[(pos_y[i] + y) * x + (pos_x[i] + x)] == 255){ out[(pos_y[i] + y) * x + (pos_x[i] + x)] = label_count; labeling_search(label_count,(pos_y[i]+y),(pos_x[i]+x)); } } printf("ccc\n"); } int main(int argc, char *argv[]) { int result; int head, Magic; unsigned char *image, *in, *out, *res, *ros; FILE *fin, *fout; if(argc!=3){ printf("Usage : %s input output\n",argv[0]); exit(1); } fin = fopen(argv[1],"rb"); /* -------------------- ヘッダ取得ここから -------------------- */ fgets(tmp,255,fin); if(tmp[0]!='P') return 0; sscanf(tmp,"P%d",&Magic); if(Magic < 1 || Magic > 6) return 0; do fgets(tmp,255,fin); while(tmp[0]=='#'); sscanf(tmp,"%d %d",&x,&y); if(x < 1 || y < 1) return 0; fgets(tmp,255,fin); sscanf(tmp,"%d",&level); /* ヘッダの確認 */ printf("P%d\n",Magic); printf("%d %d\n",x,y); printf("%d\n",level); /* 画素の読み込み */ in = (unsigned char *)malloc(sizeof(unsigned char) *x*y); fread(in,sizeof(unsigned char),x*y,fin); fout = fopen(argv[2],"wb"); fprintf(fout,"P%d\n",Magic); fprintf(fout,"# My new PGM\n"); fprintf(fout,"%d %d\n",x, y); fprintf(fout,"%d\n",level); fwrite(out, sizeof(unsigned char),x*y, fout); out = (unsigned char *)malloc(sizeof(unsigned char) *x*y); //2値画像 for (i = 0; i < y; i++) { for (j = 0; j < x; j++){ if(in[i * x + j] > 120){ out[i * x + j] = 0; }else if(in[i * x + j] <= 120){ out[i * x + j] = 255; } } } labeling_main(); printf("Max label number:%d\n",label_count); free(in); free(out); fclose(fin); fclose(fout); } コンパイルは通るのですが実行するとlabeling_mainの if文でセグメンテーションが出てしまいます。

  • 関数とビット列

    C言語勉強中です。下記本から抜粋したものですが、 関数の流れや、1U、~0Uなどの意味がわかりません。 それぞれ関数の中でどのような処理をしているのでしょうか? scanfで正数入力し、print_bitsにnxを渡し、そこのxを1と&して 2進の0か1を表示させるのはなんとなく解るのですが、PCのCPUの ビット数を確認する為?の動きなどがわかりません。 どうか、解説していただける方、よろしくお願いします。 #include <stdio.h> int count_bits(unsigned x) {     int count = 0;     while (x) {           if (x & 1U) {              count++;           }           x >>= 1;      }      return (count); } int int_bits(void) {      return (count_bits(~0U)); } void print_bits(unsigned x) {      int i;      for (i = int_bits() - 1; i >= 0; i--) {           putchar(((x >> i) & 1U) ? '1' : '0');      } } int main(void) {      unsigned nx;      printf("非負の整数を入力してください:");      scanf("%u", &nx);      print_bits(nx);      putchar('\n');      return (0); }

  • 配列の長さについて

    現在課題で書いているプログラムに以下のような関数があるのですが、 unsigned char key[32]; int w[60]; int data[NB]; int nk; int nr; int data2[32]; int Cipher(int *); int invCipher(int *); void encryptEBC(int *); void decryptEBC(int *); main(){ unsigned char keys[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07, 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f}; unsigned char iv[]={0xcb,0x70,0x05,0x9e,0x27,0x2f,0x4e,0xd2, 0xd0,0xbe,0x0b,0x06,0xbf,0x16,0xec,0x5a}; unsigned char init2[]={'1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0', '1','2','3','4','5','6','7','8','9','0',0x0a}; //unsigned char init2[]={'h','e','l','l','o'}; int isize = sizeof(init2)/sizeof(init2[0]); int dsize2 = sizeof(data2)/sizeof(data2[0]); printf("%d,%d\n",isize,dsize2); FILE *fp; char *fname = "test.txt"; unsigned char init[16]; int i = 0; int c; fp = fopen( fname, "r" ); if( fp == NULL ){ printf( "%sファイルが開けません\n", fname ); return -1; } while( (c = fgetc( fp )) != EOF ){ init[i] = c; i = i+1; } fclose( fp ); memcpy(key,keys,16); nk = 4; nr = nk + 6; KeyExpansion(key); memcpy(data,init,16); memcpy(data2,init2,isize); printf("%d\n",dsize2); datadump("PLAINTEXT: ",data,16); datadump("KEY: ",key,16); Cipher(data); datadump("Cipher: ",data,16); invCipher(data); datadump("invCipher: ",data,16); printf("\n"); printf("%d\n",dsize2); datadump("PLAINTEXT: ",data2,dsize2); encryptEBC(data2); printf("%d\n",dsize2); datadump("EBCCipher: ",data2,dsize2); decryptEBC(data2); datadump("invCipher: ",data2,dsize2); printf("\n"); return 0; } void encryptEBC(int data[]){ int dsize = sizeof(data)/sizeof(data[0]); int tmp[16]; int i,j,k; printf("%d\n",dsize); KeyExpansion(key); for (i = 0; i < dsize; i += 16) { for (j = 0; j < 16; j++){ tmp[j] = data[i + j]; } Cipher(tmp); for(k=0;k<16;k++){ data[i+k] = tmp[k]; } } } 関数encryptEBC内のdsizeの値がこの場合だとmain内の配列data2の長さ32になってほしいのですが、1になってしまいます。 非常に見ずらいプログラムで申し訳ないのですが、どなたか1になってしまう理由、またどうすれば正しくdata2の長さを求められるか教えていただけないでしょうか?

  • 有限体GF(4)上の同次方程式で不定方程式

    連立方程式の解法ですが、手計算だとうまくいくのにプログラムにしようとするとうまくいきません。 さらに不定方程式なので解がないといわれてしまいます。誰かわかる方がいらしたらプログラムを 見て直していただきたいです。プログラムは以下の通り。 #define N 4 #define T 6 unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char gf[4]={0,1,2,3},fg[4]={0,1,2,3}; unsigned char ad[4][4]; /* 答えは 1,1,2 */ unsigned char s[3][3]={{1,3,1},{3,3,0},{1,0,3}}; /* 答えはzを不定として1と置き、x=z=1;y=0;になる筈だがならない */ //unsigned char s[][]={{2,2,2},{2,0,2},{2,2,2}} int add(int x,int y){ return ad[x][y]; } int mlt(int x, int y){ if(x==0||y==0) return 0; return ((x+y-2)%(N-1))+1; } int mltn(int n,int x){ int i,j; if(n==0) return 1; i=x; for(j=0;j<n-1;j++) i=mlt(i,x); return i; } int div(int x,int y){ if(x==0) return 0; return ((x-y+(N-1))%(N-1))+1; } void syn(){ int i,j,k,l,n; for(i=0;i<3;i++){ for(j=0;j<3;j++){ if(i==j){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } // exit(1); if(s[i][j]==0){ while(s[i][j]==0){ j++; } printf("i-j==%d\n",s[i+1][j]); if(s[i][j]!=0){ if(s[i][j]==1){ for(l=0;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); printf("%d ",s[l][k]); } printf("\n"); } } // exit(1); if(s[i][j]!=1){ printf("%da \n",s[i][j]); n=div(1,s[i][j]); if(n==0){ printf("%d =\n",fg[s[i][j]]); exit(1); } for(k=0;k<3;k++){ if(s[0][0]==0){printf("%d?\n",s[0][0]); exit(1);} s[i][k]=mlt(n,s[i][k]); printf("%d ",s[i][k]); } printf("\n"); for(l=i;l<3;l++){ for(k=0;k<3;k++){ s[l+1][k]=add(s[l+1][k],mlt(s[l+1][k],s[i][k])); // printf("%d ",s[l][k]); } printf("\n"); } printf("\n"); for(l=0;l<3;l++){ for(k=0;k<3;k++) printf("%d ",s[l][k]); printf("\n"); } }} // i++;j++; //exit(1); } } } } } for(i=0;i<3;i++){ for(j=0;j<3;j++) printf("%2d ",s[i][j]); printf("\n"); } } int main(){ int i,j; for(i=0;i<N;i++){ for(j=0;j<N;j++) ad[i][j]=fg[gf[i]^gf[j]]; } syn(); }

  • Gaussの消去法のプログラムなんですがこれを利用して、消去法による行

    Gaussの消去法のプログラムなんですがこれを利用して、消去法による行列式の計算プログラムをつくりたいのですが難しくてよくわかりません。。。 教えていただきたいです。 困ってるのでよろしくお願いします。 int gauss(double *x, double *a, double *b, int n) { int i,j,k,m; double tmp,p,sum; for(k=0; k<n-1;k++){ printf("---- Step %d ----\n",k+1); printf("-- before --\n"); for( m = k;m < n;m++){ printf("%lf\n",a[n * m + k]); } printf("-- --\n"); j = pivot(a,n,k); if(j == ERROR) { return ERROR; } else { if(j != k) { for(i=0; i<n; i++){ tmp = a[n*k+i]; a[n*k+i] = a[n*j+i]; a[n*j+i] = tmp; } tmp=b[j]; b[j]=b[k]; b[k]=tmp; } } printf("-- after --\n"); for( m = k;m < n;m++){ printf("%lf \n",a[n * m + 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]; printf("a[%d %d]=%lf",i,j,a[n*i+j]); } b[i]=b[i]-p*b[k]; printf("b[%d]=%lf\n",i,b[i]); } 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; } int pivot(double *a, int n, int k) { int i,m; double d; /* ピボットの探索 */ m = k; d = fabs(a[k*n+k]); for(i=k+1; i<n; i++){ if(fabs(a[n*i+k]) > d){ m = i; d = fabs(a[n*i+k]); } } if(fabs(d) < EPS) { return ERROR; } else { return m; } }

  • プログラムのことで

    次のプログラムの変数の説明と処理の流れを素人でも理解できるように説明してもらえないでしょうか。 #include <stdio.h> #define MAX 128 int str_comp(char nx[], char ny[]){ int i, j, k=0; for(i=0; i<=MAX; i++){ if( nx[i]=='\0' ){ return 0; } else if( nx[i]==ny[0] ){ for( j=0; nx[i]==ny[j]; j++ ){ i++; } if( ny[j]=='\0' ){ return 1; } } } } int main(void) { char namex[MAX}; char namey[MAX}; int n; int i; printf("文字列x(64文字まで)? "); scanf("%s",namex); printf("文字列y(64文字まで)? "); scanf("%s",namey); n=str_comp(namex,namey); if(n==1){ printf("'%s'に'%s'は含まれます\n",namex,namey); } else if(n==0){ printf("'%s'に'%s'は含まれません\n",namex,namey); } return 0; } 実効結果 文字列x(64文字まで)? Katatsumuri  文字列y(64文字まで)? ta 'Katatsumuri'に'ta'は含まれます. エラーは出ないはずです。 よろしくお願いします。

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

    ガウスのの単純消去法のプログラムです。 前進消去の第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; }

  • プログラム

    下のようなプログラムを作ったのですが、10進2進変換をj=n>>2&1の部分にあるようなビットシフトではなく、 for(i=1;i<8;i++){printf("bit[%d]=%d\n",i,n%2);n=n/2;}に変えて剰余計算で行うプログラムにしたいのですが、分かる方がいましたら教えて下さい。お願いします。 #include <stdio.h> int main(void) { int i,j,n; i=2; printf("数字を入力="); scanf("%d",&n); printf("Dec=%d\n",n); printf("heX=0x%x\n",n); j=n>>2&1; printf("bit[%d]=%d\n",i,j); return(0); }

  • 上三角行列の解を出力するプログラム

    /*下記のプログラムで”1回目”という部分以降の繰り返し計算がうまくいきません.エラーは出ませんが,何が間違っているか,お気づきの点を教えてください,よろしくお願いします(..) */ #include <stdio.h> #include <stdlib.h> #include <math.h> int main(){ FILE *fp; //*fp fopen("kadai2.dat","w"); //数値結果エラー表示 if((fp=fopen("kadai2.dat","w"))==NULL){ printf("error\n"); exit(1); } int i,j,k; double r=2,ta=1000,tb=0;//r,ta,tb const int N=10;//N const int T=1;//N const int m=N-1;//mは(N-1)とりあへず一定にしないと定まらないみたい const int n=N-1;//n=N-1 とりあへず一定にしないと定まらないみたい const int t=T;//n=N-1 とりあへず一定にしないと定まらないみたい //行列定義aa,xx double a[m+2][n+2],**aa,a1,x1; double x[n+2][t],**xx; aa=( double **) malloc((unsigned) m*sizeof(float*)); for(i=0;i<=m-1;i++){ aa[i]=a[i]; } xx=( double **) malloc((unsigned) n*sizeof(float*)); for(i=0;i<=n-1;i++){ xx[i]=x[i]; } //xx[n][t]初期化 x[0][],x[10][]以外 for(i=1;i<=n+1;i++){ x[i][0]=0; } //huyou double b[n+2][t],**bb; bb=( double **) malloc((unsigned) m*sizeof(float*)); for(i=0;i<=m-1;i++){ bb[i]=b[i]; } //************************************ 入れなおしでx完成 //kの繰り返し開始 for(k=0;k<=T;k++){ //aaに初期値 初期化 for(j=0;j<=N;j++){ for(i=0;i<=N;i++){ a[j][i]=0; } } //aaに値代入 for(i=0;i<=N-1;i++){ a[i][i]=1+2*r; a[i+1][i]=-r; a[i][i+1]=-r; } //xx[n][t]初期化 x[0][],x[10][] x[0][k]=ta; x[10][k]=tb; //xx[n][t]値代入 j x[1][k]=x[1][k]+r*x[0][k]; x[N-1][k]=x[N-1][k]+r*x[10][k]; //************************************計算部 //printf("*********************** %d\n",k); //1回目 for(j=1;j<=N-2;j++){ for(i=1;i<=N-1;i++){ a[j+1][i]=a[j+1][i]-a[j][i]*a[j+1][j]/a[j][j]; } x[j+1][k]=x[j+1][k]-x[j][k]*a[j+1][j]/a[j][j]; } for(j=1;j<=N-1;j++){ for(i=1;i<=N-1;i++){ printf("%4.2fl",a[j][i]); } printf("\n"); } //2回目 for(j=1;j<=N-2;j++){ for(i=1;i<=N-1;i++){ a[N-1-j][i]=a[N-1-j][i]-a[N-j][i]*a[N-1-j][N-j]/a[N-j][N-j]; } x[N-1-j][k]=x[N-j-1][k]-x[N-1-j][k]*a[N-1-j][N-j]/a[N-j][N-j]; } //3回目 for(i=1;i<=N-1;i++){ x[i][k]=x[i][k]/a[i][i]; } //答え出てきたら //ファイルに結果放り込む※時間変化表示 n x t for(i=0;i<=N;i++){ fprintf(fp,"%d %10.5fl %d\n",i,x[i][k],k); //printf("%d %10.7g %d\n",i,x[i][k],k); } //出てきたxを次の時間用に入れなおし for(i=0;i<=8;i++){ x[i][k+1]=x[i][k]; } }//kの繰り返し終了 fclose(fp); return 0; }

  • C言語のコードについて

    C言語の問題なのですか、作成したのですが内容がわからないです。 コードをわかりやすく解説していただけると嬉しいです。 #include <stdio.h> void printBinary(unsigned char num) { int i ; /*①上位ビットから順に表示する*/ for(i = 7 ; i >= 0; i--) { /*②シフトとマスクを使用しています。*/ printf("%d", (num>>i) &0x01 ); } printf("\n"); } int main(void) { unsigned char num1 = 0xD2;/*11010010*/ unsigned char num2 = 0x5E;/*01011110*/ printf("0xD2 : "); printBinary(num1); printf("0x5E : "); printBinary(num2); return 0; }

専門家に質問してみよう