2017-02-11 11 views
1

関数にcharポインタを渡して値を設定して戻したいと思っています。ここで私の試みですが、printfはゴミを印刷します、どこが間違っていますか?C char配列ポインタ

int a() { 
    char *p;  
    b(p);  
    printf("%s", p); 
    return 0; 
} 

int b(char * ptr) { 
    ptr = "test string"; 
    return 0; 
} 

答えて

3

ポインタへの参照を渡します。通過するの未定義の動作を避けるために、ここでp

int a(void) { 
    char *p = NULL;  
    p = b(p);  
    printf("%s", p); 
    return 0; 
} 

char * b(char * ptr) { 
    ptr = "test string"; 
    return ptr; 
} 

NULLに初期化されます:あなたは、ポインタの値を設定し、戻ってそれを渡したい場合は

int b(char **ptr) 
{ 
    *ptr = "Print statement"; 
    //your code 
} 
//call 
b(&p); 
+0

私はこれがつべこべさを知っているが、私は、'文字を変更します:機能b()ではなく、文字列リテラルで初期化、独自のポインタを宣言でき文字列。 – d3L

+0

私自身constポインタの使用に精通していないので、それを示唆することはできません。 – Pbd

+0

'' Printステートメント ''は定数文字列であり、実行可能ファイルの読み取り専用セクション内に配置される可能性が非常に高いでしょう。これを変更するとクラッシュする可能性があります。 'const char *' '' 'は文字列の変更を防ぎます。 – d3L

2

は、その後、b()は、ポインタを返す必要があります初期化されていない値を関数に渡します。 pを別の文字列リテラルに初期化することもできます。 bの内部では、ptrbに渡されたポインタpのコピーです。 ptrに格納されている値を文字列リテラル"test string"のアドレスに再割り当てすると、元のポインタpは変更されません。 ptrを呼び出し関数に戻し、pを戻り値bに再割り当てすると、呼び出し関数は更新された値を使用できます。

コメントには@M.Mが記載されていますが、これはやや冗長です。それが一定であるため、 `**のconstのchar`に `**

int a(void) { 
    char *p = b();  
    printf("%s", p); 
    return 0; 
} 

char * b(void) { 
    char *ptr = "test string"; 
    return ptr; 
} 
+0

'b'に' char * 'の戻り値を与えることを意図しています。しかし、このコードでは、関数のパラメータは冗長であり、削除する必要があります。 (実際には 'b(p)'は初期化されていないポインタ値を使って未定義の動作を引き起こします)。 –

+1

@ M.M--コメントをありがとう。私はすべてが今固定されていると思う。私は、_lvalue conversion_についてのC11§6.3.2.12は、あなたが記述する未定義の動作の関連セクションであると信じています: "lvalueが自動保存期間のオブジェクトを指定し、そのオブジェクトが初期化されていない場合...未定義。"この状況にさらに適した別の引用がある場合は、それを一緒に渡してください。 –