2

より明確になるようにコードが書き直されました

void indexe(char * line, unsigned ref) {
  unsigned i = 0;
  char word[128];  //(1)
  //char * word;   //(2)
  while(*line) {
    if(isalpha(*line))
      word[i++] = *line;  //(1)
      //*word++ = *line;  //(2)
    *line++;
  }
}

int main(int argc, const char * argv[]) {
  char line[128];
  FILE * f = fopen(argv[1], "r");
  unsigned x = 0;
  while (fgets(line, 128, f)){
    indexe(line, ++x);
  }
  fclose(f);
  return 0;
}

こんにちは、私は上記の2つの組み合わせを試しました。

  1. word []-> word [i ++]
  2. * word-> * word ++

EOFに到達する場合を除いて、すべてが問題なく機能します。この場合、ポインター構文はセグメンテーション違反で失敗しますが、配列構文は失敗しません。

私はCの完全な初心者ですが、誰かがここで何が起こっているのかを初心者の言葉で説明し、ポインター構文を修正するための解決策を提案できますか?(しかし、ほとんど説明してください)

4

2 に答える 2

1

投稿されているこのバージョンは問題ありません。

void indexe(char * line, unsigned ref) {
  unsigned i = 0;
  char word[128];  //(1)
  //char * word;   //(2)
  while(*line) {
    if(isalpha(*line))
      word[i++] = *line;  //(1)
      //*word++ = *line;  //(2)
    *line++;
  }
}

ただし、代わりに//(2)とマークされた行を使用するようにコードを推奨すると、次のようになります。

char * word;   //(2
*word++ = *line;  //(2)

これは、割り当てられたメモリで初期化していないポインタに書き込む場合です。これは許可されていません。アレイとして保持するか、mallocストレージを予約するようなものを使用する必要があります。配列をまったく使用せずに関数を記述したい場合、コードは次のようになります。

char *word = malloc(128);    // reserve 128 bytes 
if (word == NULL) {          // these checks are important
   fprintf(stderr, "Cannot allocate memory!");
   exit(EXIT_FAILURE);
}
...other stuff...
free(word);

また、次の点にも注意してください。

*line++;

インクリメントlineしますが、理由もなく(インクリメントされる前に)逆参照します。

于 2013-03-14T21:29:20.820 に答える
0

ポインタを定義したchar * word;が、データを指すように設定していないため、ポインタ構文は失敗します。ポイントしているメモリはどこにあってもかまいません。したがって、次のステートメントを実行すると、次のようになります。

*word++ = *line;

lineが指す値を。が指す値に格納していますwordword残念ながら、どこを指しているのかわかりません。@teppicが指摘したように、割り当てられたメモリに初期化されていないポインタに書き込んでいます。

@teppicが以前に指摘したように、そのメモリをmallocすることができます。次のこともできます。

char reserve[128];
char * word = reserve;  // could also have used &reserve[0]

お役に立てば幸いです。

于 2013-03-15T00:33:42.783 に答える