ここから本文です

c言語プログラミングで、関数に文字型配列を渡す場合

mor********さん

2020/7/615:46:43

c言語プログラミングで、関数に文字型配列を渡す場合

関数で行った文字列への変化を、メイン関数側に影響させない方法ってありますか?
ダミーを作って、それを使う方法しかないですかね?

閲覧数:
114
回答数:
4
お礼:
50枚

違反報告

ベストアンサーに選ばれた回答

hjk********さん

2020/7/620:04:18

C言語では、すべてのものが、コピー渡しです。
そして、関数に文字型配列は、渡せているように見えますが、渡せません。
C言語は、配列型変数のコピーができないためです。

char str[] = "abc";
func(str);

とした際、strの型は、char str[4] 型で間違いありません。
しかし、func に str が渡される前に str を"評価" することによって、配列型は先頭へのポインタ型に型調整されます。
そのため、
func(&str[0])
と完全に等価です。

さて、関数側では、このポインタ &str[0] がコピーされて、
void func(char func_str[])
のポインタ型変数 func_str にコピーされます。(ここで、関数宣言における仮引数並びに、〜型への配列型は、〜型へのポインタ型にやはり型調整されるため、void func(char *func_str) と等価であることに注意)

したがって、func_str には、&str[0] がコピーされます。

その結果、func_str と str は同じ位置を指すポインタになります。

したがって、func_str = "stu" などと変更しても func_str が保持するアドレスが変化するだけで str は変わりませんが、
func_str[1] = 'z'
などとすると、str[1] == 'z' となってしまいますね。

上述のことから、関数で行った文字列への変化を、メイン関数側に影響させない方法は、

char str[] = "abc";
char copy_str = malloc(4);
strcpy(copy_str, str);
func(copy_str);


void func(const char* str)
として func は変更しないことを明示した上で、中でコピーをしてから操作する


構造体の配列型のメンバは、構造体がコピーされる時に、各要素ごとにコピーされることを利用する


などが考えられます。

質問した人からのコメント

2020/7/6 22:52:42

回答の中で、最も多かった指摘の中で、より詳しく書いてくださったのでベストアンサーとさせていただきます

ベストアンサー以外の回答

1〜3件/3件中

並び替え:回答日時の
新しい順
|古い順

2020/7/619:55:12

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

void hoge(char *p){


while(*p!=0)
{
(*p)++;
p++;
}
}



int main(void)
{

char moji[50];
char moji2[50];

strcpy(moji,"abcdefghijkl");
hoge(moji);
printf("%s\n",moji);

strcpy(moji,"abcdefghijkl");
strcpy(moji2,moji);
hoge(moji2);
printf("%s\n",moji);



return 0;
}

関数を呼び出してその文字列が破壊される物で有れば、コピーを取ってから呼び出してください。 ただ、放置しておくと問題があるので関数の制作者に、引き渡した文字列を破壊しないように頼んでみてください。

プロフィール画像

カテゴリマスター

あみやさん

2020/7/617:12:24

別の場所にコピーを作るしか無いです。

プロフィール画像

カテゴリマスター

Windcatさん

2020/7/617:11:55

普通に実態で関数に渡せばいいだけです。

例:
#include<stdio.h>

int main()
{
char str[64]={"qwerty"};

printf("str: %s\n",str);
test(str);
printf("str: %s\n",str);
return 0;
}

void test(char s[]){
printf("s[]: %s\n",s);
s = "abcdef";
printf("s[]: %s\n",s);
}

-------------------------------------------
実行結果
str: qwerty
s[]: qwerty
s[]: abcdef
str: qwerty

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる