//: Playground - noun: a place where people can play
import UIKit
var str = "Hello, playground"
//位运算符
//UInt8,将十进制数以二进制的方式赋值,UInt8类型是8位无符号整型,也就是说,任何一个UInt8类型的变量都是采用8个二进制位来存储数据的。因此下面的a变量的实际存储数据为0b00000111。位运算的实质就是对数据的每一个二进制位进行逻辑运算
var a:UInt8 = 0b111
a = 0b100
//~取反,&位与,|位或,^异或,<<左移,
a = ~a //00000100 ->11111011 255-4 = 251
a = 0b1001 & a //11111011 & 00001001 = 00001001 ->9
a>>1 // 00001001 >>1 = 00000100 ->4
a<<1 //00001001 <<1 = 00010010 ->18
a = a<<1 // 18
//注意,进行按位左移或右移运算的时候,有可能出现丢失数据位的情况,例如对于UInt8类型,将 00001111 向左移6位,变成了 110000000
//溢出运算符
//在Swift语言注重安全性,在编写代码时,如果出现了数据溢出,会直接出现运行时报错。而溢出运算符这种设计将代码的不确定性降低了许多。所谓溢出,就是超出数据类型的最大值或者最小值,以UInt8为例,最大值为255,加1就会溢出
/*
var b:UInt8 = 255
b=b+1
error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
*/
//如果需要溢出操作,就要使用溢出操作符&
var b:UInt8 = 255
b = b &+ 1 //支持溢出的加操作后,b的值为0
b = b &- 1 //255
b = b &* 2 //乘操作
//注意:对于二进制数据进行乘2运算,实质就是对二进制数据进行左移一位的运算。例如二进制数据 11111111*2 = 1111110
//运算符的重载与自定义
//定义一个形状枚举
enum Shape{
case circle(center:(Double,Double),radius:Double)//通过圆心和半径创建圆形
case rect (width:Double,height:Double,center:(Double,Double))//设置矩形的宽、高、中心点
case trangle (point1:(Double,Double),point2:(Double,Double),point3:(Double,Double))//三角的三个角点
}
//这样在创建的时候,直接提供所需的参数即可
var circle = Shape.circle(center: (20, 20), radius: 20)
var rect = Shape.rect(width: 10, height: 10, center: (40, 40))
var trangle = Shape.trangle(point1: (20, 20), point2: (50, 90), point3: (30, 50))
//在switch-case结构语句中,匹配到枚举后,可以通过参数捕获的方式来获取枚举实例的相关值
func shapeFunc(param:Shape){
switch param {
case let .circle(center,radius):
print("圆形:中心点\(center),半径\(radius)")
case let .rect(center,width,height):
print("矩形:中心\(center),宽度\(width),高度\(height)")
case let .trangle(point1, point2, point3):
print("三角的顶点:\(point1)、\(point2)、\(point3)")
}
}
shapeFunc(param: circle)
shapeFunc(param: trangle)
shapeFunc(param: rect)
//递归枚举
/*
递归是一种代码算法技巧,递归算法的效率十分高,但是其性能资源的耗费也十分严重。函数的功能是进行数据计算,递归函数只是使用递归的算法来进行数据的计算。枚举的功能是数据的描述。因此,递归枚举的作用就是使用递归的方式来进行数据描述。
*/
//使用枚举模拟加减乘除四则运算
enum Expression {
// 描述单个数字
case num(param:Int)
// 表示加法,将Expression作为相关值参数类型,使用indirect关键字修饰的枚举值表示这个枚举是可递归的
indirect case add(param1:Expression,param2:Expression)
indirect case sub(param1:Expression,param2:Expression)
indirect case mul(param1:Expression,param2:Expression)
indirect case div(param1:Expression,param2:Expression)
}
//运算((5+5)*2-8)/2
var num5 = Expression.num(param:5)
//5+5
var num55 = Expression.add(param1: num5, param2: num5)
//2
var num2 = Expression.num(param: 2)
//(5+5)*2
var numMul = Expression.mul(param1: num55, param2: num2)
//8
var num8 = Expression.num(param: 8)
// -8
var numsub8 = Expression.sub(param1: numMul, param2: num8)
// /2
var resultNum = Expression.div(param1: numsub8, param2: num2)
//这样result就是对((5+5)*2-8)/2的描述,在开发中要将描述和运算结合,能够编写出优美的代码,处理递归枚举通常采用递归函数,这样就可以通过描述的表达式进行计算
func ExpressionFunc(param:Expression) -> Int{
switch param {
case let .num(param):
return param
case .add(let param1, let param2):
return ExpressionFunc(param: param1)+ExpressionFunc(param: param2)
case .sub(let param1, let param2):
return ExpressionFunc(param: param1) - ExpressionFunc(param: param2)
case .mul(let param1, let param2):
return ExpressionFunc(param: param1) * ExpressionFunc(param: param2)
case .div(let param1, let param2):
return ExpressionFunc(param: param1) / ExpressionFunc(param: param2)
}
}
print(ExpressionFunc(param: resultNum))//最后的计算结果是6
//1、模拟C语言通过自定义运算符的方式实现前缀自增、前缀自减、后缀自增、后缀自减
prefix operator ++ //声明前缀++
postfix operator ++ //声明后缀++
prefix operator -- //声明前缀--
postfix operator -- //声明后缀--
prefix func ++ (param:inout Int ) ->Int{
param += 1
return param
}
prefix func -- (param: inout Int)->Int{
param -= 1
return param
}
postfix func ++(param: inout Int)->Int{
param += 1
return param - 1
}
postfix func -- (param: inout Int ) -> Int{
param -= 1
return param + 1
}
var a2 = 5
print(a2++)
//2、Swift语言中的加法运算符不能支持对区间范围的相加操作,重载加法运算符,使其支持区间的追加,例如(0...5)+6后的计算结果为区间0...11
func + (param:ClosedRange<Int>,param2:Int)->ClosedRange<Int>{
return param.lowerBound...param.upperBound+param2
}
var newRange = 0...5+6 //0...5 ->param,6->param2
print(newRange)//0...11
//3、自定义阶乘运算符
postfix operator *!
postfix func *! (param:Int)->Int{
if param <= 0 {
return 0
}
var tem = param
var result = 1
while tem>1 {
result *= tem
tem -= 1
}
return result
}
print(5*!)