常量与变量
1.常量
常量与变量一样都需要用一个名字将一个特定类型的值联系起来,这个过程叫做常量的定义,在给常量定义的时候需要用到关键字let,常量被定义之后值是无法改变的。
let constant = 5
constant = 6 //这里如果给常量重新赋值就会报错
2.变量
变量顾名思义是一个可以被改变的值,它也需要被定义,定义的方式也多种多样。
//可以直接给变量x一个类型,再给它赋值
var x:Int
x = 1
//Swift语言是拥有强大类型推断的功能,只需要在定义的时候给它赋值,就能推断出该变量的类型
var y = 1 //这样就定义了一个Int类型,值为1的变量
//如果要定义多个相同类型的变量,也可以这样定义
var x,y,z:Int
var a = 0,b = 0,c = 0
a = 3 //变量就可以给它重新赋值,但是只能赋一个与定义的类型相同的值,这是Swift中类型安全特性所决定的
3.常量与变量的标识符
标识符通俗的来讲就是常量与变量的名字,通过标识符能够对常量与变量进行操作处理,而标识符的命名也有很多特性和规则,包含了所有的Unicode特性,例如:
let π = 3.14159
let 你好 = "世界" //这里不仅能中文,几乎世界上所有的主流文字都可以命名。
虽然标识符的命名有很多特性,但是命名的同时也需要遵循以下规则:
1.字符(nuicode字符) 数字 下划线 数字不能开头 强烈建议使用英文字符
2.大小写敏感
3.不能使用关键字做标识符
4.驼峰标识(驼峰命名法)-第一个单词全小写,以后每个单词首字母大写
5.见名知意
前三条为必须遵守的规则,后两条如果你想成为一个优秀的程序员也必须遵循。
4.常量与变量的类型
在定义常量与变量的时候需要给它一个类型,类型种类也有多种多样。
- 整数类型有:Int8,Int16,Int32,Int,还有无符号整型:UInt8,UInt16,UInt32,UInt。
- 小数类型有Float,Double
- 字符串类型有String
- 布尔值类型Bool,在表示真假情况下使用
- 元组 用一个变量或一个常量来保存多个信息
对于这么多种类型,但是在使用的过程中只需要记住大多数情况下只使用Int,Double,String,下面是各种类型的使用,在定义之后我们可以按住alt加鼠标点击可以获取到值的类型
var a = 3 //Int类型
var b = 3.0 //Double类型
var c = "你好" //String类型
var d = true //Bool类型
var e = (1,"你好") //Tuples类型(元组)type为:(Int, String)
运算符
运算符分为一元运算符,二元运算符,三元运算符
1.一元运算符只有- +(正负号)
2.二元运算符为运算符两边都参加运算,如赋值运算符 = 、算术运算符(+-/) 、求模运算符 % 、复合运算符 += -= *= /=、还有关系运算符,也叫比较运算符 == !=等
3.三元运算符,也叫条件运算符,用于只有真假两种情况的赋值例如:
let question = true
if question {
answer1
} else {
answer2
}
//question为真a就等于answer1否则就等于answer2,注意问号前一定要空格
var a = question ? answer1:answer2
流程控制
几乎在所有的编程语言中,程序的运行流程都是由三种结构所控制的:顺序结构、分支结构、循环结构。通过这三种结构可以实现很多复杂的结构。
1.顺序结构
顺序结构就是代码自然执行顺序,也是最常见的一种结构
2.分支结构
当程序出现需要根据条件选择执行不同代码的时候,需要用到分支结构,下面就用一个输入年份来判断是否是闰年的小程序来体现分支结构的用法:
print("请输入年份:",terminator:"\t")
let year = inputInt()
//用if关键字来判断是否为闰年,后面的表达式为一个布尔值
if year % 4 == 0 && year % 100 != 0 || year % 400 == 0{
print("该年是闰年") //如果条件满足则执行该代码
}
else{
print("该年不是闰年") //否则就执行该代码
}
除了if else这种分支语句可以实现分支选择,用switch case也可以实现,下面用一个输入年月日来判断是该年的第几天来说明switch case 的用法:
//生成一个1-3的随机数来代表石头剪刀布
let computer = Int(arc4random_uniform(3)) + 1
print("石头(1)、剪刀(2)、布(3)\n")
let yournum = inputInt() //输入一个数
var msg,msg1:String
switch yournum{ //以你的数为选择条件
case 1: //yournum==1就执行以下代码与随机出来的数字通过if else来判断输赢
if computer == 1{
msg = "你出的石头,打平\n"
}
else if computer == 2{
msg = "你出的石头,你赢了\n"
}
else{
msg = "你出的石头,你输了\n"
}
case 2: //yournum == 2的时候执行
if computer == 1{
msg = "你出的剪刀,你输了\n"
}
else if computer == 2{
msg = "你出的剪刀,打平\n"
}
else{
msg = "你出的剪刀,你赢了\n"
}
case 3:
if computer == 1{
msg = "你出的布,你赢了\n"
}
else if computer == 2{
msg = "你出的布,你输了\n"
}
else{
msg = "你出的布,打平\n"
}
default: //这里就是以上情况之外才执行的,在switch 中必须写default,表示除case情况以外发生。
msg = "请输入1-3\n"
}
print(msg)
3.循环结构
循环结构可以减少源程序重复书写的工作量,用来描述重复执行某段算法的问题,这是程序设计中最能发挥计算机特长的程序结构 。下面通过各种例子来了解循环结构的使用方式:
1.找出2-10000之间的完美数字(28=1+2+4+7+14)自身等于除自身外的所有因子和
//思路:首先需要摆出一个2-10000的循环,用于完美数的本身的寻找。然后我们需要找出这个数的所有因子,也需要摆出一个循环,循环条件应该是1-这个数减1,但是这样需要的循环的次数太多,可以只找出前半段因子,循环条件为小于a开根号,减少循环次数。例如28,可以只循环到6,找出1,2,4,再用28除以1,2,4得到后半段7,14,28,如果所有因子相加等于2倍的28就为完美数,这样大大减少了循环次数。
//for循环,在2...10000里面循环,每次都加1
for a in 2...10000{
var sum = 0
var i = 1
while i<=Int(sqrt(Double(a))){
if a%i == 0 {
sum += i
if a/i != i { //通过判断是否前半段的因子等于后半段的因子
sum += a/i
}
}
i += 1
}
if sum == 2*a{ //如果所有因子加起来等于2倍的本身,该数就是完美数
print("\(a)是完美数字")
}
}
在这个程序中用到了for循环和while循环,接下来是用repeat while循环来实现一个craps小游戏。
//接下来需要摇多次骰子,将产生随机数的封装成了一个函数,直接调用就会返回一个1-6的随机数,相当于摇一次骰子
func shock () ->Int{
return Int(arc4random_uniform(6)) + 1
}
var money = 1000
//摆出一个循环repeat while 表示不管怎样都会执行一次,相当于其他语言中的do while
repeat{
print("玩家总资产\(money)")
var debt:Int
//输入赌注循环,循环条件就是while后面跟的,赌注小于0和赌注大于资产
repeat{
print("请输入赌资",terminator:"")
debt = inputInt()
}while debt <= 0 || debt > money
var needGoOn = false
var firstShock = shock() + shock()
//不管怎样都需要进行第一次的摇骰子,通过switch来选择第一次的输赢情况。
switch firstShock {
case 7,11:
print("第1次摇了\(firstShock)点,你赢了")
money += debt
case 2,3,12:
print("第1次摇了\(firstShock)点,你输了")
money -= debt
default:
print("第1次摇了\(firstShock)点,游戏继续")
needGoOn = true //第一次没有获胜,需要继续进行下面的游戏,将刚开始定义的循环条件变为true,表示需要接下来的循环
}
//num用于记录摇的次数
var num = 2
//while循环只有当一次没分出胜负后执行
while needGoOn {
let secondShock = shock() + shock()
if secondShock == firstShock{
//分出胜负后循环结束
print("第\(num)次摇了\(secondShock)点,你赢了")
needGoOn = false
money += debt
}
else if secondShock == 7 {
print("第\(num)次摇了\(secondShock)点,你输了")
needGoOn = false
money -= debt
}
else{
//这里也是没有分出胜负后循环继续
print("第\(num)次摇了\(secondShock)点,游戏继续")
}
num += 1
}
}while money > 0 //金额大于0循环才继续
在计算机的循环中我们有很多好用的方法,比如穷举法,根据题目的部分条件确定答案的大致范围,并在此范围内对所有可能的情况逐一验证,直到全部情况验证完毕。
例如:五个分鱼的问题,第一个人将鱼分为5份多了一条直接扔了,拿走了1份,第二人也将鱼分为5份也多了一条直接扔了,也拿走了1份,以此类推第五个人也将鱼分了五份,多了一条,问最少有多少条鱼。
对于这个问题,我们也完全不知道大概有多少条鱼,这里就需要用到穷举法。
var goOn = true
var num = 1
//首先需要摆出一个循环,这个循环结束条件就是找到一个数按题目的要求分5次
while goOn{
//定义一个数来记录连续分鱼的次数
var num1 = 0
var fish = num
//该循环就是分鱼的循环
for _ in 1...5{
//满足这个条件就将鱼重新赋值,同时num1也加1
if (fish-1)%5 == 0{
fish = (fish-1)/5*4
num1 += 1
}
}
//连续分鱼的次数达到5次就表示找到了满足条件的数量,循环结束
if num1 == 5{
print(num)
goOn = false
}
num += 1
}
容器类型
1.数组
数组是一组相同类型的值在一个有序列表中的集合,就是把一定数量的相同类型变量用一个名字命名,然后用编号将它们变量区分的集合,变量名就是数组名,编号就是索引。下面来列举几种创建数组的方法:
//创建一个空的数组
var someInts = [Int]()
//创建一个含有默认值的数组,count代表数组长度,repeatedValue是初始值。
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)
//创建一个数组逐个赋值
var food:[String] = ["bread","Milk"]
//还可以利用swift的类型推断
var food = ["bread","Milk"]
很多时候数组都是需要增加内容或者删除内容的,下面就是数组的增加与移除的方法:
var array = ["one","two"]
array.append("three") //直接加在数组最后一项
print(array) //打印结果为["one","two","three"]
array += ["four"] //与append的效果是一模一样的
print(array) //["one","two","three","four"]
array.insert("first", atIndex: 0) //把值插入到数组,atIndex代表插入的位置,0是数组的第一位。
//数组的移除方式有很多,下面只列举一两种
array.removeAtIndex(0)//跟插入的方法相同,但实现的操作是相反的
array.removeAll() //移除数组所有的值,清理存储空间
array.removeAll(keepCapacity: true) //保存存储空间,多用于一些移除了马上又会重新赋值的数组
数组的排序:对于一些无序的数组,根据不同的需求可能会对其进行由小到大、由大到小等排序,在Swift中对数组排序有多种方式:
1.Swift中自带的排序功能
var array = [12,556,88,11,65,32]
let array1 = array.sort(>) //括号内>代表由大到小,把排序好的数组返回给一个新的数组
array.sortInPlace() //默认为自然排序,在原来的数组上排序,所以定义的时候需要用var
2.简单选择排序
//选择最小的放到最左边,第二小的放到第二的位置,以此类推
var array = [12,556,88,11,65,32]
for i in 0..<array.count-1{
var small = i //假设最小的就是第一个
for j in i+1..<array.count
{
if array[j]<array[i]{
small = j //如果后面有比定义小的重新赋值,将最小元素的位置记录下来
}
}
//利用元组的特性直接将最小的和第i个元素交换位置。
(array[i],array[small]) = (array[small],array[i])
}
3.冒泡排序
//冒泡排序的思想是将数组中的元素从左往右两两依次比较,如果前者和比后者大则交换位置,想当于每执行一轮,则最大的数到了最右边。
var array = [12,556,88,11,65,32]
for i in 1..<array.count
{
var needGoOn = false
//循环由0到array.count-i
for j in 0..<array.count-i{
if array[j]>array[j+1]{
(array[j],array[j+1]) = (array[j+1],array[j])
needGoOn = true //只要进行了交换就赋值true,证明还需要继续
}
}
if needGoOn = false {
break //如果循环一轮依次交换都没有发生,说明数组已经有序,可以提前结束循环,优化代码
}
}
print(array)
数组的遍历:
1.只读遍历
var array = ["1","2","3"]
for i in array{ //i相当于数组的代言人,i的类型也数组元素的类型,这里为String类型
print(i)
}
2.可以操作数组元素的遍历
var array = ["1","2","3"]
for i in 0...array.count-1
{
array[i] = "5" //可以对数组元素进行操作,重新赋值
print(array[i])
}
3.迭代器遍历
var array = [12,556,88,11,65,32]
//index为数组的索引,value为索引对于的值
for (index,value) in array.enumerate()
{
print(index+1,value)
}
2.集合
集合是装一组无序排列的相同类型无重复值的容器,与数组相比,不同的是集合中没有重复的值,但是在数组中是可以有重复值的。下面是集合的基本操作:
var set:Set<Int> = [0,1,2,4,5,1,6,4]
var set1:Set<Int> = [1,5,6] //集合的定义,和数组类似但是必须再定义类型set
set.remove(2) //移除值为2的项
print(set) //结果[0,1,4,5,6]
var set1:Set<Int> = [1,5,6]
//求交集
print(set.intersect(set1))
//求并集
print(set.union(set1))
//求差集
print(set.subtract(set1))
//判断set1是否是set的子集
print(set1.isSubsetOf(set))
//set是否是set1的超集
print(set.isSupersetOf(set))
3.字典
字典是存储相同类型不同值的容器。每一个值都对应着一个键,通过这个键可以找到这个值,就像字典中每一个值都有一个标识符。和数组的元素不同的是字典的元素是没有特殊的序列。Swift的字典写法是Dictionary< KeyType,ValueType >,KeyType是你想要储存的键,ValueType是你想要储存的值。唯一的限制就是KeyType是可哈希类型(hashable),目的就是让它们自身是独立识别的。下面是字典的基本用法:
//字典的每个元素由两部分构成,冒号前面是键冒号后面是值
var dict = [1:"刘琼",2:"ss",3:"nihao"]
//通过键获取对应的值(可空类型,因为给的键有可能没有与之对应的值)
dict[4]="狗屎" //添加字典元素
dict.removeValueForKey(2) //删除某元素,2为键值
dict[3]=nil //也是删除某元素
//遍历字典的值
for value in dict.values{
print(value)
}
//遍历字典的键,通过键取值
for key in dict.keys{
print(key,dict[key]) //取出的是可空类型
}
//遍历字典的键和值
for (key,value) in dict {
print(key,value) //直接通过一个元组获得键和值
}
字典规范:
1:[ ]中由 key:value 键值对组成的
2:所有key 的类型必须一致, 所有value的类型必须一致,所有key不能重复
3:第一种格式定义的字典,是直接定义字典,第二种格式定义的数组 是编译器通过类型值推导出是字典格式
注意点:
1:常量关键字(let) 定义的字典,是不可变字典,不能做任何修改,只能访问。
2:变量关键字(var) 定义的字典 ,是可变字典,可以修改,可以访问。