- ベストアンサー
初心者が引数を渡せない文字列出力プログラムを作成する方法
- 初心者が引数を渡せずに文字列出力プログラムを作成する方法を教えてください。
- 引数を渡せない文字列出力プログラムを初心者が作成する方法を教えてください。
- 初心者が引数を指定できない文字列出力プログラムを作成する方法を教えてください。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
前回の回答の補足についての回答です。 関数でポインタを渡す時の注意点です。 char str[50]; とした場合、 1.void func(char* p); // 関数呼び出しは、func(str); 2.void func(char*& p); // 関数呼び出しは、func(str); 3.void func(char** p); // 関数呼び出しは、func(&str); この3つの違いは分かりますでしょうか? 1.は、ポインタの値渡しです。 2.は、ポインタの参照渡しです。 3.は、ポインタのポインタ渡しです。 1.では、ポインタが指しているデータへのアクセスと変更をすることが可能ですが、 ポインタの値そのものを変更することはできません。 これに対し、2.3.では、ポインタの値を変更することが可能です。 上記を踏まえて次を考えてみて下さい。 char* name_main = NULL; とします。 set_name(name_main); で関数にname_mainを渡す場合を考えてみて下さい。 void set_name(char *name) { const char* str = "yamada taro"; name = (char*)malloc(50); // ↑ここで、nameのポインタの値が変更されます。 // しかし、nameは、値渡しされていますので、その変更された値は、 // 関数の呼び出し元へは反映されません。 // さてどうすれば良いでしょうか? strcpy( name, str ); } 答え、void set_name(char *& name) になります。
その他の回答 (4)
- Tacosan
- ベストアンサー率23% (3656/15482)
C なのか C++ なのかを区別する必要はありますが>#4, C++ としてもおかしい部分があります. char str[50]; とした場合、 1.void func(char* p); // 関数呼び出しは、func(str); 2.void func(char*& p); // 関数呼び出しは、func(str); 3.void func(char** p); // 関数呼び出しは、func(&str); と書いていますが, str の型を考えれば 2 や 3 が不正な呼び出しであることはほぼ自明です. str の型は char * ではないことに注意. 本題に関していえば, ポインタを使ってるから勘違いするのかもしれんけど本質的に #include <stdio.h> void foo(int x) { x = 50; } int main() { int a = 100; foo(a); printf("a = %d\n", a); return 0; } と同じ. main で表示される a の値は 50 でしょうか, それとも 100 でしょうか?
お礼
ご回答いただきありがとうございます。 分かりやすい例を挙げていただきありがとうございます。 変数の値を関数に渡して、それを更新してしまったために 思った結果が出なかったということですね。 とても勉強になりました。ありがとうございました。
- mi65536
- ベストアンサー率100% (6/6)
何点か問題があると思います。 とりあえず、set_name()関数を次の様にすると、とりあえず、出力はできると思います。 void set_name(char* name) { const char* str2 = "yamada taro"; strcpy(name, str2); } あと、malloc()を使用する場合ですが、 str = malloc() でメモリーを確保した場合、 free(str) で解放する必要があります。
補足
ご回答いただきありがとうございました。 おっしゃるとおり、freeやその他諸々ができていませんでした。 初歩的なミスでお手を煩わせてしまい、申し訳ございませんでした。 下記のように直したところ、正常に動作しました。 ここで一つ追加で質問させてください。 set_name内でmallocを使用して、 name = (char*)malloc(50) として実行してもやはり動作しませんでした。 この関数の場合、引数のnameをmallocする必要ないのでしょうか? また、mallocを使うとするとどんな書き方があるのでしょうか? たびたび質問してしまい、申し訳ございません。ご回答いただけたら 幸いです。 ***修正ソース*** int _tmain(int argc, _TCHAR* argv[]) { char name[50]; set_name(name); printf( "セットされている名前は%sです", name ); return 0; } void set_name(char *name) { const char* str = "yamada taro"; strcpy( name, str ); }
- yuipu
- ベストアンサー率38% (18/47)
set_name() は 一応ポインタを受け取っていますが、結局は自分のローカル変数の str と str2だけをいじっていて引数に対して何もしてませんよね。 memcpy( name, str2, 50) とすれば動きますが、かなり危ないコードです。 50って暗黙の了解だし。 でも、いろいろ経験するのはいいかもしれませんね。いじわるじゃなくって。
お礼
おっしゃる通り、仮引数を使用していませんでした。 初歩的なミスにお手を煩わせてしまい、申し訳ございませんでした。 いろいろ試してみて、失敗も含め積み重ねていきたいと思います。 ご指摘していただきありがとうございました。
- hashioogi
- ベストアンサー率25% (102/404)
関数set_nameに仮引数nameがあります。 この仮引数はset_nameからtmainが名称を受け取るためのものと想像されますが、関数set_nameの内部でnameが使用されていないのでtmainに名称が渡りません。
お礼
ご回答いただきありがとうございます。 おっしゃる通り、仮引数を使用していませんでした。 初歩的なミスにお手を煩わせてしまい、申し訳ございませんでした。 また、ご指摘していただきありがとうございました。
お礼
ご回答いただきありがとうございます。 丁寧に説明していただきありがとうございます。 データへのポインタを更新してしまったために、 関数呼び出し後に反映されなかったのですね。 とても勉強になりました。ありがとうございました。