0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

條理清晰,淺顯易懂:Lua語法技術(shù)知識詳解(第三部分)

青山老竹農(nóng) ? 來源:jf_82863998 ? 作者:jf_82863998 ? 2024-10-29 13:43 ? 次閱讀

今天我們繼續(xù)學(xué)習(xí)Lua語法基礎(chǔ)教程,下篇。

9.4 函數(shù)返回值

在前面的代碼中,我們實現(xiàn)了一個函數(shù),輸入變量a、b,函數(shù)會自動輸出兩個數(shù)值的和。

但是一般來說,我們的需求遠(yuǎn)遠(yuǎn)不止這些,我們可能需要一個如下功能的函數(shù):

執(zhí)行函數(shù),輸入兩個值,獲取這兩個值的和

如果還是按上面幾節(jié)的內(nèi)容,我們只會輸出這個值,并不能把這個值傳遞給其他的變量進(jìn)行后續(xù)使用,如何解決這個需求呢?

我們可以使用函數(shù)的返回值來實現(xiàn)這個需求,結(jié)合上面的需求,我們可以用下面的代碼實現(xiàn):


function add(a,b)

return a+b

end

all = add(1,2)

--這里all的值就是3了

print(all)

這里的return表示返回一個值,并且立刻結(jié)束這個函數(shù)的運行

同時,和輸入值可以有多個一樣,返回值也可以有多個


function add(a,b)

return a+b,"ok"

end

all, result = add(1,2)

--這里all的值就是3了

--這里result的值就是string "ok"

print(all,result)

下面問題來了,請設(shè)計一個函數(shù)p,可以按下面的調(diào)用方式來返回出物體的密度,返回值為number類型:


function p(a,b,c,m)

--請補(bǔ)全代碼

end

--一個長方體的長寬高分別為a、b、c(單位米)

a = 1

b = 2

c = 3

--這個物體重量為m(單位克)

m = 230

--下面返回密度值

--注:密度計算公式 密度 = 質(zhì)量 / 體積

result = p(a,b,c,m)

print(result)

9.5 判斷三角形合法性2(自測題)

你需要使用前面幾章的知識,來完成下面的題目

  • 已知三個number類型的變量,分別代表三根木棒的長度
  • 請判斷,使用這三根木棒,是否可以組成一個三角形(兩短邊之和大于第三邊)
  • 請新建一個函數(shù)triangle,并可以用如下形式調(diào)用(如果可以組成,就返回true):

function triangle(a,b,c)

--請補(bǔ)全代碼

end

result = triangle(1,2,3)--傳入值為三邊長度,多改幾個測試下

print(result)

9.6 返回多個值(自測題)

你需要使用前面幾章的知識,來完成下面的題目

  • 已知2個number類型的變量,分別代表一個長方體的長和寬
  • 請計算這個長方形的周長和面積
  • 請新建一個函數(shù)rectangle,并可以用如下形式調(diào)用:

function rectangle(a,b)

--補(bǔ)全代碼

end

area,len = rectangle(1,2)

--結(jié)果:

--面積area為2

--周長len為6

print(area,len)

十、table

10.1 認(rèn)識數(shù)組

數(shù)組,使用一個變量名,存儲一系列的值

很多語言中都有數(shù)組這個概念,在Lua中,我們可以使用table(表)來實現(xiàn)這個功能

在Lua中,table是一個一系列元素的集合,使用大括號進(jìn)行表示,其中的元素之間以逗號分隔,類似下面的代碼:


t = {1,3,8,5,4}

我們可以直接使用元素的下標(biāo),來訪問、或者對該元素進(jìn)行賦值操作。

在上面的table變量t中,第一個元素的下標(biāo)是1,第二個是2,以此類推。

我們可以用變量名+中括號,中括號里加上下標(biāo),來訪問或更改這個元素,如下面的例子:


t = {1,3,8,5,4}

print(t[1]) --打印1

print(t[3]) --打印8

t[2] = 99 --更改第二個元素的值

print(t[2]) --打印99

t[6] = 2 --憑空新建第六個元素并賦值

print(t[6]) --打印2

print(t[10])

--因為不存在,打印nil

以上就是table最簡單的一個例子了,就是當(dāng)作數(shù)組來用(注意,一般語言中的數(shù)組基本都為不可變長度,這里的table為可變長度)

下面你需要完成:

  • 新建一個table,名為cards,存入1-10十個數(shù)字
  • 將第3個元素與第7個元素交換
  • 將第9個元素與第2個元素交換
  • 增加第11個變量,值為23

--請補(bǔ)全代碼

cards =

10.2 簡單table

上一節(jié)里,我們將table來表示數(shù)組,實際上,table中可以包括任意類型的數(shù)據(jù)

比如我們可以在table中放置number和string數(shù)據(jù),類似下面的代碼:


t = {"abc",223,",..a",123123}

我們甚至能在里面放function變量


t = {

function() return 123 end,

function() print("abc") end,

function(a,b) return a+b end,

function() print("hello world") end,

}

t1

t2

t3

t4

這些table訪問每個元素的方式仍然是直接用下標(biāo),并且也能用下標(biāo)來進(jìn)行修改

下面你需要完成:

  • 新建一個table,名為funcList,并實現(xiàn)以下功能
  • 調(diào)用funcList1,返回a和b的乘積
  • 調(diào)用funcList2,返回a減b的差
  • 調(diào)用funcList3,返回a的相反數(shù)(-a)

