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等等,一般不使用预定义标识符,所有如下:

保留关键字:

break default func interfance select
case defer go map struct
chan else goto package switch
const fallthrought if range type
continue for import return var

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

append bool byte cap close complex
complex64 complex128 uint16 copy false float32
float64 imag int int8 int16 uint32
int32 int64 iota len make new
nil panic uint64 print println real
recover string true uint uint8 uintprt

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。

猜你喜欢

转载自blog.csdn.net/Destinyxzc/article/details/127837677
今日推荐