Go语言学习笔记(三)---指针,运算符及流程控制

4.2.8 指针

基本介绍:1)基本数据类型,变量存的就是值,也叫值类型。2)获取变量的地址,用&。3)指针类型,指针变量存的是一个地址,这个地址指向的空间存的才是值。4)获取指针类型所指向的值,使用:*。

使用细节:值类型都有对应的指针类型,形式为数据类型,比如 int的对应的指针就是int, float32对应的指针类型就是float32,依次类推;

值类型包括int,float,bool string,数组,struct;变量直接存储,内存通常在栈中分配

引用类型包括:指针、slice切片、map、管道chan、interface等,变量存储的是一个地址,这个地址对应的空间才真正存储数据值,内存通常在堆上分配,没有任何变量引用地址是,该地址对应数据空间成为垃圾,由GC(Garbage Collection)来回收。

func Zhizhen() {
	var num1 int = 10
	//&num1用于获取存放的地址
	fmt.Println("num1的地址是", &num1)
	//1. ptr是一个指针变量;2. ptr的类型是*int;3. ptr本身的值为&num1
	//ptrnum1本身值为num1的地址,&获取指针的值,*获取指针指向的值
	var ptrnum1 *int = &num1
	fmt.Println("ptrnum1值为:", ptrnum1)
	fmt.Println("ptrnum1的地址为:", &ptrnum1)
	fmt.Println("ptrnum1指向的值为:", *ptrnum1)
	//直接修改num1的值
	*ptrnum1 = 20
	fmt.Println("ptrnum1指向的值为:", *ptrnum1)
}
4.2.9 标识符的命名规范

对各种变量,方法,函数等命名时使用的字符序列成为标识符(可以自己起名字的地方)

规则:1)由26个字母大小写,0-9,_组成。

2)数字不可开头 1num := 10 //false

3)Golang中严格区分大小写。

4)标识符中不能包含空格

5)不能用系统保留关键字做标识符,比如if,break,while等等,一般不使用预定义标识符,所有如下:

保留关键字:

breakdefaultfuncinterfanceselect
casedefergomapstruct
chanelsegotopackageswitch
constfallthroughtifrangetype
continueforimportreturnvar

预定义标识符(包括基本数据类型和系统内嵌函数)

appendboolbytecapclosecomplex
complex64complex128uint16copyfalsefloat32
float64imagintint8int16uint32
int32int64iotalenmakenew
nilpanicuint64printprintlnreal
recoverstringtrueuintuint8uintprt

6)下划线"_"本身在Go中是一个特殊的标识符,称为空标识符。可以代表任何其它的标识符,但是它对应的值会被忽略(比如:忽略某个返回值)。所以仅能被作为占位符使用,不能作为标识符使用

func biaoshifu() {
	//_用于占位,即返回多个函数值时可以使用
	sum2, _ := getSumAndSub(10, 50) //只返回第二个值
	fmt.Println("sum2=", sum2)
	//可以使用int等数据结构走位变量,但是不推荐
	int := 10
	fmt.Println(int)
}

注意事项:1)包名:package的名字和目录保持一直,不要使用标准库的名字。

2)变量名,函数名,常量名采用驼峰法xxxYyyyZzzz

3)如果变量名、函数名、常量名首字母大写,则可以被其他的包访问;如果首字母小写,则只能在本包中使用(注:可以简单的理解成,首字母大写是公开的,首字母小写是私有的),在golang 没有public , private等关键字。

在这里插入图片描述

4. 3运算符

运算符时一种特殊的符号,用以表示数据的运算、赋值和比较等等,主要分为六大类:

1)算术运算符 2)赋值运算符 3)比较运算符 4)逻辑运算符 5)位运算 6)其他运算符

Golang中不存在三元运算符

4.3.1 算数运算符

对数值类型的变量进行运算(加减乘除)

运算符运算
+正数,加法,字符串相加
-负数,减法
*乘法
/除法(运算都是整数,除后只保留整数部分10/4=2)
%取模
++自增(+1)
自减

注意:

1)除法运算时,整数相除只保留整数部分;需要保留小数部分则需要有浮点数参与运算

2)取模运算本质运算为:a%b = a - a / b * b

3)golang中的++,–只能当作单独语言使用,不能直接赋值a := b++,也不能 i = i ++

