0
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

int myatoi(const char* string) {
  int i = 0;
  while (*string) {
    i = (i << 3) + (i<<1) + (*string -'0');
    string++;
  }
  return i;
}

void decimal2binary(char *decimal, int *binary) {
  decimal = malloc(sizeof(char) * 32);
  long int dec = myatoi(decimal);
  long int fraction;
  long int remainder;
  long int factor = 1;
  long int fractionfactor = .1;
  long int wholenum;
  long int bin;
  long int onechecker;
  wholenum = (int) dec;
  fraction = dec - wholenum;

  while (wholenum != 0 ) {
    remainder = wholenum % 2;  // get remainder
    bin = bin + remainder * factor;  // store the binary as you get remainder
    wholenum /= 2;  // divide by 2
    factor *= 10;  // times by 10 so it goes to the next digit
  }
  long int binaryfrac = 0;
  int i;
  for (i = 0; i < 10; i++) {
    fraction *= 2;  // times by two first
    onechecker = fraction;  // onechecker is for checking if greater than one
    binaryfrac += fractionfactor * onechecker;  // store into binary as you go
    if (onechecker == 1) {
      fraction -= onechecker;  // if greater than 1 subtract the 1
    }   
    fractionfactor /= 10;
  }

  bin += binaryfrac;
  *binary = bin;
  free(decimal);
}

int main(int argc, char **argv) {   
  char *data;
  data = malloc(sizeof(char) * 32);
  int datai = 1;
  if (argc != 4) {
    printf("invalid number of arguments\n");
    return 1;
  }
  if (strcmp(argv[1], "-d")) {  
    if (strcmp(argv[3], "-b")) {
      decimal2binary(argv[2], &datai);
      printf("output is : %d" , datai);
    } else {
      printf("invalid parameter");
    }
  } else {
    printf("invalid parameter");
  }
  free(data);
  return 0;
}

この問題では、問題なくmyatoi動作し、decimal2binaryアルゴリズムは正しいのですが、コードを実行するたびに出力が 0 になります。理由はわかりません。ポインターの問題ですか?変数データのアドレスを設定しましたが、出力は変わりません。

./dec2bin "-d" "23" "-b"
4

4 に答える 4

1

この線:

long int fractionfactor = .1;

変数が整数として定義されているため、に設定fractionfactorされます。代わりにor0を使用してみてください。floatdouble

同様に、

long int dec = myatoi(decimal);

整数値を格納するため、wholenum不要です。


それ以外の

i = (i << 3) + (i<<1) + (*string -'0');

コードははるかに読みやすくなります

i = i * 10 + (*string - '0');

そして、今日の最適化コンパイラでは、両方のバージョンが同じオブジェクト コードを生成する可能性があります。一般に、特にコードが機能していない場合は、最適化よりも読みやすさを優先してください。


fraction *= 2;  // times by two first

コードを英語に翻訳するだけのこのようなコメントは、その言語を通常とは異なる方法で使用していない限り不要です。読者はその言語に精通していると想定できます。代わりに、理由を説明する方がはるかに役に立ちます。

于 2012-11-07T06:23:49.447 に答える
0

別のコーディングのヒント:書く代わりに

if (strcmp(argv[1], "-d")) {  
  if (strcmp(argv[3], "-b")) {
    decimal2binary(argv[2], &datai);
    printf("output is : %d" , datai);
  } else {
    printf("invalid parameter");
  }
} else {
  printf("invalid parameter");
}

ネストされたifブロックをリファクタリングして、それらをより単純で理解しやすくすることができます。一般に、エラー状態を早期にチェックし、エラーチェックをコア処理から分離し、ユーザーがエラーを修正する方法を理解できるように、エラーをできるだけ具体的に説明することをお勧めします。

これを行うと、元の条件の両方を無効にする必要があることを理解しやすくなる場合もあります。

if (strcmp(argv[1], "-d") != 0) {  
  printf("Error: first parameter must be -d\n");
else if (strcmp(argv[3], "-b") != 0) {
  printf("Error: third parameter must be -b\n");
} else {
  decimal2binary(argv[2], &datai);
  printf("Output is: %d\n" , datai);
}
于 2012-11-07T23:29:09.287 に答える
0
if(!strcmp(argv[3] , "-b"))

if(!strcmp(argv[3] , "-d"))

続行できるように、文字列比較関数の結果を否定する必要があります。それ以外の場合、無効なパラメーターが出力されます。文字列が等しい場合、strcmp は「0」を返すためです。

「decimal2binary」関数では、入力パラメータ「decimal」の関数内に新しいメモリ ブロックを割り当てています。

decimal = malloc(sizeof(char) * 32);

これにより、入力パラメーター データが実際に上書きされます。

于 2012-11-07T06:29:14.663 に答える
0
void decimal2binary(char *decimal, int *binary) {
  decimal = malloc(sizeof(char) * 32);
  ...
}

上記のコード行は、メモリの新しいブロックを に割り当てdecimalます。これは、入力データを指しなくなります。次に、ライン

long int dec = myatoi(decimal);

新しく割り当てられたメモリ (のランダムな値) を に割り当てますdec

だから、行を削除します

decimal = malloc(sizeof(char) * 32);

そして、あなたは正しい答えを得るでしょう。

于 2012-11-07T07:10:47.030 に答える