--請補(bǔ)全代碼

funcList = {

}

a,b = 1,2--提供兩個數(shù)

print("a,b值為",a,b)

print("a和b的乘積:",funcList1)

print("a和b的差:",funcList2)

print("a和相反數(shù):",funcList3)

10.3 table下標(biāo)

在前兩節(jié),我們的table都只是一些簡單的List(列表),每個元素的下標(biāo)都是自動從1排列的

實際上,Lua中,下標(biāo)可以直接在聲明時進(jìn)行指定,像下面這樣:


t = {6,7,8,9}

--上面和下面的代碼等價

t = {

[1] = 6,

[2] = 7,

[3] = 8,

[4] = 9,

}

--甚至你可以跳過某些下標(biāo)

t = {

[1] = 6,

[3] = 7,

[5] = 8,

[7] = 9,

}

print(t[7])

--輸出9

--在聲明后賦予元素值也是可以的

t = {}--空的table

t[101] = 10

print(t[101])

--輸出10

下面你需要:

  • 新建一個變量t,并按下面的格式聲明
  • 下標(biāo)為1的元素,值為123(number)
  • 下標(biāo)為13的元素,值為"abc"(string)
  • 下標(biāo)為666的元素,值為"666"(string)

--請補(bǔ)全代碼

t = {

}

print("下標(biāo)為1的元素:",t[1],type(t[1]))

print("下標(biāo)為13的元素:",t[13],type(t[13]))

print("下標(biāo)為666的元素:",t[666],type(t[666]))

10.4 下標(biāo)進(jìn)階

在上一節(jié),我們學(xué)習(xí)了如何自定義下標(biāo),其實在Lua中,下標(biāo)也可以是字符串,如下面的例子


t = {

["apple"] = 10,

banana = 12,

pear = 6,

}

--使用["下標(biāo)"] = 值

--和 下標(biāo) = 值

--都是正確寫法

--當(dāng)?shù)诙N方式有歧義時,應(yīng)該用第一種方式

--可以用下面兩種方式訪問:

print(t["apple"])

--輸出10

print(t.apple)

--輸出10

--當(dāng)?shù)诙N方式有歧義時,應(yīng)該用第一種方式

可見,在使用string作為下標(biāo)時,table的靈活性提升了一個數(shù)量級。

string作為下標(biāo)時,也可以動態(tài)賦值:


t = {} -- 空table

t["new"] = "新的值"

print(t.new)

--輸出 新的值

下面你需要完成:

  • 新建table變量t
  • 下標(biāo)為apple的元素,值為123(number)
  • 下標(biāo)為banana的元素,值為"abc"(string)
  • 下標(biāo)為1@1的元素,值為"666"(string)

--請補(bǔ)全代碼

t = {

}

print("下標(biāo)為apple的元素:",t["apple"],type(t["apple"]))

print("下標(biāo)為banana的元素:",t["banana"],type(t["banana"]))

print("下標(biāo)為1@1的元素:",t["1@1"],type(t["1@1"]))

10.5 table小測驗

下面的代碼,將會打印什么?


t = {

apple = {

price = 7.52,

   weight = 2.1,

},

banana = {

price = 8.31,

   weight = 1.4,

   year = '2018'

},

year = '2019'

}

print(

t.price,

t.apple.price,

t.banana.weight,

t.year

)

10.6 table小測驗2

下面的代碼,將會打印什么?


t = {

{

price = 7.52,

   weight = 2.1,

},

{

price = 8.31,

   weight = 1.4,

   year = '2018'

},

year = '2019'

}

print(

t["price"],

t[1].price,

t[2].weight,

t["year"]

)

10.7 Lua全局變量與table

在前面我們知道了,在table中,可以直接用table名[下標(biāo)]或table名.string下標(biāo)來訪問元素

實際上,在Lua中,所有的全局變量全部被存放在了一個大table中,這個table名為:_G

我們可以用下面的例子來示范:


n = 123--新建變量

print(n)--輸出123

print(_G.n)--輸出123

_G.abc = 1--相當(dāng)于新建全局變量

print(abc)--輸出1

_G["def"] = 23--相當(dāng)于新建全局變量

print(def)--輸出23

--甚至你可以像下面這樣

_G.print("hello")

_G"print"

現(xiàn)在,你明白為什么說萬物基于table了吧?

你需要完成下面的任務(wù):

  • 已知有一個全局變量,名為@#$
  • 請新建一個變量result
  • 將@#$變量里的值賦值給result

_G["@#$"] = 123

result = --請補(bǔ)全代碼

print("result值為",result)

10.8 table小測試3

請新建一個名為t的table,滿足以下要求

  • t[10]可獲得number類型數(shù)據(jù)100
  • t.num可獲得number類型數(shù)據(jù)12
  • t.abc[3]可獲得string類型數(shù)據(jù)abcd
  • t.a.b.c可獲得number類型數(shù)據(jù)789

--請補(bǔ)全代碼

t = {

}

print("t[10]可獲得number類型數(shù)據(jù)100:",t[10],type(t[10]))

print("t.num可獲得number類型數(shù)據(jù)12:",t.num,type(t.num))

print("t.abc[3]可獲得string類型數(shù)據(jù)abcd:",t.abc[3],type(t.abc[3]))