4)++,–只能存在与变量后面,不存在++a,–a。(Golang去点c/java中容易混淆的写法)

func yunsuanfu() {
	/*除法*/
	//整数相除只保留整数部分
	fmt.Println(10 / 4) //输出2
	//如果需要保留小数部分,则需要有浮点数参与运算
	fmt.Println(10.0 / 4) //输出2.5
	/*取模*/
	//标准公式为a%b = a - a / b * b
	fmt.Println(10 % 3)
	fmt.Println(-10 % 3) //= -10 - (-10) / 3 * 3 = -10 - (-9) = -1
}
4.3.2 关系运算符

关系运算符的结果都是bool类型,返回值也就是要么是true,要么是false

关系表达式 经常用在if或者循环结构中。

运算符运算
==相等于
!=不等于
<小于
>大于
<=小于等于
>=大于等于

注意:1)返回值只能是true或者是false

2)有关系运算符组成的表达式称为关系表达式

3)”==“表示相等,”=“表示赋值,不能混用,需要特别注意

	/*关系运算符*/
	fmt.Println(9 != 8)  //true
	fmt.Println(10 <= 7) //false
4.3.4 逻辑运算符

用于连接多个条件(关系表达式),最终结果也是bool

&&:逻辑与,两边都为真则真

||:逻辑或,有一个为真则为真

!:逻辑非,逻辑相反

注意:1)&&短路与运算中,如果第一个条件为false,则第二个条件不再判断,最终结果为false

2)||短路或运算中,如果第二个条件为true,则第二个条件不会判断,最终结果为true。

	func test() bool {
	fmt.Println("查看是否输出")
	return true
}
	
	/*逻辑运算符*/
	num2 := 10
	if num2 < 9 && test() {
		fmt.Println("&&后面语句是否执行") //不输出
	}
	if num2 > 9 && test() {
		fmt.Println("&&test()语句是否执行") //既输出test()又输出结果
	}
	if num2 > 9 || test() {
		fmt.Println("||后面语句是否执行") //只输出该语句
	}
4.3.5 赋值运算符

赋值运算符就是将某个运算后的值,付给指定的变量。

运算符描述实例
=简单赋值c = a + b 将a+b的值赋给c
+=相加后赋值c += a :: c = c + a
-=相减后赋值c -= a : c = c - a
*=相乘后赋值c *= a : c = c * a
/=相除后赋值c/-= a : c = c / a
%=取模后赋值c %= a : c = c %a
<<=左移后赋值c <<= 2 :: c = c << 2
>>=右移后赋值c >>= 2 :: c = c >> 2
&=按位与后赋值c &= 2 :: c = c & 2
^=按位异或后赋值c ^= 2 :: c = c ^ 2
!=按位或后赋值c != 2 :: c = c ! 2

注意:1)运算顺序从右往左:先计算,再赋值

2)赋值运算符的左边只能是变量,右边可以是变量,表达式,常量值

	func test() int {
	return 90
}
	/*赋值运算符*/
	var d int
	d = 8 + 2 * 8
	d = test() + 90
	d = 890
	fmt.Println(d)

不允许使用中间变量交换a和b的值,用a保存a+b,再用a+b-b获得a的值赋给b,再做减法赋给a

	//不使用中间变量交换值
	a := 10
	b := 20
	a = a + b
	b = a - b
	a = a - b
4.3.6 位运算符

计算机进行运算时都是按照二进制补码进行运算的:

运算符描述
&全一为一,否则为0
|有一为一,否则为0
^(异或)两者不同(0/1)才能为一,否则为0
	/*位运算符*/
	fmt.Println(2 & 3)  //2
	fmt.Println(2 | 3)  // 3
	fmt.Println(2 ^ 3)  // 3
	fmt.Println(12 & 3) //0
	fmt.Println(5 | 4)  //5
	fmt.Println(-3 ^ 3) //-2
	/*2的补码 0000 0010
      3的补码 0000 0010
      2&3    0000 0010 ==>2*/
4.3.7 其他运算符
运算符描述实例
&返回变量存储地址&a:给出机器数的实际地址
*指针变量描述为指针
4.3.8运算符优先级

在这里插入图片描述

4.4 程序流程控制

程序运行的流程控制,决定程序是如何执行的,主要有三大流程控制语句:1)顺序控制。2)分支控制。3)循环控制

