指针、运算符和位运算
[toc]
😶🌫️go语言官方编程指南:https://golang.org/#
go语言的官方文档学习笔记很全,推荐去官网学习
😶🌫️我的学习笔记:github: https://github.com/3293172751/golang-rearn
区块链技术(也称之为分布式账本技术),是一种互联网数据库技术,其特点是去中心化,公开透明,让每一个人均可参与的数据库记录
❤️💕💕关于区块链技术,可以关注我,共同学习更多的区块链技术。博客http://nsddd.top
1.指针
1.1基本介绍
- 基本数据类型,变量存的就是值,也叫值类型
Go 语言的取地址符是 &
,放到一个变量前使用就会返回相应变量的内存地址。
package main
import "fmt"
func main(){
var i int = 10
Plantln("i的地址是:",&i)
//熟悉C/C++知道&也是取地址符
}
在内存的情况:
1.2 指针变量
指针变量指向的是一个地址,这个地址指向的空间才是值。
var ptr *int = &i
解释:
ptr是一个指针变量,类型是一个*int类型,==是一个地址==
ptr本身的值是&i
1.3 指针的使用流程
✏️指针的使用流程如下:
- 定义指针变量。
- 为指针变量赋值。
- 访问指针变量中指向地址的值。
⚠️在指针类型前面加上 *
号(前缀)来获取指针所指向的内容。
💡简单的一个案例如下:
package main
import "fmt"
func main() {
var a int= 20 // 声明实际变量
var ip *int /* 声明指针变量 */
ip = &a /* 指针变量的存储地址 */
//&a和ip是一样的,都是地址
fmt.Printf("a 变量的地址是: %x\n", &a )
// 指针变量的存储地址
fmt.Printf("ip 变量储存的指针地址: %x\n", ip )
// 使用指针访问值
fmt.Printf("*ip 变量的值: %d\n", *ip )
}
以上实例执行输出结果为:
a 变量的地址是: 20818a220 #不可预料的地址
ip 变量储存的指针地址: 20818a220
*ip 变量的值: 20
1.4 Go 空指针
当一个指针被定义后没有分配到任何变量时,它的值为 nil
。
nil
指针也称为空指针。nil
在概念上和其它语言的null
、None
、nil
、NULL
一样,都指代零值或空值。- 一个指针变量通常缩写为 ptr。
💡简单的一个案例如下:
package main
import "fmt"
func main() {
var ptr *int
fmt.Printf("ptr 的值为 : %x\n", ptr )
}
以上实例输出结果为:
ptr 的值为 : 0
空指针判断:
if(ptr != nil) /* ptr 不是空指针 */
if(ptr == nil) /* ptr 是空指针 */
1.5指针变量的修改
num := 9
var ptr *int
ptr = &num
*ptr = 10 //此时会将num的值修改为1
❤️ 由此可见,golang 相对C语言和c++的指针,相对简单而且容易理解
小方法:
当我们不用包的时候,可以在前面加一个_
表示忽略,但是如果你没用到也没有忽略的化,那程序就是报错(前面所写go特性)
package main
import(
_ "fmt"
)
2. 值类型和引用类型
- **值类型:都有对应的指针类型,形式为 数据形式,比如int 的对应的指针就是 int ,* float32是float对应的指针类型
- 值类型包括:基本数据类型 int系统,float系列,bool,string,struct和结构体。
- 引用类型:指针,slice切片,map,管道chan,interface等都是
2.1 区别/使用:
值类型:变量可以之间存储值,内存通常在栈中分配
引用类型:变量存储的是一个地址,这个地址对应的空间才是真正存储数据(值),内存通常在堆上分配,当没有任何变量引用这个地址时,这个地址对应的数据空间就成为一个垃圾,由GC回收
eng:内存是由栈区和堆区组成
3. 标识符的命名规范
- Golang对各种变量、方法、函数等命名时使用的字符序列称之为标识符
- 凡是自己可以其名字的地方都叫标识符
3.1 标识符的命名规范
二十六个字母组成
数字不能开头
Golang严格区分大小写
var num int = 10 var Num int = 100 //num 和 Num是不同的变量
标识符不能有空格,但是可以用
__
“__"
本身在Golang中是一个特殊的标识符,表示var _ int = 40 //错误 var a_ai int = 40 //正确
不能使用系统保留的关键字作为标识符(前面讲过25个标识符)
3.2 标识符命名注意事项
包名:Golang 每一个go文件 都归属于一个包,包名应该保持和目录尽量一致
变量名、函数名、常量名:采用驼峰法
- 第一个字母小写,第二个字母大写
- var goodPrice float32 = 1234.234
==变量名、函数名、常量名首字母大写,则可以被其他包访问; 如果首字母小写,则只能在本包中使用==(注意❤️ -- 参考其他语言:理解为首字母大写是公开的(pubilc),首字母小写是私有的(private))
4. Go算数运算符
下表列出了所有Go语言的算术运算符。假定 A 值为 10,B 值为 20。
运算符 | 描述 | 实例 |
---|---|---|
+ | 相加 | A + B 输出结果 30 |
- | 相减 | A - B 输出结果 -10 |
* | 相乘 | A * B 输出结果 200 |
/ | 相除 | B / A 输出结果 2 |
% | 求余 | B % A 输出结果 0 |
++ | 自增 | A++ 输出结果 11 |
-- | 自减 | A-- 输出结果 9 |
和其他语言相似,不举例。
细节:
小数问题:
x := 19/5
==此时x=3 ,向下取整==
==在Golang,++和--只能独立使用==,强制语法统一性和简洁性
在Golang中,++ 或者--只能写在变量后面,不能写在前面
var a int =5 a = i++ //错误,只能独立使用 a = i-- //错误 a++ //正确 ++a //错误 if i++ > 0{ //错误,在if语句中,非独立使用的 fmt.Println("ok") }
5. Go关系运算符
关系运算符也称之为比较运算符,常用于流程控制
结果是bool类型,要么是true要么是false
下表列出了所有Go语言的关系运算符。假定 A 值为 10,B 值为 20。
运算符 | 描述 | 实例 |
---|---|---|
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 | (A == B) 为 False |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 | (A != B) 为 True |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 | (A > B) 为 False |
< | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 | (A < B) 为 True |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 | (A >= B) 为 False |
<= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 | (A <= B) 为 True |
6. 逻辑运算符
表列出了所有Go语言的逻辑运算符。假定 A 值为 True,B 值为 False。
运算符 | 描述 | 实例 |
---|---|---|
&& | 逻辑 AND 运算符。 如果两边的操作数都是 True,则条件 True,否则为 False。 | (A && B) 为 False |
|| | 逻辑 OR 运算符。 如果两边的操作数有一个 True,则条件 True,否则为 False。 | (A || B) 为 True |
! | 逻辑 NOT 运算符。 如果条件为 True,则逻辑 NOT 条件 False,否则为 True。 | !(A && B) 为 True |
和其他语言都差不多🐶🐶🐶
同样的,为||
的时候,当左边的为真,就不看右边的了。当为&&
时候,左边为假,那么右边也不需要看了
6.1 实例
package main
import "fmt"
func main() {
var a bool = true
var b bool = false
if ( a && b ) {
fmt.Printf("第一行 - 条件为 true\n" )
}
if ( a || b ) {
fmt.Printf("第二行 - 条件为 true\n" )
}
/* 修改 a 和 b 的值 */
a = false
b = true
if ( a && b ) {
fmt.Printf("第三行 - 条件为 true\n" )
} else {
fmt.Printf("第三行 - 条件为 false\n" )
} o'o
if ( !(a && b) ) {
fmt.Printf("第四行 - 条件为 true\n" )
}
}
测试:
8. 其他运算符
❤️说明:Go语言明确说明不支持三元运算符
其它语言的三元运算符:
语法为:
条件表达式?表达式1:表达式2
。**说明:**问号前面的位置是判断的条件,判断结果为bool型,为true时调用表达式1,为false时调用表达式2。
其逻辑为:“如果条件表达式成立或者满足则执行表达式1,否则执行第二个。”常用在设置默认值,例如某个值不一定存在,则判断这个值是否存在,不存在给默认值(表达式2)。
8.2 Golang三元运算符的实现使用if判断
i := 10
j := 20
if i>j{
n := i
}else{
n := j
}
fmt.Paarintln(n)
/*传统编程语言实现:
n = i > j ? i : j
*/
8. 键盘输入
参考第二天的最后笔记
8.1步骤:
- 导入fmt包
- 调用fmt包的fmt.Scanln() 或者 fmt.Scanf()
💡简单的一个案例如下:
package main
import "fmt"
fun main(){
var name string
var age int
var mf bool
fmt.Println(请输入姓名,年龄,性别)
fmt.Scanln(&name)
fmt.Scanln(&age)
fmt.Scanln(&mf)
//方式二
fmt.Scanf("%s %d %f %t",&name,&age,&mf)
}
9. 进制
9.1 基本的输出方式
%b 表示为二进制
%c 该值对应的unicode码值
%d 表示为十进制
%o 表示为八进制
%q 该值对应的单引号括起来的go语法字符字面值,必要时会采用安全的转义表示
%x 表示为十六进制,使用a-f
%X 表示为十六进制,使用A-F
%U 表示为Unicode格式:U+1234,等价于"U+%04X"
9.2 补充python中进制的转换
在ipython模式下的进制转化是我认为最方便的一种
- 10进制转16进制:
hex(10)
- 10进制转8进制:
oct(10)
- 10进制转2进制:
bin(10)
- 16进制转10进制:
int('0x5',16)
- 8进制转10进制:
int('0o5',8)
- 2进制转10进制:
int('0b1100',2)
10 .位运算
位运算符对整数在内存中的二进制位进行操作。
下表列出了位运算符 &, |, 和 ^ 的计算:
p | q | p & q | p | q | p ^ q |
---|---|---|---|---|
0 | 0 | 0 | 0 | 0 |
0 | 1 | 0 | 1 | 1 |
1 | 1 | 1 | 1 | 0 |
1 | 0 | 0 | 1 | 1 |
假定 A = 60; B = 13; 其二进制数转换为:
A = 0011 1100
B = 0000 1101
-----------------
A&B = 0000 1100
A|B = 0011 1101
A^B = 0011 0001
10.1 实例
package main
import "fmt"
func main() {
var a int = 21
var c int
c = a
fmt.Printf("第 1 行 - = 运算符实例,c 值为 = %d\n", c )
c += a
fmt.Printf("第 2 行 - += 运算符实例,c 值为 = %d\n", c )
c -= a
fmt.Printf("第 3 行 - -= 运算符实例,c 值为 = %d\n", c )
c *= a
fmt.Printf("第 4 行 - *= 运算符实例,c 值为 = %d\n", c )
c /= a
fmt.Printf("第 5 行 - /= 运算符实例,c 值为 = %d\n", c )
c = 200;
c <<= 2
fmt.Printf("第 6行 - <<= 运算符实例,c 值为 = %d\n", c )
c >>= 2
fmt.Printf("第 7 行 - >>= 运算符实例,c 值为 = %d\n", c )
c &= 2
fmt.Printf("第 8 行 - &= 运算符实例,c 值为 = %d\n", c )
c ^= 2
fmt.Printf("第 9 行 - ^= 运算符实例,c 值为 = %d\n", c )
c |= 2
fmt.Printf("第 10 行 - |= 运算符实例,c 值为 = %d\n", c )
}
~
编译:
10.2 原码、补码、反码
❤️注意:在计算机运算的时候,都是以补码的方式来运算的
10.3 golang 中的位运算
Go 语言支持的位运算符如下表所示。假定 A 为60,B 为13:
运算符 | 描述 | 实例 |
---|---|---|
& | 按位与运算符"&"是双目运算符。 其功能是参与运算的两数各对应的二进位相与。 | (A & B) 结果为 12, 二进制为 0000 1100 |
| | 按位或运算符"|"是双目运算符。 其功能是参与运算的两数各对应的二进位相或 | (A | B) 结果为 61, 二进制为 0011 1101 |
^ | 按位异或运算符"^"是双目运算符。 其功能是参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 | (A ^ B) 结果为 49, 二进制为 0011 0001 |
<< | 左移运算符"<<"是双目运算符。左移n位就是乘以2的n次方。 其功能把**"<<"左边的运算数的各二进位全部左移若干位,由"<<"右边的数指定移动的位数,高位丢弃,低位补0**。 | A << 2 结果为 240 ,二进制为 1111 0000 |
>> | 右移运算符">>"是双目运算符。右移n位就是除以2的n次方。 其功能是把**">>"左边的运算数的各二进位全部右移若干位**,">>"右边的数指定移动的位数。 | A >> 2 结果为 15 ,二进制为 0000 1111 |
💡简单的一个案例如下:
先求补码,再计算
正数的补码与原码相同。负数的补码的符号位为1,其余位为该数绝对值的原码按位取反,然后整个数加1。
package main
import "fmt"
func main(){
fmt.Parintln(2&3) //2
fmt.Parintln(2|3) //3
fmt.Parintln(2^3) //1
}
输出
2
3
1
位移运算:也遵守按照补码计算
a := 1 >> 2 //0
c := 1 << 2 //4
fmt.Println("a=",a,"c=",c)
分析:
c:0000 0001 => 0000 0100 = 4
a:0000 0001 => 0000 0000 = 0
11. 流程控制
❤️❤️❤️ 为了更好的区分理解,这部分将和python一同介绍
程序由上到下逐步执行(参考python交互式脚本语言) ,中间没有任何的判断和跳转。
变量应该先声明后定义,再使用。
11.1 Go分支控制if -else
单分支
双分支
多分支
注意❤️
**1. 和C/C++不同,在Golang中就算只写一行代码,也需要有{} **
2. Go中的if还有一个强大之处是在条件判断语句中允许申明一个变量,这个变量的作用域只能在该条件逻辑块内,在其他地方是不起作用的
if age := 20;age > 18{ //在此处定义变量而且可以直接使用 类似于 int i = 0
fmt.Println("你的年龄是多少啊?")
}
Go 编程语言中 if 语句的语法如下:
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
}
Go 编程语言中 if...else 语句的语法如下:
if 布尔表达式 {
/* 在布尔表达式为 true 时执行 */
} else {
/* 在布尔表达式为 false 时执行 */
}
If 在布尔表达式为 true 时,其后紧跟的语句块执行,如果为 false 则执行 else 语句块。
Go 编程语言中 if...else 语句的语法如下:
if 布尔表达式 1 {
/* 在布尔表达式 1 为 true 时执行 */
if 布尔表达式 2 {
/* 在布尔表达式 2 为 true 时执行 */
}
}
你可以以同样的方式在 if 语句中嵌套 else if...else 语句
但是不建议嵌套过多,尽量控制在三层
案列:
定义两个变量int32 ,判断二者之和,是否能被3又能被5整除,打印提示信息
//定义两个变量int32 ,判断二者之和,是否能被3又能被5整除,打印提示信息
package main
import (
"fmt"
)
var a int32 = 10
var b int32 = 15
func main(){
if (a+b)%3==0 && (a+b)%5 ==0{
fmt.Println("该数符合要求")
}else{ //注意格式,括号不可随意移位
fmt.Println("该数木满足要求")
}}
判断闰年:
if year:= 2019;(year %4 ==0 && year %100 !=0)||year%400 == 0{
fmt.Println(year,"是闰年")
} //直接定义
注意:使用数字运算的时候要引入math包进行数字运算
11.2 补充:python分支控制if -else
python语句要注意缩进问题
# -\*- coding: UTF-8 -\*-** **#****定义中文**
print( "你好,世界" )
判断语句
if 判断条件 1:
执行语句1
elif判断语句2:
执行语句2
else:
执行语句3
import random
:引入随机库
x = random.randint(0,3)
:表示随机生成0~3数字
In [13]: if x != 90:
...: print("该随机数并不是理想的")
...: elif x == 80:
...: print("该随机数就是理想的")
...: else:
...: i = 10
...: if i>10:
...: print("i大于10")
...: elif i<10:
...: print("i小于10")
...: else:
...: print("i等于10")
...:
END 链接
✴️版权声明 © :本书所有内容遵循CC-BY-SA 3.0协议(署名-相同方式共享)©