print("t.a.b.c可獲得number類型數(shù)據(jù)789:",t.a.b.c,type(t.a.b.c))

10.9 table.concat

table.concat (table [, sep [, i [, j ] ] ])

將元素是string或者number類型的table,每個元素連接起來變成字符串并返回。

可選參數(shù)sep,表示連接間隔符,默認(rèn)為空。

i和j表示元素起始和結(jié)束的下標(biāo)。

下面是例子:


local a = {1, 3, 5, "hello" }

print(table.concat(a))

print(table.concat(a, "|"))

-->打印的結(jié)果:

--135hello

--1|3|5|hello

請完成下面的任務(wù):

  • 已知table變量t,
  • 將t中的結(jié)果全部連起來
  • 間隔符使用,
  • 并使用print打印出來

t = {"a","b","c","d"}

print("連接結(jié)果:")

--補(bǔ)全代碼

10.10 table刪減

table.insert (table, [pos ,] value)

在(數(shù)組型)表 table 的 pos 索引位置插入 value,其它元素向后移動到空的地方。pos 的默認(rèn)值是表的長度加一,即默認(rèn)是插在表的最后。

table.remove (table [, pos])

在表 table 中刪除索引為 pos(pos 只能是 number 型)的元素,并返回這個被刪除的元素,它后面所有元素的索引值都會減一。pos 的默認(rèn)值是表的長度,即默認(rèn)是刪除表的最后一個元素。

下面是例子:


local a = {1, 8} --a[1] = 1,a[2] = 8

table.insert(a, 1, 3) --在表索引為1處插入3

print(a[1], a[2], a[3])

table.insert(a, 10) --在表的最后插入10

print(a[1], a[2], a[3], a[4])

-->打印的結(jié)果:

--3 1 8

--3 1 8 10

local a = { 1, 2, 3, 4}

print(table.remove(a, 1)) --刪除速索引為1的元素

print(a[1], a[2], a[3], a[4])

print(table.remove(a)) --刪除最后一個元素

print(a[1], a[2], a[3], a[4])

-->打印的結(jié)果:

--1

--2 3 4 nil

--4

--2 3 nil nil

請完成下面的任務(wù):

  • 已知table變量t,
  • 去除t中的第一個元素
  • 然后這時,在t的第三個元素前,加上一個number變量,值為810

t = {1,2,3,4,5,6,7,8,9}

--補(bǔ)全代碼

print("第一個元素應(yīng)為2:",t[1])

print("第三個元素應(yīng)為810:",t[3])

十一、循環(huán)

11.1 while循環(huán)

在實際功能實現(xiàn)中,經(jīng)常會遇到需要循環(huán)運行的代碼,比如從1到100填充table數(shù)據(jù),我們可以直接用循環(huán)語句來實現(xiàn)

我們首先來學(xué)習(xí)while這個循環(huán)語法,整體的格式如下:


while 繼續(xù)循環(huán)判斷依據(jù) do

執(zhí)行的代碼

end

下面舉一個例子,我們計算從1加到100的結(jié)果:


local result = 0

local num = 1

while num <= 100 do

result = result + num

num = num + 1

end

print(result)

上面的代碼,就是當(dāng)num≤100時,result不斷地加num,并且num每次循環(huán)后自己加1

理解了上面的代碼,我們來完成下面一個簡單的任務(wù)吧:

  • 已知兩個number類型的變量min和max
  • 請計算從min與max之間,所有3的倍數(shù)的和
  • 打印出結(jié)果

min,max = 114,514 --這個結(jié)果應(yīng)為42009

result = 0--結(jié)果存放到這個變量

while 請完善 do

--補(bǔ)全代碼

end

print("結(jié)果:",result)

11.2 for循環(huán)

for循環(huán)在某些程度上,和while循環(huán)很相似,但是for循環(huán)可以更加簡潔地表達(dá)中間累積的量

我們首先來學(xué)習(xí)for這個循環(huán)語法,整體的格式如下:


for 臨時變量名=開始值,結(jié)束值,步長 do

循環(huán)的代碼

end

其中,步長可以省略,默認(rèn)為1

臨時變量名可以直接在代碼區(qū)域使用(但不可更改),每次循環(huán)會自動加步長值,并且在到達(dá)結(jié)束值后停止循環(huán)

下面舉一個例子,我們計算從1加到100的結(jié)果:


local result = 0

for i=1,100 do

result = result + i

end

print(result)

上面的代碼,就是當(dāng)i≤100時,result不斷地加i,并且i每次循環(huán)后增加1

理解了上面的代碼,我們來完成下面一個簡單的任務(wù)吧:

  • 已知兩個number類型的變量min和max
  • 請計算從min與max之間,所有7的倍數(shù)的和
  • 打印出結(jié)果

min,max = 114,514 --這個結(jié)果應(yīng)為17955

result = 0--結(jié)果存放到這個變量

for --補(bǔ)全代碼

print("結(jié)果:",result)

11.3 中斷循環(huán)

前面我們學(xué)習(xí)了循環(huán)語句,有些時候循環(huán)運行到一半,我們不想再繼續(xù)運行了,怎么辦呢?

我們可以在一個循環(huán)體中使用break,來立即結(jié)束本次循環(huán),繼續(xù)運行下面的代碼

比如像下面這樣,計算1-100相加途中,小于100的最大的和:


result = 0

for i=1,100 do

result = result + i

if result > 100 then

