3
int enter_path(char** path) {
  char* standard = "./questions.txt";
   printf("\n\t%s\n\t%s",
          "Please enter the file location.", "path: ");
   fgets(*path, MAX_PATH_LENGTH ,stdin);
     *(*path + (strlen(*path)-1) ) = '\0';
   if(**path == '\n' )
     *path = strdup(standard);
   return 0;
}

int main(void){
  char* path = malloc(MAX_PATH_LENGTH);
  enter_path(&path);
  some_other_function_using_the_path_string(path);
}

上記のコードは正常に動作します。これを投稿する理由は次のとおりです。

ポインター「パス」のアドレスを関数enter_pathに渡す必要があるのはなぜですか。これにより、他の関数が変更された値を使用/読み取ることができます。つまり、「enter_path」関数を呼び出すときに &-operand を使用する必要があり、enter_path を「int enter_path(char* path);」として定義できないのはなぜですか。

これが int や long などのデータ型を参照する通常の変数であることはわかっていますが、ポインターを操作する場合、他のすべての関数で変更が表示されるはずだと思いました。ポインターがメモリ内の同じポイントを参照しているため、値が変更されているだけです。

私はこれをすべて間違って見ているのでしょうか?

PS: コードを ansi-C に準拠させるために最善を尽くしています。これが、readline の代わりに fgets を使用している理由です。readline 関数の方が使いやすい/安全であるという事実に関して、すでにいくつかのコメントを受け取っているからです。

敬具、JD

4

3 に答える 3

2

T関数で変更できるようにする型の変数がある場合は、ポインターを介して渡す必要があります。つまり、次のようになります。

void foo(T *p) { *p = 42; }

int main(void) {
    T t;
    foo(&t);
    // The value of t is now 42
}

あなたのコードでTは、ですchar *; つまり、関数はポインターを変更できる必要があるため、そのポインターへのポインターを渡す必要があります。


ただし、これは適切なコードではありません。true の場合(**path == '\n')、メモリ リークが発生します。

于 2012-06-16T11:52:37.197 に答える
1

その理由は、パラメーターの型を として指定するchar *と、関数内のポインターのコピーを操作するため、コード (このシナリオ用に変更)

path = strdup(standard);

関数の終了後に呼び出し元に反映されない

変数のアドレスを渡すことにより、ポイント先のポインターを変更できます。この変更は、関数が戻った後も保持されます。

ポインターをデータと考えてください ( などと同様int)。ポインターを渡すことで、char *ポイント先の文字を変更できます。ポインターを渡すことにより、ポイント先のchar **ポインターを変更できます (変更は呼び出し元関数にも反映されます)。

于 2012-06-16T11:51:30.687 に答える
0

pathそれ自体がポインターである変数を渡しています。ただし、関数内のポインター自体を変更しているenter_pathため、ポインターをに渡す必要があるpathため、のアドレスpathが渡されるため、&path渡されます。

現在のシナリオでは、行

*path = strdup(standard);

関数内の変数パスを変更しますが、その値は関数の外部、つまり関数 main では変更されません。

于 2012-06-16T11:58:27.790 に答える