常量與變量
1.常量
常量與變量一樣都需要用一個名字將一個特定類型的值聯(lián)系起來豹爹,這個過程叫做常量的定義,在給常量定義的時候需要用到關(guān)鍵字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.常量與變量的標識符
標識符通俗的來講就是常量與變量的名字使鹅,通過標識符能夠?qū)ΤA颗c變量進行操作處理揪阶,而標識符的命名也有很多特性和規(guī)則,包含了所有的Unicode特性患朱,例如:
let π = 3.14159
let 你好 = "世界" //這里不僅能中文鲁僚,幾乎世界上所有的主流文字都可以命名。
雖然標識符的命名有很多特性裁厅,但是命名的同時也需要遵循以下規(guī)則:
1.字符(nuicode字符) 數(shù)字 下劃線 數(shù)字不能開頭 強烈建議使用英文字符
2.大小寫敏感
3.不能使用關(guān)鍵字做標識符
4.駝峰標識(駝峰命名法)-第一個單詞全小寫冰沙,以后每個單詞首字母大寫
5.見名知意
前三條為必須遵守的規(guī)則,后兩條如果你想成為一個優(yōu)秀的程序員也必須遵循执虹。
4.常量與變量的類型
在定義常量與變量的時候需要給它一個類型拓挥,類型種類也有多種多樣。
- 整數(shù)類型有:Int8,Int16,Int32,Int袋励,還有無符號整型:UInt8,UInt16,UInt32,UInt侥啤。
- 小數(shù)類型有Float,Double
- 字符串類型有String
- 布爾值類型Bool,在表示真假情況下使用
- 元組 用一個變量或一個常量來保存多個信息
對于這么多種類型,但是在使用的過程中只需要記住大多數(shù)情況下只使用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.二元運算符為運算符兩邊都參加運算,如賦值運算符 = 磺芭、算術(shù)運算符(+-/) 赁炎、求模運算符 % 、復合運算符 += -= *= /=钾腺、還有關(guān)系運算符徙垫,也叫比較運算符 == !=等
3.三元運算符,也叫條件運算符垮庐,用于只有真假兩種情況的賦值例如:
let question = true
if question {
answer1
} else {
answer2
}
//question為真a就等于answer1否則就等于answer2松邪,注意問號前一定要空格
var a = question ? answer1:answer2
流程控制
幾乎在所有的編程語言中,程序的運行流程都是由三種結(jié)構(gòu)所控制的:順序結(jié)構(gòu)哨查、分支結(jié)構(gòu)逗抑、循環(huán)結(jié)構(gòu)。通過這三種結(jié)構(gòu)可以實現(xiàn)很多復雜的結(jié)構(gòu)。
1.順序結(jié)構(gòu)
順序結(jié)構(gòu)就是代碼自然執(zhí)行順序邮府,也是最常見的一種結(jié)構(gòu)
2.分支結(jié)構(gòu)
當程序出現(xiàn)需要根據(jù)條件選擇執(zhí)行不同代碼的時候荧关,需要用到分支結(jié)構(gòu),下面就用一個輸入年份來判斷是否是閏年的小程序來體現(xiàn)分支結(jié)構(gòu)的用法:
print("請輸入年份:",terminator:"\t")
let year = inputInt()
//用if關(guān)鍵字來判斷是否為閏年褂傀,后面的表達式為一個布爾值
if year % 4 == 0 && year % 100 != 0 || year % 400 == 0{
print("該年是閏年") //如果條件滿足則執(zhí)行該代碼
}
else{
print("該年不是閏年") //否則就執(zhí)行該代碼
}
除了if else這種分支語句可以實現(xiàn)分支選擇忍啤,用switch case也可以實現(xiàn),下面用一個輸入年月日來判斷是該年的第幾天來說明switch case 的用法:
//生成一個1-3的隨機數(shù)來代表石頭剪刀布
let computer = Int(arc4random_uniform(3)) + 1
print("石頭(1)仙辟、剪刀(2)同波、布(3)\n")
let yournum = inputInt() //輸入一個數(shù)
var msg,msg1:String
switch yournum{ //以你的數(shù)為選擇條件
case 1: //yournum==1就執(zhí)行以下代碼與隨機出來的數(shù)字通過if else來判斷輸贏
if computer == 1{
msg = "你出的石頭,打平\n"
}
else if computer == 2{
msg = "你出的石頭叠国,你贏了\n"
}
else{
msg = "你出的石頭未檩,你輸了\n"
}
case 2: //yournum == 2的時候執(zhí)行
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: //這里就是以上情況之外才執(zhí)行的,在switch 中必須寫default香追,表示除case情況以外發(fā)生合瓢。
msg = "請輸入1-3\n"
}
print(msg)
3.循環(huán)結(jié)構(gòu)
循環(huán)結(jié)構(gòu)可以減少源程序重復書寫的工作量,用來描述重復執(zhí)行某段算法的問題翅阵,這是程序設計中最能發(fā)揮計算機特長的程序結(jié)構(gòu) 歪玲。下面通過各種例子來了解循環(huán)結(jié)構(gòu)的使用方式:
1.找出2-10000之間的完美數(shù)字(28=1+2+4+7+14)自身等于除自身外的所有因子和
//思路:首先需要擺出一個2-10000的循環(huán),用于完美數(shù)的本身的尋找掷匠。然后我們需要找出這個數(shù)的所有因子滥崩,也需要擺出一個循環(huán),循環(huán)條件應該是1-這個數(shù)減1讹语,但是這樣需要的循環(huán)的次數(shù)太多钙皮,可以只找出前半段因子,循環(huán)條件為小于a開根號顽决,減少循環(huán)次數(shù)短条。例如28,可以只循環(huán)到6,找出1才菠,2茸时,4,再用28除以1赋访,2可都,4得到后半段7缓待,14,28渠牲,如果所有因子相加等于2倍的28就為完美數(shù)旋炒,這樣大大減少了循環(huán)次數(shù)。
//for循環(huán)签杈,在2...10000里面循環(huán)瘫镇,每次都加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倍的本身,該數(shù)就是完美數(shù)
print("\(a)是完美數(shù)字")
}
}
在這個程序中用到了for循環(huán)和while循環(huán),接下來是用repeat while循環(huán)來實現(xiàn)一個craps小游戲答姥。
//接下來需要搖多次骰子铣除,將產(chǎn)生隨機數(shù)的封裝成了一個函數(shù),直接調(diào)用就會返回一個1-6的隨機數(shù)踢涌,相當于搖一次骰子
func shock () ->Int{
return Int(arc4random_uniform(6)) + 1
}
var money = 1000
//擺出一個循環(huán)repeat while 表示不管怎樣都會執(zhí)行一次通孽,相當于其他語言中的do while
repeat{
print("玩家總資產(chǎn)\(money)")
var debt:Int
//輸入賭注循環(huán),循環(huán)條件就是while后面跟的睁壁,賭注小于0和賭注大于資產(chǎn)
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)點秕噪,游戲繼續(xù)")
needGoOn = true //第一次沒有獲勝钳降,需要繼續(xù)進行下面的游戲,將剛開始定義的循環(huán)條件變?yōu)閠rue,表示需要接下來的循環(huán)
}
//num用于記錄搖的次數(shù)
var num = 2
//while循環(huán)只有當一次沒分出勝負后執(zhí)行
while needGoOn {
let secondShock = shock() + shock()
if secondShock == firstShock{
//分出勝負后循環(huán)結(jié)束
print("第\(num)次搖了\(secondShock)點腌巾,你贏了")
needGoOn = false
money += debt
}
else if secondShock == 7 {
print("第\(num)次搖了\(secondShock)點遂填,你輸了")
needGoOn = false
money -= debt
}
else{
//這里也是沒有分出勝負后循環(huán)繼續(xù)
print("第\(num)次搖了\(secondShock)點,游戲繼續(xù)")
}
num += 1
}
}while money > 0 //金額大于0循環(huán)才繼續(xù)
在計算機的循環(huán)中我們有很多好用的方法,比如窮舉法澈蝙,根據(jù)題目的部分條件確定答案的大致范圍吓坚,并在此范圍內(nèi)對所有可能的情況逐一驗證,直到全部情況驗證完畢灯荧。
例如:五個分魚的問題礁击,第一個人將魚分為5份多了一條直接扔了,拿走了1份逗载,第二人也將魚分為5份也多了一條直接扔了哆窿,也拿走了1份,以此類推第五個人也將魚分了五份厉斟,多了一條挚躯,問最少有多少條魚。
對于這個問題擦秽,我們也完全不知道大概有多少條魚码荔,這里就需要用到窮舉法食侮。
var goOn = true
var num = 1
//首先需要擺出一個循環(huán),這個循環(huán)結(jié)束條件就是找到一個數(shù)按題目的要求分5次
while goOn{
//定義一個數(shù)來記錄連續(xù)分魚的次數(shù)
var num1 = 0
var fish = num
//該循環(huán)就是分魚的循環(huán)
for _ in 1...5{
//滿足這個條件就將魚重新賦值目胡,同時num1也加1
if (fish-1)%5 == 0{
fish = (fish-1)/5*4
num1 += 1
}
}
//連續(xù)分魚的次數(shù)達到5次就表示找到了滿足條件的數(shù)量锯七,循環(huán)結(jié)束
if num1 == 5{
print(num)
goOn = false
}
num += 1
}
容器類型
1.數(shù)組
數(shù)組是一組相同類型的值在一個有序列表中的集合,就是把一定數(shù)量的相同類型變量用一個名字命名誉己,然后用編號將它們變量區(qū)分的集合眉尸,變量名就是數(shù)組名,編號就是索引巨双。下面來列舉幾種創(chuàng)建數(shù)組的方法:
//創(chuàng)建一個空的數(shù)組
var someInts = [Int]()
//創(chuàng)建一個含有默認值的數(shù)組噪猾,count代表數(shù)組長度,repeatedValue是初始值筑累。
var threeDoubles = [Double](count: 3, repeatedValue: 0.0)
//創(chuàng)建一個數(shù)組逐個賦值
var food:[String] = ["bread","Milk"]
//還可以利用swift的類型推斷
var food = ["bread","Milk"]
很多時候數(shù)組都是需要增加內(nèi)容或者刪除內(nèi)容的袱蜡,下面就是數(shù)組的增加與移除的方法:
var array = ["one","two"]
array.append("three") //直接加在數(shù)組最后一項
print(array) //打印結(jié)果為["one","two","three"]
array += ["four"] //與append的效果是一模一樣的
print(array) //["one","two","three","four"]
array.insert("first", atIndex: 0) //把值插入到數(shù)組,atIndex代表插入的位置慢宗,0是數(shù)組的第一位坪蚁。
//數(shù)組的移除方式有很多,下面只列舉一兩種
array.removeAtIndex(0)//跟插入的方法相同镜沽,但實現(xiàn)的操作是相反的
array.removeAll() //移除數(shù)組所有的值,清理存儲空間
array.removeAll(keepCapacity: true) //保存存儲空間敏晤,多用于一些移除了馬上又會重新賦值的數(shù)組
數(shù)組的排序:對于一些無序的數(shù)組,根據(jù)不同的需求可能會對其進行由小到大缅茉、由大到小等排序嘴脾,在Swift中對數(shù)組排序有多種方式:
1.Swift中自帶的排序功能
var array = [12,556,88,11,65,32]
let array1 = array.sort(>) //括號內(nèi)>代表由大到小,把排序好的數(shù)組返回給一個新的數(shù)組
array.sortInPlace() //默認為自然排序蔬墩,在原來的數(shù)組上排序译打,所以定義的時候需要用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.冒泡排序
//冒泡排序的思想是將數(shù)組中的元素從左往右兩兩依次比較蔬蕊,如果前者和比后者大則交換位置结澄,想當于每執(zhí)行一輪,則最大的數(shù)到了最右邊岸夯。
var array = [12,556,88,11,65,32]
for i in 1..<array.count
{
var needGoOn = false
//循環(huán)由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麻献,證明還需要繼續(xù)
}
}
if needGoOn = false {
break //如果循環(huán)一輪依次交換都沒有發(fā)生,說明數(shù)組已經(jīng)有序猜扮,可以提前結(jié)束循環(huán)勉吻,優(yōu)化代碼
}
}
print(array)
數(shù)組的遍歷:
1.只讀遍歷
var array = ["1","2","3"]
for i in array{ //i相當于數(shù)組的代言人,i的類型也數(shù)組元素的類型旅赢,這里為String類型
print(i)
}
2.可以操作數(shù)組元素的遍歷
var array = ["1","2","3"]
for i in 0...array.count-1
{
array[i] = "5" //可以對數(shù)組元素進行操作齿桃,重新賦值
print(array[i])
}
3.迭代器遍歷
var array = [12,556,88,11,65,32]
//index為數(shù)組的索引惑惶,value為索引對于的值
for (index,value) in array.enumerate()
{
print(index+1,value)
}
2.集合
集合是裝一組無序排列的相同類型無重復值的容器,與數(shù)組相比短纵,不同的是集合中沒有重復的值带污,但是在數(shù)組中是可以有重復值的。下面是集合的基本操作:
var set:Set<Int> = [0,1,2,4,5,1,6,4]
var set1:Set<Int> = [1,5,6] //集合的定義香到,和數(shù)組類似但是必須再定義類型set
set.remove(2) //移除值為2的項
print(set) //結(jié)果[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.字典
字典是存儲相同類型不同值的容器鱼冀。每一個值都對應著一個鍵,通過這個鍵可以找到這個值悠就,就像字典中每一個值都有一個標識符千绪。和數(shù)組的元素不同的是字典的元素是沒有特殊的序列。Swift的字典寫法是Dictionary< KeyType,ValueType >,KeyType是你想要儲存的鍵梗脾,ValueType是你想要儲存的值荸型。唯一的限制就是KeyType是可哈希類型(hashable),目的就是讓它們自身是獨立識別的。下面是字典的基本用法:
//字典的每個元素由兩部分構(gòu)成炸茧,冒號前面是鍵冒號后面是值
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) //直接通過一個元組獲得鍵和值
}
字典規(guī)范:
1:[ ]中由 key:value 鍵值對組成的
2:所有key 的類型必須一致踪宠, 所有value的類型必須一致,所有key不能重復
3:第一種格式定義的字典妈嘹,是直接定義字典,第二種格式定義的數(shù)組 是編譯器通過類型值推導出是字典格式
注意點:
1:常量關(guān)鍵字(let) 定義的字典绍妨,是不可變字典润脸,不能做任何修改,只能訪問他去。
2:變量關(guān)鍵字(var) 定義的字典 毙驯,是可變字典,可以修改灾测,可以訪問爆价。