result = result - i

   break

end

end

print(result)

可以看見,當(dāng)發(fā)現(xiàn)和大于100后,代碼立即把result的值還原到了加上當(dāng)前數(shù)字之前的狀態(tài),并且調(diào)用break語句,立即退出了本次循環(huán)

在while中,我們也可以使用break:


result = 0

c = 1

while true do

result = result + c

if result > 100 then

result = result - c  

   break

end

c = c + 1

end

print(result)

我們在這里直接使用了死循環(huán)(因為while的繼續(xù)運行判斷依據(jù)始終為true),整體邏輯也和之前for的代碼一致,當(dāng)發(fā)現(xiàn)和大于100后,代碼立即把result的值還原到了加上當(dāng)前數(shù)字之前的狀態(tài),并且調(diào)用break語句,立即退出了本次循環(huán)

現(xiàn)在你需要完成一項任務(wù):

  • 請求出小于變量max的13的倍數(shù)的最大值(max大于0)
  • 并將結(jié)果打印出來
  • 本題理論上不用循環(huán)就能實現(xiàn),但是為了練習(xí)一下技巧,請用for循環(huán)來實現(xiàn)

max = 810 --結(jié)果應(yīng)為806

result = 0

for --請補(bǔ)全代碼

print(result)

11.4 循環(huán)測試題1(自測題)

前面我們學(xué)習(xí)了循環(huán)語句,我們需要完成下面的任務(wù)

我們知道,print函數(shù)可以打印一行完整的輸出

那么,已知變量a,請打印出下面的結(jié)果:

(a為大于0的整數(shù),且需要輸出a行數(shù)據(jù),數(shù)據(jù)從1開始,每行與上一行的差為2)

1

3

5

7

9

(上面例子為當(dāng)a為5的情況)

做題區(qū)域:

a = 10

--需要用print輸出要求的結(jié)果

print("輸出結(jié)果:")

for --請補(bǔ)全代碼

11.5 循環(huán)測試題2(自測題)

我們需要完成下面的任務(wù)

那么,已知變量a,請打印出下面的結(jié)果:

(a為大于0的整數(shù),且需要輸出a行數(shù)據(jù),第一行為一個,后面每行多一個)


**




(上面例子為當(dāng)a為5的情況)

做題區(qū)域:


a = 10

--需要用print輸出要求的結(jié)果

print("輸出結(jié)果:")

for --請補(bǔ)全代碼

11.6 循環(huán)測試題3(自測題)

我們需要完成下面的任務(wù)

那么,已知變量a,請打印出下面的結(jié)果:

(a為大于0的整數(shù),且需要輸出a行數(shù)據(jù),按圖示規(guī)律輸出)


1

12

123

1234

12345

123456

1234567

12345678

123456789

12345678910

1234567891011

(上面例子為當(dāng)a為11的情況)

做題區(qū)域:


a = 20

--需要用print輸出要求的結(jié)果

print("輸出結(jié)果:")

for --請補(bǔ)全代碼

11.7 循環(huán)測試題4(自測題)

  • 有一只猴子,第一天摘了若干個桃子 ,當(dāng)即吃了一半,但還覺得不過癮 ,就又多吃了一個。
  • 第2天早上又將剩下的桃子吃掉一半,還是覺得不過癮,就又多吃了兩個。
  • 以后每天早上都吃了前一天剩下的一半加天數(shù)個(例如,第5天吃了前一天剩下的一半加5個)。
  • 到第n天早上再想吃的時候,就只剩下一個桃子了。
  • 那么,已知變量a為最后一天的天數(shù),請打印出第一天的桃子數(shù)。
  • 如:a為5時,輸出114

做題區(qū)域:


a = 6

--需要用print輸出要求的結(jié)果

print("輸出結(jié)果:")

for --請補(bǔ)全代碼

十二、詳解string庫

12.1 string.sub

接下來幾節(jié)會講解string庫的各種接口


string.sub(s, i [, j])

返回字符串 s 中,從索引 i 到索引 j 之間的子字符串。

i 可以為負(fù)數(shù),表示倒數(shù)第幾個字符。

當(dāng) j 缺省時,默認(rèn)為 -1,也就是字符串 s 的最后位置。

當(dāng)索引 i 在字符串 s 的位置在索引 j 的后面時,將返回一個空字符串。

下面是例子:


print(string.sub("Hello Lua", 4, 7))

print(string.sub("Hello Lua", 2))

print(string.sub("Hello Lua", 2, 1))

print(string.sub("Hello Lua", -3, -1))

-->打印的結(jié)果:

lo L

ello Lua

Lua

值得注意的是,我們可以使用冒號來簡化語法,像下面這樣:


s = "12345"

s1 = string.sub(s, 4, 7)

s2 = s:sub(4, 7)

--兩種寫法是等價關(guān)系

print(s1,s2)

請完成下面的任務(wù):

  • 已知字符串變量s,請分別打印出(每種一行):
  • s從第4個字符開始,到最后的值
  • s從第1個字符開始,到倒數(shù)第3個字符的值
  • s從倒數(shù)第5個字符開始,到倒數(shù)第2個字符的值

s = "1919810"

--補(bǔ)全代碼

print()

print()

print()

12.2 string.rep

string.rep(s, n)

返回字符串 s 的 n 次拷貝。

示例代碼:


print(string.rep("abc", 3))

