case文で範囲指定を使用する

 caseラベルにおいて連続した値の範囲を指定することができます.

  case low ... high:

 この例は,low以上high以下の個々の整数値について,個別にcaseラベルを記述するのと同等の効果をもちます.これは便利に使用できると思います.ANSI Cの仕様にこだわらないならば,可搬性を犠牲にして,可読性を取るのも良いと思います.

 リスト25リスト28に示すように,case文で範囲指定を使用したほうが可読性も上がり,またアセンブラからわかるように速度も改善されると思います.

 もっとも,リスト29のような条件の場合には,default文を使ったほうがコードは小さくなります.ただし,この記法では,dataの値が2,3,4,5の場合に何をするのかが一目ではわかりません.

〔リスト29〕default文を使った例test64.c)
	#include <stdio.h>
	int main(void)
	{
	 int temp;
	 int data;
	 switch  ( data )
	 {
	  case 1:
	   temp = 5;
	   break;
	  case 6:
	   temp = 10;
	   break;
	  default:
	   temp = 9;
	 }
	 return;
	}	

共用体へのキャスト

 以下のような定義があるとします.

  union foo { int i; double d; };
  int x;
  double y;,

 この場合,

(1) u = (union foo) x
(2) u.i = x
(3) u = (union foo) y
(4) u.d = y

の(1)と(2),(3)と(4)が等価になります.

 共用体へのキャストを関数への引き数として使うことも可能です.この仕様は,生成関数式から派生しています.これを使うことは,可読性という面に関しては有益でしょう.

 リスト31リスト34に例を示します.アセンブラを比較すると,微妙にANSI C準拠のコードのほうがコンパクトになっています.共用体へのキャストを使用したほうのアセンブラで,1行増えた原因となっているコード,

  movl %edx,-4(%ebp)

は不要であるような気がします.これは,最適化したら改善されました(リスト35).

〔リスト35〕最適化してアセンブルした結果test67.s)
	 .file "test67.c"
	 .version "01.01"
	gcc2_compiled.:
	 .comm x,4,4
	 .comm y,8,8
	.text
	 .align 4
	.globl main
	 .type  main,@function
	main:
	 pushl %ebp
	 movl %esp,%ebp
	 movl $10,x
	 movl %ebp,%esp
	 popl %ebp
	 ret
	.Lfe1:
	 .size  main,.Lfe1-main
	 .ident "GCC: (GNU) 2.95.3 20010315 (release)"	

Copyright 2003 岸 哲夫

Copyright 1997-2017 CQ Publishing Co.,Ltd.

 

NEW記事内インデックス    連載インデックスはこちら   Interfaceのトップ
可変長自動配列
可変個数の引き数を受け取ることができるマクロ /左辺値ではない配列の添字が存在/voidポインタと関数へのポインタの算術演算/非定数による初期化/生成関数式/配列の初期化について
◆case文で範囲指定を使用する/共用体へのキャスト
関数属性の宣言