4.4.1 顺序控制

程序从上到下逐行执行,中间没有任何判断和跳转。也是最基本的程序运行方式,按照程序从上至下的阅读顺序进行运行。

需要注意,定义变量时必须采用合法的前向引用,正确调用之前的内容。

4.4.2 分支控制

主要有三种形式:1)单分支。2)双分支。3)多分支

4.4.2.1 单分支

golang支持再if中,直接定义一个变量

语法:/*if 条件表达式{执行代码块}*/

	//单分支
	var age int
	fmt.Scanln(&age)
	if age >= 18 {
		fmt.Println("已经成年了!")
	}
	//在条件中直接赋值
	if age2 := 20; age2 > 20 {
		fmt.Println("已经不是小孩子了")
	}

4.4.2.2 双分支

双分支指挥执行其中的一条分支

语法:
/*if 条件表达式{
执行代码块
}else{
代码块
}*/
	var a int
	var b int
	if a > 10 {
		fmt.Println("a比10大")
		if b < 10 {
			fmt.Println("b小于10")
		} else {
			fmt.Println("b大于10")
		}
	} else {
		fmt.Println("没什么好说的")
	}
4.4.3 多分支控制
4.4.3.1 一般多分支

如果条件表达式1为真,直接执行代码1;如果1假2真,执行代码2;以此类推,如果都不成立执行else语句【else不是必须的】。

	//多分支控制
	if age > 0 && age <= 10 {
		fmt.Println("还是小孩子")
	} else if age > 10 && age <= 20 {
		fmt.Println("年轻人")
	} else if age > 20 && age <= 30 {
		fmt.Println("年轻人")
	} else {
		fmt.Println("老年人")
	}
	//案例
	b := true
	if b == false {
		fmt.Println("1")
	} else if b {
		fmt.Println("2")
	} else if !b {
		fmt.Println("3")
	} else {
		fmt.Println("4")
	}//输出2
4.4.3.2 嵌套分支

在一个分支结构中又完整的嵌套了另一个完整的分支结构,里面的分支结构称为内层分支,外面的分支结构称为外层分支。

嵌套分支不宜过多,建议控制在3层内。

	var a int
	var b int
	if a > 10 {
		fmt.Println("a比10大")
		if b < 10 {
			fmt.Println("b小于10")
		} else {
			fmt.Println("b大于10")
		}
	} else {
		fmt.Println("没什么好说的")
	}
4.4.4 switch分支控制

switch语句用于基于不同条件执行不同动作,每一个case分支都是唯一的,从上到下逐一测试,知道匹配为止。匹配项后面也不需要加break

基本语法:

switch 表达式{
      case 表达式1,表达式2,...:
      语句块1
      case 表达式3,表达式4,...:
      语句块2
      //多个case
      default:
      语句块
}

执行的流程及注意:

1)先执行表达式,得到值,然后和case的表达式进行比较,如果相等就匹配到,然后执行对应case的语句块,然后退出switch控制。

2)如果case里的表达式都没有匹配成功,则执行default的语句块,执行后退出switch控制。

3)golang中case后的表达式可以有多个,使用逗号间隔

4)golang中的case语句块不需要写break,默认会有,即默认情况下执行完case语句块后,就直接退出该switch控制结构

5)case/swich后是一个表达式(常量,变量,有返回值的函数都可)

6)default一句不是必须的,switch后面也可以不带表达式,类似if-else语句。

7)swich穿透-fallthrough,如果在case语句后面增加fallthrough,则会继续执行下一个case。但是指挥默认穿透一层,直接忽略掉下一层的判定条件。

	var key byte
	fmt.Println("请选择输入一个字母")
	fmt.Scanf("%c",&key)
	switch key {
	case 'a':
		fmt.Println("输入的字母是a")
		fallthrough
	case 'b':
		fmt.Println("输入的字母是b")
	default:
		fmt.Println("输入的字母有问题")
	}
	/*输入a,输出"输入的字母是a 输入的字母是b"*/

8)typeswich:还可以用于判断某个interface变量中实际指向的变量类型。

switch和if的比较:如果判断的具体数值不多,而且符合整数没浮点数,字符串这些类型,建议使用switch;如果对去接判断以及结果为bool类型的判断,使用if。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值