--輸出結(jié)果:

--abcabcabc

請完成下面的任務(wù):

打印一行數(shù)據(jù),數(shù)據(jù)內(nèi)容為810個114514


--補(bǔ)全代碼

print()

12.3 string.len

string.len(s)

接收一個字符串,返回它的長度。

示例代碼:


s = "hello lua"

print(string.len(s))

--輸出結(jié)果:

9

--同時也可以使用簡便語法

print(s:len())

請完成下面的任務(wù):

  • 新建一個變量s,使數(shù)據(jù)內(nèi)容為810個114514
  • 并打印出字符串s的長度

s = --補(bǔ)全代碼

print()

12.4 大小寫轉(zhuǎn)換

string.lower(s)

接收一個字符串 s,返回一個把所有大寫字母變成小寫字母的字符串。

string.upper(s)

接收一個字符串 s,返回一個把所有小寫字母變成大寫字母的字符串。

示例代碼:


s = "hello lua"

print(string.upper(s))

print(string.lower(s))

--輸出結(jié)果:

HELLO LUA

hello lua

--同時也可以使用簡便語法

print(s:upper())

print(s:lower())

請完成下面的任務(wù):

已知一個變量s,打印出全是大寫字母的s字符串


s = "asd8938KJjsidiajdl;(()k)"

print --補(bǔ)全代碼

12.5 string.format

string.format(formatstring, ...)

按照格式化參數(shù)formatstring,返回后面...內(nèi)容的格式化版本。

編寫格式化字符串的規(guī)則與標(biāo)準(zhǔn) c 語言中 printf 函數(shù)的規(guī)則基本相同:

它由常規(guī)文本和指示組成,這些指示控制了每個參數(shù)應(yīng)放到格式化結(jié)果的什么位置,及如何放入它們。

一個指示由字符%加上一個字母組成,這些字母指定了如何格式化參數(shù),例如d用于十進(jìn)制數(shù)、x用于十六進(jìn)制數(shù)、o用于八進(jìn)制數(shù)、f用于浮點數(shù)、s用于字符串等。

示例代碼:


print(string.format("%.4f", 3.1415926)) -- 保留4位小數(shù)

print(string.format("%d %x %o", 31, 31, 31))-- 十進(jìn)制數(shù)31轉(zhuǎn)換成不同進(jìn)制

d,m,y = 29,7,2015

print(string.format("%s %02d/%02d/%d", "today is:", d, m, y))

--控制輸出2位數(shù)字,并在前面補(bǔ)0

-->輸出

-- 3.1416

-- 31 1f 37

-- today is: 29/07/2015

請完成下面的任務(wù):

  • 已知一個變量n,為number類型整數(shù)
  • 打印出n:連上n值的字符串

n = 810

print --補(bǔ)全代碼

12.6 string的本質(zhì)

這一節(jié)我們來講解字符串的本質(zhì)

字符串,是用來存儲一串字符的,但是它的本質(zhì)就是一串?dāng)?shù)字。如何用一串?dāng)?shù)字來代表一串字符呢?

在計算機(jī)中,每一個符號都對應(yīng)著一個數(shù)字,但是在講解這個知識之前,我們了解一下補(bǔ)充知識:


在大多數(shù)編程語言中,我們使用0x開頭來表示這個數(shù)字是16進(jìn)制的。

比如

10等價于0x0a

256等價于0xff

接下來,你需要了解,每一個符號都對應(yīng)著一個數(shù)字,比如:

0對應(yīng)著0x30、1對應(yīng)著0x31 a對應(yīng)著0x61、b對應(yīng)著0x62 A對應(yīng)著0x41、B對應(yīng)著0x42

上面的編碼規(guī)則,我們稱之為ascii碼,具體想了解可以打開下面的網(wǎng)址查看:http://ascii.911cha.com/

當(dāng)然,1字節(jié)最大為0xff,即256,只能存下一部分符號,大部分的中文按某些編碼,一個中文占用2或3個字節(jié)

計算機(jī)如何解析這些數(shù)據(jù),我們不需要了解,當(dāng)你知道了上面的知識后,你應(yīng)該可以理解下面的描述:


字符串"apple"實際上的內(nèi)容就是下面的一串?dāng)?shù)字:

0x61,0x70,0x70,0x6c,0x65

同時,lua的字符串中可以保存任何數(shù)值,即使是0x00這種不代表任何含義的數(shù),也可以保存


補(bǔ)充:在其他語言中(如C),0x00代表字符串結(jié)束,但是在lua中并不是這樣。

lua的字符串每字節(jié)可以存儲任意的一字節(jié)數(shù)據(jù)。

比如下面的描述:


有一串lua字符串中的數(shù)據(jù)為:

0x01,0x02,0x30,0x00,0x44

實際人能看到的(不可見字符用?代替):

??0?D

當(dāng)然,你不能說你看不見的數(shù)據(jù)就不存在,他們都完好無損地在這個字符串中

下面你需要思考一個問題:一串字符串?dāng)?shù)據(jù)如下,它的實際內(nèi)容是什么(指人能看見的字符串內(nèi)容,如abcd)?

0x62,0x61,0x6e,0x61,0x6e,0x61

12.7 string.char

string.char (...)

接收 0 個或更多的整數(shù)(整數(shù)范圍:0~255),返回這些整數(shù)所對應(yīng)的 ASCII 碼字符組成的字符串。當(dāng)參數(shù)為空時,默認(rèn)是一個 0。

