プログラミングをしてみると、2つの変数の値を入れ替える場面が出てくることがあります。, 何かを開発していた訳でなくても、学校の課題でも出題されることも少なくありません。この記事では2つの変数の値を入れ替える方法を紹介しています。, 2つの変数の値を入れ替える方法はいくつかありますが、まずはダメな例から見ていきましょうか。, このコードで上手くいくと思って実行してみると、a,b両方の値が10になっているのが確認できるはずです。, このように、両方の値が同じ値になってしまうので、ただ代入するコードを2行書くだけではだめなのです。, この駄目なコードについてわかったところで、ちゃんと変数の値を交換できる方法を紹介していきます。, 一時的に変数を1つ増やして、入れ替える変数のうち一つを退避させて行う方法で、数値や文字列など様々な変数の値を交換することができます。, bをaに代入してもaの値はcに入っているため、最後にcをbに代入することで値の交換が完了するのです。, よっぽどメモリの制約が厳しい場合でない限り、この方法がいいでしょう。可読性も落ちずに見やすいコートになるはずです。, やっていることはビット演算なので、加算・減算でやる方法よりも高速で、一時変数も使いません。, ただし、除算のコストがびっくりするくらい高い(最適化しないと加算の10倍くらい)関係で処理速度が非常に遅いので実用性はありません。, そこで役立つならアルゴリズム図鑑。図解を使って解説されているので、どんなプログラミング言語にも応用できます。, アルゴリズムそのものを理解することができるので、C言語ではかけるけどJavaScriptでは書けないといった問題を事前に解決できます。. for (i = 0; i < CNT; i++) swap_asm2(&a, &b); 演習4-9 読み込んだ値の個数だけ+と-を交互に表示 0以下の整数が入力されたときは、何も表示しない. googletag.defineSlot('/21812778492/blog_728x90_common_eyecatch01_adsence', [728, 90], 'div-gpt-ad-1566564252373-0').addService(googletag.pubads()); 今回は,一時変数を用いる方法や排他的論理和を用いる方法,さらにはアセンブラを用いる方法を比較し,その実行速度を調べてみました., しかし一時変数を使わずとも,ビット演算子 ^(排他的論理和:XOR)を用いることでも 演習4-3 負の値を読み込んだ時に改行文字を出力しないようにList4-5を書き換え。 新・明解C言語入門編の答え この広告は、90日以上更新していないブログに表示しています。 //-->, 通常の変数への値の代入は次のように行われます。, この時のメモリ使用状況をイメージ化したものは、次のようになります。, 同じことをポインタを使って行うと次のようになります。, (1)が実行された時にint型の変数data用のメモリ領域が確保されます。, 続いて(2)が実行されるとint型のポインタであるbuf変数用のメモリ領域が確保されます。この文は*bufがint型であることを表しています。, (3)でdata変数用のメモリ領域のアドレスがbuf変数に格納されます。単項演算子&はオブジェクトのアドレスを与えます。, そして(4)でbufポインタが指しているアドレスに対して25が書き込まれます。単項演算子*は間接演算子で、これをポインタに適用すると、そのポインタが指しているオブジェクトにアクセスできます。このようにしてdata変数に25が入ります。, ポインタの使用例としてswap関数を書いてみます。この関数はint型の2つの変数の値を入れ替えると言う関数です。, C言語では、関数に渡す引数は全て値で受渡しされます。値がコピーされて渡されるため、呼び出された関数側でパラメータの内容を変更しても、元の引数の内容を変えることはできません。, 呼び出し元の引数の値を変えたい場合には、このswap関数の使用例のようにポインタを使用します。このような例はポインタ使用法の最もポピュラーなものです。, この部分で、C言語の標準ライブラリを使用するためにヘッダをインクルードしています。, swap関数のプロトタイプ宣言です。引数の型がint型ではなく、intのポインタであることに注目してください。, main()の冒頭でint型の変数a,bを宣言し、その後、引数を取得、atoi()でint型に変換し、aとbに代入しています。, swap関数をコールします。この時引数に渡すものは変数a,b、それぞれのアドレスです。aとbの値ではないことに注意してください。swap関数本体を見てみましょう。, 渡されたa,bのアドレスをintのポインタであるxとyで受け取ります。int型の変数tmpを宣言し、その中に*xを代入します。*xはポインタxが指し示しているところの内容(すなわち変数aの内容)です。次に*xに*yを代入。*yはポインタyが指し示しているところの内容(すなわち変数bの内容)ですので、これで変数aに変数bの値が代入されました。最後に*yにtmpを代入し、これで変数bに変数aの値が代入されたことになります。, main()の最後で変数a,bの内容を出力しています。このプログラムを実行するとコマンドラインから渡した2つの引数の順番が入れ替わって表示されます。. googletag.defineSlot('/21812778492/blog_300x250_common_sidemiddle02_adsense', [[300, 250], [336, 280]], 'div-gpt-ad-1565198822157-0').addService(googletag.pubads()); int t0, t1, t2, t3, t4; var googletag = googletag || {}; 演習4-2 二つの整数値を読み込んで、小さい方の数以上で大きい方の数以下の全整数を加えた値を表示。 新・明解C言語入門編の答え この広告は、90日以上更新していないブログに表示しています。 このブログが何かのお役に立てばうれしいです。. この記事の内容は、古い内容となります。 googletag.pubads().collapseEmptyDivs(); クラスの作り方と使い方を勉強するためにカラーボールクラスを作った。 搭載エンジンはrb20de型、rb25de型、rb25det型、およびrd28型(sohc18バルブ、c34型からのキャリーオーバー)の4機種。トランスミッションは4速atのみ搭載。足回りはフロントがストラット式(4wd車はマルチリンク式)、リアがマルチリンク式。cm出演は俳優の 佐藤浩市(ブランド終了まで。 … __asm { fatal:... WSLでGUIアプリ実行エラー:Error: Can't open display:の対処法. titleに設定した文字列をStringクラスのcharAtで一文字ずつ先頭から取り出し、画面に表示している。 Bash on WindowsのUbuntuでapt installできないときの対処法. printf("SWAP_ASM2\t: %d\tms\n", t4 - t3); MOV ECX, [EDX] ¨ã€€ãƒªãƒ³ã‚¯é›†, 呼び出すときに型を指定すれば、型の違いも吸収できる, プリプロセスでの処理になるので、実引数の与え方など、注意が必要. (一部のHTMLタグを使うことができます。) MOV EAX, [EBX] google_ad_height = 90; MOV [EDX], EAX Copyright © 2011-2020 ほくとのぶろぐ All rights Reserved. }, 確かにその通りですね. 好きな食べ物はトマトです。 unsigned int i; ポインタの利用例として作った関数。mainで宣言した2つの変数内容を入れ替える関数swapの作成。swap.c実行結果a = 20b = 10関数swap実行後、変数aとbの内容が入れ替わっている。 JavaScriptの場合は、function記述でクラスとなる。 googletag.enableServices(); googletag.defineSlot('/21812778492/blog_728x90_common_overlay', [728, 90], 'div-gpt-ad-1584694002281-0').addService(googletag.pubads()); printf("SWAP_XOR\t: %d\tms\n", t1 - t0); 新・明解c言語入門編の答え 新・明解c言語入門編の答えや情報技術について個人的にただ書いていくだ … pbjs.que=pbjs.que||[]; git clone git://git.drogon.net/wiringPi ... JavaScriptでsetTimeout関数の使い方サンプルを作った。 googletag.defineSlot('/21812778492/blog_728x90_common_overlay_adsence', [728, 90], 'div-gpt-ad-1583302554779-0').addService(googletag.pubads()); プログラムに関して最終的に変数btcには、整数値としてビットコイン価格が取得される。もし、小数点以下も含めた実数で取得したい場合は、btc ... スーパーで買ったニュージーランド産のカボチャの種を土に埋めたら、みるみる大きくなった。花も咲き、実もつけているようだ。「種」というプログラムは素晴らしい。. pbjs.setConfig({bidderTimeout:2000}); }, はじめにアセンブラを用いない,純粋なC言語のみを用いた方法を比べてみると,XOR を用いる方法は,一時変数を用いる方法のおよそ倍の時間がかかってしまいました., このことより,可読性の観点からも実行速度の観点からも,一時変数を用いる方法の方が優れていることがわかりました., XOR の方法が遅い原因としては,一時変数の方法では代入を3回繰り返すだけなのに対し,XOR の方法では,ビット演算3回と代入を3回行っているからだと考えられます., アセンブラの XOR の方法では,一時変数を用いる方法よりもやや実行速度が優れていました.流石アセンブラというべきでしょうか., おそらく,一時変数の方法よりもメモリアクセスの回数が減っているからではないでしょうか(あまり確証は持てませんが)., アセンブラの XCHG を用いる方法では,アセンブラの XOR の方法よりもさらにやや早くなっています., これは,XOR は 1 クロック命令で3回実行しているので 3 クロック,XCHG 命令は EAX レジスタを用いる場合 2 クロック命令であり,XOR の方法よりも 1 クロック短いことが影響しているのではないかと考えられます., C言語のみでの XOR による方法では,変数を1つ節約できるものの,組み込み開発などの特殊な環境を除けば変数1つの大きさが問題となることは考えられにくく,実行速度や可読性の観点から言っても XOR による方法を用いる理由はほぼないと考えられます., アセンブラを用いる方法では,確かにやや実行速度が改善されるものの,可読性が低下され,他の人が読むことになったとき,その人もアセンブラが使えるとは限らないので,よほどの高速化を望まない限りはあまり積極的に採用する理由はなさそうです., 結局,C言語で変数の値を交換(Swap)するには,無難に一時変数を用いるのがよいと思われます., void swap_asm3(int *a, int *b) { googletag.pubads().setTargeting('blog_type', 'Tech'); JavaScriptで「キーイベント」「マウスイベント」「加速度センサーイベント」を取得するプログラムのシンプルなひな形を作った。 googletag.defineSlot('/21812778492/blog_300x250_common_sidetop01_adsense', [[300, 250], [336, 280]], 'div-gpt-ad-1565330658303-0').addService(googletag.pubads());