{{fbdoc item="title" value="SELECT CASE"}}----
Conditional statement block

{{fbdoc item="syntax"}}##
	**Select Case** //expression//
	[ **Case** //expressionlist//] 
		[//statements//]
	[ **Case Else** ]
		[//statements//]
	**End Select**
//or//
	**Select Case** As Const //integer_expression//
	[ **Case** //constant// | //enumeration// ]
		[ //statements// ]
	[ **Case Else** ]
		[ //statements// ]
	**End Select**
##
{{fbdoc item="desc"}}
	##**Select Case**## executes specific code depending on the value of an expression. The expression is evaluated once, and compared against each ##**Case**##, in order, until a matching expression is found. The code inside the matching Case branch is executed, and the program skips down to the end of the ##**Select Case**## block. ##**Case Else**## matches any case not already matched, so if there is a ##**Case Else**##, at least one ##**Case**## is guaranteed to be executed. If no ##**Case**##s match, the whole ##**Select Case**## block will be skipped.
		
	##**End Select**## is used to close the ##**Select Case...End Select**## block.
	
	##**Exit Select**## can be used to escape the ##**Select Case**## block, preventing further code in the ##**Case**## block from being executed.
	
	Note for C users: In ""FreeBASIC"", ##**Select Case**## works like a ##switch## block where all cases have a ##break## at the end. As there is no fall-through, multiple options must be put in an expression list in a single ##**Case**##.
	
	Besides integer types, floating point and string expressions are also supported with the first syntax.  
	
	Syntax of an expression list:
	##{ //expression// | //expression// **To** //expression// | **Is** //relational operator// //expression// }[, ...]##
	
	- ##//expr//##: evaluates ##//expr//##, and compares for equality with the original expression.  If they are equal, then a match has been found.  This could be considered as a shorthand for "##**Is** = //expr//##" (see below).
	- ##//expr1// **To** //expr2//##: evaluates ##//expr1//## and checks to see if it is less than or equal to the original expression.  If so, it evaluates ##//expr2//##, and checks to see if it is greater than or equal to the original expression.  If so, then a match has been found.
	- ##**Is** //relational_operator// //expr//##: evaluates ##//expr//##, and compares the original operation against it, using the supplied ##//relational_operator//## (##=##, ##>##, ##<##, ##<>##, ##<=##, ##>=##).  If the comparison is true, then a match has been found.
	
	Multiple checks can be made in each ##**Case**##, by separating them by a comma (##,##).  Once a match is found, the program finishes its checks, and goes on to execute the code statements for that ##**Case**## block.  No further expressions are evaluated or checked.
	
	example of expression lists:
	{{table columns="2" cellpadding="1" cells="Case 1 ;constant;Case 5.4 To 10.1;range;Case Is > 3;bigger than-smaller than;Case 1, 3, 5, 7 to 9;match against a set of values;Case x ;value of a variable"}}
	
	If ##**As Const**## is used, only integer constants (all numeric constants excluding the two floating-point constants: single and double) can be evaluated and the expression list supports simple constants and enumerations only. "##**To**##" ranges are supported, but "##**Is**##" relational operators are not.
	
	With ##**As Const**##, a jump table is created to contain the full range of integer ##**Case**##s handled.  This allows ##**Select Case As Const**## to be faster than ##**Select Case**##.
	However, the size of the range of values is limited, and after converting the values to the uinteger type, the largest value in the range may be no higher than the smallest value + 8191 (current implementation).
	
	**Note:** No statement can be placed between the ##**Select Case**## statement and the first ##**Case**## statement.

{{fbdoc item="ex"}}

	{{fbdoc item="filename" value="examples/manual/control/select.bas"}}%%(freebasic)
dim choice as integer

input "Choose a number between 1 and 10: "; choice

select case as const choice
case 1
	print "number is 1"
case 2
	print "number is 2"
case 3, 4
	print "number is 3 or 4"
case 5 to 10
	print "number is in the range of 5 to 10"
case else
	print "number is outside the 1-10 range"
end select
%%
	
	{{fbdoc item="filename" value="examples/manual/control/select-speed.bas"}}%%(freebasic)
'' SELECT CASE vs. SELECT CASE AS CONST speed test

const N = 50000000

dim as integer dummy = 0
dim as double t = timer()

for i as integer = 1 to N
	select case i
	case 1, 3, 5, 7, 9
		dummy += 1
	case 2, 4, 6, 8, 10
		dummy += 1
	case 11 to 20
		dummy += 1
	case 21 to 30
		dummy += 1
	case 31
		dummy += 1
	case 32
		dummy += 1
	case 33
		dummy += 1
	case is >= 34
		dummy += 1
	case else
		print "can't happen"
	end select
next

print using "SELECT CASE: ##.### seconds"; timer() - t
t = timer()

for i as integer = 1 to N
	select case as const i
	case 1, 3, 5, 7, 9
		dummy += 1
	case 2, 4, 6, 8, 10
		dummy += 1
	case 11 to 20
		dummy += 1
	case 21 to 30
		dummy += 1
	case 31
		dummy += 1
	case 32
		dummy += 1
	case 33
		dummy += 1
	case else
		if( i >= 34 ) then
			dummy += 1
		else
			print "can't happen"
		end if
	end select
next

print using "SELECT CASE AS CONST: ##.### seconds"; timer() - t
sleep
%%

{{fbdoc item="diff"}}
	- ##**Select Case As Const**## did not exist in QB.
	- in an "##//expr1// TO //expr2//##" case, QB would always evaluate both expressions, even if ##//expr1//## was higher than the original expression.
	- In the //[[CompilerOptlang|-lang qb]]// and //[[CompilerOptlang|-lang fblite]]// dialects, variables declared inside a ##**Select**##..##**End Select**## block have a function-wide [[ProPgVariableScope|scope]] as in QB.
	- In the //[[CompilerOptlang|-lang fb]]// and //[[CompilerOptlang|-lang deprecated]]// dialects, variables declared inside a ##**Select**##..##**End Select**## block are visible only inside the block, and can't be accessed outside it. To access duplicated symbols defined as global outside this block, add one or preferably two dot(s) as prefix: ##.""SomeSymbol""## or preferably ##..""SomeSymbol""## (or only ##..""SomeSymbol""## if inside a [[KeyPgWith|With..End With]] block).

{{fbdoc item="see"}}
	- ##[[KeyPgIfthen|If...Then]]##

{{fbdoc item="back" value="CatPgControlFlow|Control Flow"}}