如果上一章節(jié)有認(rèn)真學(xué)習(xí)過了的話,這段話應(yīng)該是很好理解的。實質(zhì)上就是把計算機(jī)認(rèn)識的一串?dāng)?shù)字,變成字符串變量,并且字符串內(nèi)的數(shù)據(jù)就是要存的那串?dāng)?shù)據(jù)。

示例代碼:


str1 = string.char(0x30,0x31,0x32,0x33)

str2 = string.char(0x01,0x02,0x30,0x03,0x44)

print(str1)

print(str2)

-->輸出(不可見字符用?代替)

--0123

--??0?D

請完成下面的任務(wù):

  • 已知一個字符串的每個字符在數(shù)組t中按順序排列
  • 請根據(jù)t的值,打印出字符串內(nèi)容(一行數(shù)據(jù))
  • 注:這個字符串存儲的不一定是可見的字符

t = {0x79,0x6F,0x75,0x20,0x61,0x72,0x65,0x20,0x72,0x69,0x67,0x68,0x74}

print("真正的字符串內(nèi)容:")

--補(bǔ)全代碼

12.8 string.byte

string.byte(s [, i [, j ] ])

返回字符 s[i]、s[i + 1]、s[i + 2]、······、s[j] 所對應(yīng)的 ASCII 碼。i 的默認(rèn)值為 1,即第一個字節(jié),j 的默認(rèn)值為 i 。

這個函數(shù)功能剛好和前面的string.char相反,是提取字符串中實際的數(shù)值。

示例代碼:


str = "12345"

print(string.byte(str,2))

print(str:byte(2))--也可以這樣

print(str:byte())--不填默認(rèn)是1

-->輸出(十進(jìn)制數(shù)據(jù))

--50

--50

--49

請完成下面的任務(wù):

  • 已知字符串s
  • 請把s中代表的數(shù)據(jù),全部相加,并打印出來

s = string.char(1,2,3,4,5,6,7,8,9)

print("s內(nèi)數(shù)據(jù)的和是:")

--補(bǔ)全代碼

12.9 string.find

string.find(s, p [, init [, plain] ])

這個函數(shù)會在字符串s中,尋找匹配p字符串的數(shù)據(jù)。如果成功找到,那么會返回p字符串在s字符串中出現(xiàn)的開始位置和結(jié)束位置;如果沒找到,那么就返回nil。

第三個參數(shù)init默認(rèn)為1,表示從第幾個字符開始匹配,當(dāng)init為負(fù)數(shù)時,表示從s字符串的倒數(shù)第-init個字符處開始匹配。

第四個參數(shù)plain默認(rèn)為false,當(dāng)其為true時,只會把p看成一個字符串對待。

可能你會奇怪,第四個參數(shù)有什么存在的必要嗎?p不是本來就應(yīng)該是個字符串嗎? 實際上,lua中的匹配默認(rèn)意義是正則匹配,同時,這里的正則與其它語言也有些許不同。

由于篇幅有限,本節(jié)和下面的幾節(jié)涉及匹配內(nèi)容時,均不會考慮正則的使用方法,Lua正則教程將會在最后幾節(jié)單獨詳細(xì)地列出來。

第四個參數(shù)為true時,便不會使用正則功能。

示例代碼:


--只會匹配到第一個

print(string.find("abc abc", "ab"))

-- 從索引為2的位置開始匹配字符串:ab

print(string.find("abc abc", "ab", 2))

-- 從索引為5的位置開始匹配字符串:ab

print(string.find("abc abc", "ab", -3))

-->輸出

--1 2

--5 6

--5 6

請完成下面的任務(wù):

  • 已知字符串s,里面有很多相同的字符串
  • 請找出字符串s中,所有字符串a(chǎn)wsl的位置
  • 使用print打印結(jié)果,結(jié)果一行一個
  • 如字符串12awslawslaw,輸出3和7

s = "12awsaslwlaawsllslllswasllalssawwlawslaw"

print("兩個awsl的位置分別是:")

--補(bǔ)全代碼

12.10 string.gsub

string.gsub(s, p, r [, n])

將目標(biāo)字符串s中所有的子串p替換成字符串r。

可選參數(shù)n,表示限制替換次數(shù)。

返回值有兩個,第一個是被替換后的字符串,第二個是替換了多少次。

特別提示:這個函數(shù)的目標(biāo)字符串s,也是支持正則的

下面是例子:


print(string.gsub("Lua Lua Lua", "Lua", "hello"))

print(string.gsub("Lua Lua Lua", "Lua", "hello", 2)) --指明第四個參數(shù)

-->打印的結(jié)果:

-- hello hello hello 3

-- hello hello Lua 2

同樣的,我們也可以使用冒號來簡化語法,像下面這樣:


s = "12345"

r = s:gsub("2","b")

print(r)

請完成下面的任務(wù):

  • 已知字符串變量s,請分別打印出(每種一行):
  • 把字符串s中,前5個a,替換為b
  • 把字符串s中,前3個c,替換為xxx
  • 把結(jié)果打印出來,一行數(shù)據(jù)

s = "asdicagydausckfugdaflgscdabgsdbahhacbshbsd"

print("s變換前的值:",s)

--補(bǔ)全代碼

十三、跨文件調(diào)用

