文字配列のswap関数とマクロ関数

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Ohagi
記事: 31
登録日時: 3年前

文字配列のswap関数とマクロ関数

#1

投稿記事 by Ohagi » 3年前

文字配列のswap関数とポインタの関係がわかりません。

コード:

#define swap(type, x, y) do { type t = x; x = y; y = t; } while (0)
参考書では上のようなスワップ関数が紹介されていましたが
これをマクロ関数ではなく普通の関数として書くとうまくスワップされません。

コード:

#include <stdio.h>

void swap(char *s1, char *s2)
{
  char *t = s1;
  s1 = s2;
  s2 = t;
}

int main(void)
{
  char *str[2] = {"windows", "linux"};
  swap(str[0], str[1]);
  return 0;
}


これにアドレス演算子を足してみると問題なくスワップされるのですがよくわかりません。

コード:

#include <stdio.h>

void swap(char **s1, char **s2)
{
  char *t = *s1;
  *s1 = *s2;
  *s2 = t;
}

int main(void)
{
  char *str[2] = {"book", "helm"};

  swap(&str[0], &str[1]);
  
  return 0;
}

1.
マクロ関数をそのまま?書き写した関数の挙動が違う理由

2.
コード3のswap(&str[0], &str[1]);は画像でいうbの値をスワップしていますよね?
ではコード2のswap(str[0], str[1])はどこの値をスワップしているのでしょうか? a?
画像のaをスワップしても結果的にはスワップされていそうな気がするのですがわかりません...

画像

box
記事: 1738
登録日時: 8年前

Re: 文字配列のswap関数とマクロ関数

#2

投稿記事 by box » 3年前

kazuki2655 さんが書きました: これにアドレス演算子を足してみると問題なくスワップされるのですがよくわかりません。
入れ替えた後の結果を出力していないので、本当に問題ないのかどうかよくわかりません。
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

アバター
みけCAT
記事: 6216
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: 文字配列のswap関数とマクロ関数

#3

投稿記事 by みけCAT » 3年前

kazuki2655 さんが書きました:1.
マクロ関数をそのまま?書き写した関数の挙動が違う理由
マクロは文字列(正確にはトークン列)の「コピペと引数の置換」で書かれた場所に「展開」されるが、
関数は(少なくともソースコードレベルでは)「展開」のようなことは起こらず、呼び出し元とは分離されたスコープを持つためです。
kazuki2655 さんが書きました:2.
コード3のswap(&str[0], &str[1]);は画像でいうbの値をスワップしていますよね?
ではコード2のswap(str[0], str[1])はどこの値をスワップしているのでしょうか? a?
呼び出し元からコピーされた仮引数s1とs2の値をスワップしています。
コピーの値を変更しても、コピー元のstrの要素への影響はありません。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6216
登録日時: 8年前
住所: 千葉県
連絡を取る:

Re: 文字配列のswap関数とマクロ関数

#4

投稿記事 by みけCAT » 3年前

オフトピック
box さんが書きました:
kazuki2655 さんが書きました: これにアドレス演算子を足してみると問題なくスワップされるのですがよくわかりません。
入れ替えた後の結果を出力していないので、本当に問題ないのかどうかよくわかりません。
問題ないのかどうかを知りたいなら、入れ替えた後の結果を出力すればいいでしょう。
例えば、デバッガを用いて出力させる方法が考えられます。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

Ohagi
記事: 31
登録日時: 3年前

Re: 文字配列のswap関数とマクロ関数

#5

投稿記事 by Ohagi » 3年前

マクロは文字列(正確にはトークン列)の「コピペと引数の置換」で書かれた場所に「展開」されるが、
関数は(少なくともソースコードレベルでは)「展開」のようなことは起こらず、呼び出し元とは分離されたスコープを持つためです。
マクロの基本的な部分が頭から抜けていました。
ありがとうございます。
呼び出し元からコピーされた仮引数s1とs2の値をスワップしています。
コピーの値を変更しても、コピー元のstrの要素への影響はありません。
配列の先頭文字を渡して仮引数でシャッフルしていただけだったのですね。
改めて指摘を受けてわかったような気がします。
ありがとうございました。

box
記事: 1738
登録日時: 8年前

Re: 文字配列のswap関数とマクロ関数

#6

投稿記事 by box » 3年前

みけCAT さんが書きました: 問題ないのかどうかを知りたいなら、入れ替えた後の結果を出力すればいいでしょう。
まさにそこ!デバッガーなんて七面倒くさい手段を使わずとも、入れ替えた直後にprintfするか何かして、
問題があるのかないのかなんで確認してないんだろう?って思ったしだいです。
ふつうしますよね?
バグのないプログラムはない。
プログラムは思ったとおりには動かない。書いたとおりに動く。

閉鎖

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