概念
go默認(rèn)使用Unicode字符集脐供,同時使用utf-8作為編碼方式
go里面沒有字符類型(char)凳鬓,而是使用byte(uint8)和rune(int32)來代表字符。
我們聲明一個字符時患民,默認(rèn)是rune類型缩举,除非特別定義。 一個string變量既可以被拆分為字符匹颤,也可以被拆分為字節(jié)仅孩;前者使用rune[]切片表示,后者使用byte[]切片表示
一個rune值就是代表一個字符印蓖,在輸入輸出中經(jīng)沉赡剑看到類似’\U0001F3A8’,’\u2665’的就是一個rune字符(unicode字符)赦肃,其中的每位都是一個16進(jìn)制數(shù)
var a = 'A' // rune type
var b byte = 'a' // byte type
c:= byte('b') // byte type
本質(zhì)上溅蛉,byte其實(shí)都是整型類型公浪,其中byte是uint8的別稱,rune是int32的別稱船侧。例如一個byte類型的字符'a'其實(shí)是整型數(shù)字97欠气,對應(yīng)ASCII碼的字符a。
var a = 'a'
var b byte = 'a'
fmt.Printf("%T, %v", a, a) // int32, 97
fmt.Printf("%T, %v", b, b) // uint8, 97
byte類型和rune類型使用編碼方式不同镜撩,其中byte是ASCII編碼字符预柒,rune是utf-8字符。
string
字符串可以為空袁梗,但不能為nil宜鸯;
字符串的值不能修改,只能替換遮怜;
修改字符串時需要重新分配一次內(nèi)存淋袖,之前分配的內(nèi)存由gc回收(因此字符串比較低效)
[]byte字符串
[]byte字符串類型適用于字符串的拼接:
byte 字符
[]byte 字符串
[][]byte字符串?dāng)?shù)組
b1 := byte('a') // 字符
b2 := []byte("A") // 字符串
b3 := []byte{'a', 'b', 'c'} // 字符串
fmt.Printf("b1 = %c\n", b1)
fmt.Printf("b2 = %c\n", b2)
fmt.Printf("b3 = %s\n", b3)
s1 := []byte("Hello") // 字符串
s2 := []byte("World") // 字符串
s3 := [][]byte{s1, s2} // 字符串?dāng)?shù)組
s4 := bytes.Join(s3, []byte(","))
s5 := []byte{}
s5 = bytes.Join(s3, []byte("--"))
s6 := [][]byte{[]byte("foo"), []byte("bar"), []byte("baz")}
fmt.Printf("s1 = %s\n", s1)
fmt.Printf("s2 = %s\n", s2)
fmt.Printf("s3 = %s\n", s3)
fmt.Printf("s4 = %s\n", s4)
fmt.Printf("s5 = %s\n", s5)
fmt.Printf("%s\n", bytes.Join(s6, []byte(", ")))
b1 = a
b2 = [A]
b3 = abc
s1 = Hello
s2 = World
s3 = [Hello World]
s4 = Hello,World
s5 = Hello--World
foo, bar, baz
String和[]byte轉(zhuǎn)換及使用場景
轉(zhuǎn)換
// string to []byte
s1 := "hello"
b := []byte(s1)
// []byte to string
s2 := string(b)
使用場景
需要用做map的key時,用string锯梁,因為string可以直接比較适贸,[]byte不可以
如果需要用nil來表示額外的含義,用[]byte涝桅,因為string不能取nil值拜姿,[]byte可以
————————————————
版權(quán)聲明:本文為CSDN博主「AXIMI」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議冯遂,轉(zhuǎn)載請附上原文出處鏈接及本聲明蕊肥。
原文鏈接:https://blog.csdn.net/AXIMI/article/details/120379225
C語言中什么叫做高八位和低八位啊?
高八位和低八位:內(nèi)存里,一個單元是一個字節(jié)蛤肌,也就是8位壁却。如果是16位的指令,就是同時操作連續(xù)的2個內(nèi)存地址裸准,將這連續(xù)的2個內(nèi)存地址當(dāng)成一個單位展东,所以就有高8位和低8位之分。
由于計算機(jī)僅識別二進(jìn)制描述的數(shù)字炒俱,所以對一個內(nèi)存地址盐肃,也就是8位二進(jìn)制,如:0000 0001权悟,0000就是高四位砸王,0001就是低四位。
當(dāng)然2個內(nèi)存地址峦阁,就是16位二進(jìn)制谦铃,也就是:0000 0001 0000 0002。0000 0001 就是高八位榔昔,0000 0002就是低八位驹闰。
每個八位中又分成高低四位瘪菌。如:1010 0001 1111 0101,換算成16進(jìn)制就是:1010–10(10進(jìn)制)—A(16進(jìn)制)嘹朗,0001–1(10進(jìn)制)—1(16進(jìn)制)所以他的高八位就是A1师妙,同樣它的低八位就是F5。
擴(kuò)展資料:
如何在C語言中的ascII碼表里查找高四位骡显、低四位:
ascii碼在C語言中用char型存儲,一個char占一個字節(jié)曾掂,即8位惫谤。
當(dāng)寫成二進(jìn)制表達(dá)形式時,就是8個0或者1的數(shù)字珠洗,這8個數(shù)字中溜歪,左邊四個稱為高四位,右邊四個稱為低四位许蓖。
所以在查ascii碼表時蝴猪,需要:
1、把要查的值膊爪,轉(zhuǎn)成二進(jìn)制值自阱;
2、得到高四位值米酬,及低四位值沛豌;
3、根據(jù)高四位值查表赃额,找到所在列加派;
4、根據(jù)低四位值查表跳芳,找到所在行芍锦;
5、所在行列的交叉格飞盆,就是要查找的字符娄琉。
主機(jī)字節(jié)序
主機(jī)字節(jié)序模式有兩種,大端數(shù)據(jù)模式和小端數(shù)據(jù)模式吓歇,在網(wǎng)絡(luò)編程中應(yīng)注意這兩者的區(qū)別车胡,以保證數(shù)據(jù)處理的正確性;例如網(wǎng)絡(luò)的數(shù)據(jù)是以大端數(shù)據(jù)模式進(jìn)行交互照瘾,而我們的主機(jī)大多數(shù)以小端模式處理匈棘,如果不轉(zhuǎn)換,數(shù)據(jù)會混亂 參考 析命;一般來說主卫,兩個主機(jī)在網(wǎng)絡(luò)通信需要經(jīng)過如下轉(zhuǎn)換過程:主機(jī)字節(jié)序 —> 網(wǎng)絡(luò)字節(jié)序 -> 主機(jī)字節(jié)序
大端小端區(qū)別
大端模式:Big-Endian就是高位字節(jié)排放在內(nèi)存的低地址端逃默,低位字節(jié)排放在內(nèi)存的高地址端
低地址 --------------------> 高地址
高位字節(jié) 地位字節(jié)
小端模式:Little-Endian就是低位字節(jié)排放在內(nèi)存的低地址端,高位字節(jié)排放在內(nèi)存的高地址端
低地址 --------------------> 高地址
低位字節(jié) 高位字節(jié)
什么是高位字節(jié)和低位字節(jié)
例如在32位系統(tǒng)中簇搅,357轉(zhuǎn)換成二級制為:00000000 00000000 00000001 01100101完域,其中
00000001 | 01100101
高位字節(jié) 低位字節(jié)
int和byte轉(zhuǎn)換
在go語言中,byte其實(shí)是uint8的別名瘩将,byte 和 uint8 之間可以直接進(jìn)行互轉(zhuǎn)吟税。目前來只能將0~255范圍的int轉(zhuǎn)成byte。因為超出這個范圍姿现,go在轉(zhuǎn)換的時候肠仪,就會把多出來數(shù)據(jù)扔掉;如果需要將int32轉(zhuǎn)成byte類型,我們只需要一個長度為4的[]byte數(shù)組就可以了
大端模式下
func f2() {
var v2 uint32
var b2 [4]byte
v2 = 257
// 將 257轉(zhuǎn)成二進(jìn)制就是
// | 00000000 | 00000000 | 00000001 | 00000001 |
// | b2[0] | b2[1] | b2[2] | b2[3] | // 這里表示b2數(shù)組每個下標(biāo)里面存放的值
// 這里直接使用將uint32強(qiáng)轉(zhuǎn)成uint8
// | 00000000 0000000 00000001 | 00000001 直接轉(zhuǎn)成uint8后等于 1
// |---這部分go在強(qiáng)轉(zhuǎn)的時候扔掉---|
b2[3] = uint8(v2)
// | 00000000 | 00000000 | 00000001 | 00000001 | 右移8位 轉(zhuǎn)成uint8后等于 1
// 下面是右移后的數(shù)據(jù)
// | | 00000000 | 00000000 | 00000001 |
b2[2] = uint8(v2 >> 8)
// | 00000000 | 00000000 | 00000001 | 00000001 | 右移16位 轉(zhuǎn)成uint8后等于 0
// 下面是右移后的數(shù)據(jù)
// | | | 00000000 | 00000000 |
b2[1] = uint8(v2 >> 16)
// | 00000000 | 00000000 | 00000001 | 00000001 | 右移24位 轉(zhuǎn)成uint8后等于 0
// 下面是右移后的數(shù)據(jù)
// | | | | 00000000 |
b2[0] = uint8(v2 >> 24)
fmt.Printf("%+v\n", b2)
// 所以最終將uint32轉(zhuǎn)成[]byte數(shù)組輸出為
// [0 0 1 1]
}
小端模式下
在上面我們講過备典,小端剛好和大端相反的异旧,所以在轉(zhuǎn)成小端模式的時候,只要將[]byte數(shù)組的下標(biāo)首尾對換一下位置就可以了
func f3() {
var v3 uint32
var b3 [4]byte
v3 = 257
// 將 256轉(zhuǎn)成二進(jìn)制就是
// | 00000000 | 00000000 | 00000001 | 00000001 |
// | b3[0] | b3[1] | b3[2] | [3] | // 這里表示b3數(shù)組每個下標(biāo)里面存放的值
// 這里直接使用將uint32l強(qiáng)轉(zhuǎn)成uint8
// | 00000000 0000000 00000001 | 00000001 直接轉(zhuǎn)成uint8后等于 1
// |---這部分go在強(qiáng)轉(zhuǎn)的時候扔掉---|
b3[0] = uint8(v3)
// | 00000000 | 00000000 | 00000001 | 00000001 | 右移8位 轉(zhuǎn)成uint8后等于 1
// 下面是右移后的數(shù)據(jù)
// | | 00000000 | 00000000 | 00000001 |
b3[1] = uint8(v3 >> 8)
// | 00000000 | 00000000 | 00000001 | 00000001 | 右移16位 轉(zhuǎn)成uint8后等于 0
// 下面是右移后的數(shù)據(jù)
// | | | 00000000 | 00000000 |
b3[2] = uint8(v3 >> 16)
// | 00000000 | 00000000 | 00000001 | 00000001 | 右移24位 轉(zhuǎn)成uint8后等于 0
// 下面是右移后的數(shù)據(jù)
// | | | | 00000000 |
b3[3] = uint8(v3 >> 24)
fmt.Printf("%+v\n", b3)
// 所以最終將uint32轉(zhuǎn)成[]byte數(shù)組輸出為
// [1 1 0 0 ]
}
go轉(zhuǎn)換demo
案例1
//整形轉(zhuǎn)換成字節(jié)
func IntToBytes(n int) []byte {
x := int32(n)
bytesBuffer := bytes.NewBuffer([]byte{})
binary.Write(bytesBuffer, binary.BigEndian, x)
return bytesBuffer.Bytes()
}
//字節(jié)轉(zhuǎn)換成整形
func BytesToInt(b []byte) int {
bytesBuffer := bytes.NewBuffer(b)
var x int32
binary.Read(bytesBuffer, binary.BigEndian, &x)
return int(x)
}
案例2
arg := uint32(115)
bytes := make([]byte, 4)
binary.BigEndian.PutUint32(bytes, arg)
源碼
func (bigEndian) PutUint32(b []byte, v uint32) {
_ = b[3] // early bounds check to guarantee safety of writes below
b[0] = byte(v >> 24)
b[1] = byte(v >> 16)
b[2] = byte(v >> 8)
b[3] = byte(v)
}
相關(guān)面試題
1.mysql 中int(11)最大最小存儲多少
| tinyint | smallint | mediumint | int | bigint |
| 1 | 2 | 3 | 4 | 8 | 占用字節(jié)
1字節(jié)(Byte)占8個位(bit)提佣,1個位表示一個二進(jìn)制的0或者1吮蛹,
1個字節(jié)能表示最大的整數(shù)是255,怎么來的拌屏?
1個字節(jié)就是8個二進(jìn)制的1 “11111111” 轉(zhuǎn)換成十進(jìn)制就是255
1*2^7+1*2^6+1*2^5+1*2^4+1*2^3+1*2^2+1*2^1+1*2^0=255
int 占用4個字節(jié) 1個字節(jié)是8個位(bit) 即等于32個位(bit)
有符號 int 取值范圍 等于int8 的取值范圍 詳見下面附屬表2.取值范圍
-2^31 (-2,147,483,648) 到 2^31 - 1 (2,147,483,647)
無符號 int 取值范圍 等于uint8 的取值范圍 詳見下面附屬表2.取值范圍
0 到 (2^32) - 1 (4,294,967,295)
tinyint | smallint | mediumint | int | bigint 計算一樣參考
關(guān)于int(11)中的(11)是mysql 中選擇是否填充時使用
當(dāng)設(shè)置填充是假設(shè)存儲值1 表中則顯示為: 00000000001
當(dāng)不設(shè)置填充是假設(shè)存儲值1 表中則顯示為: 1
擴(kuò)展資料
int類型, 占用字節(jié)數(shù)為4byte, 學(xué)過計算機(jī)原理的同學(xué)應(yīng)該知道潮针,字節(jié)(byte)并非是計算機(jī)存儲的最小單位,
還有比字節(jié)(byte)更小的單位倚喂,也就是位(bit)然低,一個位就代表一個0或1; 8個位組成一個字節(jié)务唐;一般字節(jié)用大寫B(tài)來表示byte雳攘,位用小寫b來表示bit。
附屬表1.ASCII碼表
附屬表2.取值范圍