在編寫代碼時,隨著邏輯逐漸復(fù)雜,我們的代碼量也會變大。雖然有函數(shù)可以把一部分代碼邏輯封裝起來,但是所有代碼都放到一個文件里,顯然也不是個好辦法。

所以我們需要將一些代碼放到不同文件中,通過文件來區(qū)分這些代碼的功能。

比如我們有下面這個函數(shù):


---函數(shù)功能:

-- 生成從1-max的table

-- @輸入值:table的最大值

-- @返回: table結(jié)果

-- @例子: local list = getNumberList(10)

function getNumberList(max)

local t = {}

for i=1,max do

table.insert(t,i)

end

return t

end

我們新建一個文件叫tools.lua,把這個函數(shù)放進(jìn)去,現(xiàn)在,整個文件如下面這樣:

tools.lua


---函數(shù)功能:

-- 生成從1-max的table

-- @輸入值:table的最大值

-- @返回: table結(jié)果

-- @例子: local list = getNumberList(10)

local function getNumberList(max)

local t = {}

for i=1,max do

table.insert(t,i)

end

return t

end

--手動返回一個table,包含了上面的函數(shù)

return {

getNumberList = getNumberList,

}

現(xiàn)在,我們封裝的這個函數(shù)就能在其他文件里被調(diào)用了,具體代碼如下:


--引用tools.lua文件,并加載

local tool = require("tools")

local list = tool.getNumberList(12)

當(dāng)調(diào)用了require接口后,Lua虛擬機(jī)會自動加載你調(diào)用的文件,執(zhí)行文件的內(nèi)容,然后返回你文件里return的結(jié)果。

為了更好地理解這段話,我們可以看下面兩個文件,其中run.lua是被運行的那個入口文件

test.lua


--以便一會兒返回使用的table

local temp = {}

--把全局變量a更改了

a = 1

--local變量無法被外部調(diào)用

--但是可以在文件內(nèi)被調(diào)用

local b = 2

--文件在被require的時候,會被執(zhí)行

--把全局變量c更改了

c = a + b

--使函數(shù)在table里

function temp.addB()

--文件內(nèi)部可以調(diào)用變量b

b = b + 1

return b

end

--返回table

return temp

run.lua


local test = require("test")

print(a)--輸出1

print(b)--輸出nil,因為b是local變量

print(c)--輸出3

print(test.addB())--輸出3

print(test.addB())--輸出4

print(test.addB())--輸出5

同時,每個文件最多只會被require一次,如果有多個require,只有第一次會執(zhí)行。

審核編輯 黃宇

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • Lua
    Lua
    +關(guān)注

    關(guān)注

    0

    文章

    83

    瀏覽量

    10883
