ポインタによる文字列の入れ替え

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
そら豆

ポインタによる文字列の入れ替え

#1

投稿記事 by そら豆 » 9年前

2つの文字列を入れ替え、その内容を出力するプログラムを作成したいです。
以下のプログラムを実行しましたが、内容は入れ替えられませんでした。

コード:

#include <stdio.h>

void swap_str(char *x, char *y)
{
char *tmp = x;
x = y;
y = tmp;
}

int main(void)
{
char *s1 = "ABC";
char *s2 = "DEF";

printf("文字列s1は %s です。\n", s1);
printf("文字列s2は %s です。\n", s2);

swap_str(s1, s2);

printf("文字列s1と文字列s2を交換しました。\n");
printf("文字列s1は %s です。\n", s1);
printf("文字列s2は %s です。\n", s2);

return 0;
}
そこで自分で色々と調べてネット参考に改善してみたところ、以下のプログラムでは正しく実行できることを確認しました。

コード:

#include <stdio.h>

void swap_str(char **x, char **y)
{
char *tmp = *x;
*x = *y;
*y = tmp;
}

int main(void)
{
char *s1 = "ABC";
char *s2 = "DEF";

printf("文字列s1は %s です。\n", s1);
printf("文字列s2は %s です。\n", s2);

swap_str(&s1, &s2);

printf("文字列s1と文字列s2を交換しました。\n");
printf("文字列s1は %s です。\n", s1);
printf("文字列s2は %s です。\n", s2);

return 0;
}
しかし、実行は出来たのですが意味がよく分かりません。
改善前のプログラムは文字Aと文字Dのアドレスをswap関数に渡し、swap関数においてローカル変数のアドレスを入れ替えても値渡し(?)だからコピーを書き換えても元の文字は変化しない(?)。そもそも文字列リテラルはコンスタント領域にあるので文字Aと文字Dのアドレスは物理的に入れ替えられない(?)。という曖昧な理解です。

改善後のプログラムはポインタs1とポインタs2自身のアドレスを入れ替えることによってs1はDEF、s2はABCを指すようになる。よってmain関数内でswap関数にポインタs1,s2自身のアドレスを渡し、それらを入れ替えている。(尚、ポインタs1,s2はスタック領域なので変更可)…という解釈です。

(ここから質問です)
しかし、改善前のプログラムで値渡しであるから、swap関数でアドレスを入れ替えても元のs1,s2に影響ないと考えるならば改善後のプログラムでも同じ理由です上手くいかないのではないですか?
どうして改善前では上手くいかなく、改善後では上手くいくのかを教えてください。
よろしくお願いしますm(_ _)m

かずま

Re: ポインタによる文字列の入れ替え

#2

投稿記事 by かずま » 9年前

そら豆 さんが書きました: どうして改善前では上手くいかなく、改善後では上手くいくのかを教えてください。
改善前のプログラム:
 x と y を交換しているだけ
 main の s1 と s2 は交換していない

改善後のプログラム:
 *x と *y を交換している。(x と y は交換していない)
 *x とは main の s1 のこと。*y とは main の s2 のこと
 したがって、main の s1 と s2 を交換している

アバター
usao
記事: 1889
登録日時: 12年前
連絡を取る:

Re: ポインタによる文字列の入れ替え

#3

投稿記事 by usao » 9年前

よくわからなくなったら,とりあえずintで考えてみるというのはいかがでしょう.

コード:

//引数の型が int 版
void swap( int x, int y )
{
  int t = x;
  x = y;
  y = t;
}

int main()
{
  int a = 1;
  int b = 2;
  swap( a,b );  //aとbの値は入れ替わるだろうか?

  ...
}

コード:

//引数の型が int* 版
void swap( int *px, int *py )
{
  int t = *px;
  *px = *py;
  *py = t;
}

int main()
{
  int a = 1;
  int b = 2;
  swap( &a,&b );  //aとbの値は入れ替わるだろうか?

  ...
}
これの int の部分が char* になっても話は一緒でしょう.

閉鎖

“C言語何でも質問掲示板” へ戻る