收藏 0人收藏

    評論

    相關(guān)推薦
    熱點推薦

    提高篇——C語言核心技術(shù)(中文版)

    嚴(yán)謹(jǐn)?shù)男g(shù)語表介紹C語言;第二部分描述標(biāo)準(zhǔn)鏈接庫;第三部分介紹GNU軟件包中常用的編譯和測試工具。 獲取完整文檔資料可下載附件哦?。。?!如果內(nèi)容有幫助可以關(guān)注、點贊、評論支持一下哦~
    發(fā)表于 06-13 16:39

    TI大學(xué)計劃-電源篇

    本手冊將分為以下幾部分介紹信號鏈和電源相關(guān)的知識及 TI 產(chǎn)品在大學(xué)生創(chuàng)新活動中的應(yīng)用: 第一部分:運算放大器的原理和設(shè)計; 第二部分:數(shù)據(jù)轉(zhuǎn)換器的原理和設(shè)計;
    發(fā)表于 05-19 15:33

    如何用 Raspberry Pi 500 搭建家庭錄音室?

    是時候安裝并配置家庭錄音室中高質(zhì)量音頻制作所需的軟件了。這是來自《樹莓派官方雜志》系列教程的第三部分,也是最后一部分。若想閱讀整個系列教程,請先回顧第一部分(關(guān)于錄音空間設(shè)置),再閱讀第二部分
    的頭像 發(fā)表于 05-18 08:33 ?850次閱讀
    如何用 Raspberry Pi 500 搭建家庭錄音室?

    B10 BMS技術(shù)知識初探(上、下)

    課程名稱: BMS技術(shù)知識初探課程目標(biāo): 可充電電池已是人們生活中不可缺少的組成部分,基于電池技術(shù)為基礎(chǔ)的電動汽車、儲能行業(yè),更是新能源發(fā)展的重要標(biāo)志。而BMS技術(shù)是電池安全的重要保障
    發(fā)表于 05-02 11:04

    無刷電機(jī)電調(diào)的基本原理

    有關(guān)本文所談?wù)摰臒o刷電機(jī)內(nèi)容, 只涉及低速飛行類航模電調(diào)的小功率無傳感器應(yīng)用,講解的理論比較淺顯易懂 ,旨在讓初學(xué)者能夠?qū)o刷電機(jī)有一個比較快的認(rèn) 識,掌握基本原理和控制方法,可以在短時間內(nèi)達(dá)到
    發(fā)表于 03-17 19:57

    松下MPS媒體制作平臺第八篇:視頻混合器插件(第三部分)

    ? 歡迎?????大家觀看松下操作教程 MPS媒體制作平臺????? 第八篇:視頻混合器插件(第三部分) 視頻混合器(Video Mixer)插件可以輕松進(jìn)行主體鍵控,不受拍攝地點的局限,同時便于將
    的頭像 發(fā)表于 01-08 10:10 ?432次閱讀
    松下MPS媒體制作平臺第八篇:視頻混合器插件(<b class='flag-5'>第三部分</b>)

    Air780EP硬件設(shè)計原理解析(第三部分

    ? 接下來,我們繼續(xù)學(xué)習(xí)第三部分。 四、射頻接口 天線接口管腳定義如下: 表格 14:RF_ANT 管腳定義 ? 4.1 射頻參考電路 ? 注意: 連接到模塊RF天線焊盤的RF走線必須使用微帶線或者
    的頭像 發(fā)表于 11-06 15:07 ?680次閱讀
    Air780EP硬件設(shè)計原理解析(<b class='flag-5'>第三部分</b>)

    條理清晰,淺顯易懂Lua語法基礎(chǔ)知識(第二部分

    今天我們繼續(xù)學(xué)習(xí)Lua語法基礎(chǔ)教程,中篇。 五、變量 5.1 number變量 變量,可以看作是一個桶,在里面裝你想要裝的內(nèi)容。這些內(nèi)容可以是Lua包含的所有合法類型。 例如:我想要新建一個桶,名叫
    的頭像 發(fā)表于 10-29 13:40 ?484次閱讀

    Lua語法基礎(chǔ)教程(下篇)

    今天我們繼續(xù)學(xué)習(xí)Lua語法基礎(chǔ)教程,下篇。 九、函數(shù) 9.1 初識函數(shù) 函數(shù)是指一段在一起的、可以做某一件事兒的程序,也叫做子程序。 在前面的內(nèi)容中,我們已經(jīng)接觸過了函數(shù)的調(diào)用,這個函數(shù)就是前面用到
    的頭像 發(fā)表于 10-26 11:41 ?609次閱讀
    <b class='flag-5'>Lua</b><b class='flag-5'>語法</b>基礎(chǔ)教程(下篇)

    Lua語法基礎(chǔ)教程(中篇)

    今天我們繼續(xù)學(xué)習(xí)Lua語法基礎(chǔ)教程,中篇。 五、變量 5.1 number變量 變量,可以看作是一個桶,在里面裝你想要裝的內(nèi)容。這些內(nèi)容可以是Lua包含的所有合法類型。 例如:我想要新建一個桶,名叫
    的頭像 發(fā)表于 10-26 11:39 ?669次閱讀
    <b class='flag-5'>Lua</b><b class='flag-5'>語法</b>基礎(chǔ)教程(中篇)

    Lua語法基礎(chǔ)教程(上篇)

    今天我們來學(xué)習(xí)Lua語法基礎(chǔ)教程。由于篇幅過長,將分為上中下篇進(jìn)行講解,本篇為上篇。 一、初識Lua Lua 是一種輕量小巧的腳本語言,它
    的頭像 發(fā)表于 10-24 07:17 ?733次閱讀

    實際的正弦波震蕩電路主要由哪三部分組成

    實際的正弦波振蕩電路主要由以下三部分組成,盡管有時在更詳細(xì)的描述中可能會提及四部分(包括穩(wěn)幅環(huán)節(jié)),但以下三部分是構(gòu)成正弦波振蕩電路的核心: 放大電路 : 放大電路是振蕩電路的核心部分
    的頭像 發(fā)表于 10-09 16:59 ?1136次閱讀

    數(shù)字芯片設(shè)計驗證經(jīng)驗分享(第三部分):將ASIC IP核移植到FPGA上——如何確保性能與時序以完成充滿挑戰(zhàn)的

    本篇文章是SmartDV數(shù)字芯片設(shè)計經(jīng)驗分享系列文章的第三篇,將繼續(xù)分享第五、第六主題,包括確保在FPGA上實現(xiàn)所需的性能和時鐘兩個方面的考量因素。
    的頭像 發(fā)表于 08-26 14:31 ?2431次閱讀
    數(shù)字芯片設(shè)計驗證經(jīng)驗分享(<b class='flag-5'>第三部分</b>):將ASIC IP核移植到FPGA上——如何確保性能與時序以完成充滿挑戰(zhàn)的

    學(xué)習(xí)hypervisor嵌入式產(chǎn)品安全設(shè)計

    、PRTOS的配套工具等內(nèi)容。第三部分(第13~15章)介紹嵌入式Hypervisor的高級應(yīng)用和未來規(guī)劃,涵蓋μC/OS-II與Linux內(nèi)核的虛擬化過程,以及PRTOS社區(qū)的愿景等內(nèi)容。
    發(fā)表于 08-25 09:11

    直流電與交流電有什么差異

    直流電(Direct Current,簡稱DC)與交流電(Alternating Current,簡稱AC)是電力傳輸和使用中兩種基本的電流形式,它們在多個方面存在顯著差異。以下是對直流電與交流電區(qū)別的詳細(xì)闡述,內(nèi)容將超過2000字,但將盡量保持條理清晰、信息豐富。
    的頭像 發(fā)表于 08-14 11:01 ?4401次閱讀

    電子發(fā)燒友

    中國電子工程師最喜歡的網(wǎng)站

    • 2931785位工程師會員交流學(xué)習(xí)
    • 獲取您個性化的科技前沿技術(shù)信息
    • 參加活動獲取豐厚的禮品