本篇前瞻

好的,现在你已经来到一个新的小结,在这里你将学习到go语言的重要内容,习得go 25个关键字中的12个:var, const, if, else, switch, case, default, fallthrough, for, break, goto, continue,即在顺序结构学习var,const,在分支结构中学习if, else, switch, case, default, fallthrough,在循环结构中学习for, break, goto, continue。另外你最好注册一个Leetcode账号.

Leetcode习题9

让我们再来看下这个例子,这个是一个比较好的例子,里面包含了顺序,分支以及循环的所有控制结构

题目描述

9. 回文数

给你一个整数 x ,如果 x 是一个回文整数,返回 true ;否则,返回 false

回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。

代码编写

func isPalindrome(x int) bool {
if (x < 0) { //分支结构
return false
}
x64 := x //顺序结构
px64 := 0
for x64 != 0 { //循环结构
px64 = px64*10 + x64%10 // 顺序结构
x64 /= 10
}
return px64 == x
}

你在这个道题目中能看到所有的控制结构:顺序结构,分支结构,循环机构

控制结构

顺序结构(Sequence)

声明和赋值

在顺序结构中声明和赋值是很重要的

var可以声明一个变量,而const则声明一个常量

package main

import "fmt"

func main() {
var i1 int //声明变量,默认值为0
var i2 int = 1 //声明变量,初始化为1
i3 := 2 //这是最常用的声明和初始化手段
fmt.Println(i1, i2, i3)
i4 := i2 + i3 //使用运算表达式赋值
i3 *= i4 //使用运算表达式赋值
fmt.Println(i3, i4)
const ci1 int = 13 //声明常量,无法
fmt.Println(ci1)
x, y, z := 100, 101, 102 //多返回值
fmt.Println(x, y, z) //打印结果
}

输出:

0 1 2
6 3
13
100 101 102

这里仅仅举例了整形int的声明

多返回值赋值

x,y,z := 0,1,2

go语言允许这样多返回值赋值赋值方式,再挖个坑,原因会在介绍函数时说明一下。

运算符

算术运算符

++ --
自增1 自减1
+= -= *= /= %=
自增 自减 自乘 自除 自模,取余
+ - * / %
加法 减法 乘法 除法 模,取余

注意: 例如如3/2 在整型中是整除即3/2=1,在浮点型是3.0/2.0=1.5,模运算智能用于整数

位运算符

<< >> & | ^
左移 右移 亦或
<<= >>= &= |= ^=
自左移 自右移 自与 自或 自亦或

位运算符几乎我们这篇实用的编程用不到,但是这个概念也很重要,计算机底层事实上是这样工作的,这里在挖个坑,后面会介绍位运算的相关leetcode题目,你会看到它的威力。

逻辑运算

&& || == !=
相等 不等于
>= <= > <
大于等于 小于等于 大于 小于

这些会在分支语句中大放异彩。

分支结构

if 语句

if 语句有if,if-else以及if-else if-else结构,如下所示:

package main

import "fmt"

func main() {
var input int
fmt.Printf("请输入分数:")
fmt.Scanf("%d", &input)
if input < 60 { //if
fmt.Println("1.不合格")
} if input < 60 { //if-else
fmt.Println("2.不合格")
} else{
fmt.Println("2.合格")
} if input < 60 {//if-else if-else
fmt.Println("3.不合格")
} else if input < 70 {
fmt.Println("3.合格")
} else if input < 85 {
fmt.Println("3.良好")
} else {
fmt.Println("3.优秀")
}
}

结果如下:

请输入分数:59
1.不合格
2.不合格
3.不合格

switch 语句

事实上switch 语句比if语句更为强大,在有多个分支时更为符合go语言的风格,完整代码如下:

package main

import "fmt"

func main() {
var i int
fmt.Printf("请输入分数:")
fmt.Scanf("%d\n", &i)
switch {
case i < 60: //单个逻辑表达式
fmt.Println("不合格")
case i < 70:
fmt.Println("合格")
case i < 85:
fmt.Println("良好")
default:
fmt.Println("优秀")
} var c byte
fmt.Printf("请输入等级:")
fmt.Scanf("%c\n", &c) switch c {
case 'E', 'e': //可以有多个选择
fmt.Println("1.不合格")
case 'D', 'd':
fmt.Println("1.基本合格")
case 'C', 'c':
fmt.Println("1.合格")
case 'B', 'b':
fmt.Println("1.良好")
case 'A', 'a':
fmt.Println("1.优秀")
default:
fmt.Println("1.错误的输入")
} switch {
case c == 'E', c == 'e': //可以有多个表达式
fmt.Println("2.不合格")
case c == 'D', c == 'd':
fmt.Println("2.基本合格")
case c == 'C', c == 'c':
fmt.Println("2.合格")
case c == 'B', c == 'b':
fmt.Println("2.良好")
case c == 'A', c == 'a':
fmt.Println("2.优秀")
default:
fmt.Println("2.错误的输入")
} switch {
case c == 'E':
fmt.Println("3.不合格")
fallthrough //fallthrough会执行下一个case区块
case c == 'e':
fmt.Println("3.真的不合格")
case c == 'D', c == 'd':
fmt.Println("3.基本合格")
case c == 'C', c == 'c':
fmt.Println("3.合格")
case c == 'B', c == 'b':
fmt.Println("3.良好")
case c == 'A', c == 'a':
fmt.Println("3.优秀")
default:
fmt.Println("3.错误的输入")
} var in interface{} = i
switch data := in.(type) { //类型推断
case int:
fmt.Printf("int: %v\n", data)
case uint:
fmt.Printf("uint: %v\n", data)
default:
fmt.Printf("type: %T\n", data)
}
}

结果如下:

请输入分数:90
优秀
请输入等级:E
1.不合格
2.不合格
3.不合格
3.真的不合格
int: 90

逻辑表达式

注意case可以是单个或多个逻辑表达式

	switch {
case c == 'E', c == 'e': //可以有多个表达式
fmt.Println("2.不合格")。
case c == 'D', c == 'd':
fmt.Println("2.基本合格")
case c == 'C', c == 'c':
fmt.Println("2.合格")
case c == 'B', c == 'b':
fmt.Println("2.良好")
case c == 'A', c == 'a':
fmt.Println("2.优秀")
default:
fmt.Println("2.错误的输入")
}

fallthrough

fallthrough会执行下一个case区块

	switch {
case c == 'E':
fmt.Println("3.不合格")
fallthrough //fallthrough会执行下一个case区块
case c == 'e':
fmt.Println("3.真的不合格")
case c == 'D', c == 'd':
fmt.Println("3.基本合格")
case c == 'C', c == 'c':
fmt.Println("3.合格")
case c == 'B', c == 'b':
fmt.Println("3.良好")
case c == 'A', c == 'a':
fmt.Println("3.优秀")
default:
fmt.Println("3.错误的输入")
}

类型推断

这个是一个强大的方式,它可以用于推断go语言的接口的类型,不过现在只能简单那介绍一下,你可以将interface{}可以表达任何类型

	var in interface{} = i
switch data := in.(type) { //类型推断
case int:
fmt.Printf("int: %v\n", data)
case uint:
fmt.Printf("uint: %v\n", data)
default:
fmt.Printf("type: %T\n", data)
}

循环语句

循环语句只有for

package main

import "fmt"

func main() {
var input int
fmt.Printf("请输入分数(0-5):")
fmt.Scanf("%d", &input) for i := 0; i < 5; i++ { //正常的for
fmt.Println("loop1:", i) if i < 2 {
continue //跳过本次执行
}
if i == input {
fmt.Println("loop1: break") //跳出本层循环
break
}
}
i := 0
Loop:
for i < 5 { //去掉;的for循环
fmt.Println("loop2:", i)
for j := 0; j < 5; j++ {
if j == input {
fmt.Println("loop2: break Loop") //跳出Loop标记的循环
break Loop
}
if j == 1 {
break //跳出本层循环
}
}
i++
}
i = 0
for ; i < 5; i++ { //空缺一个元素并带有;的for循环
fmt.Println("loop3:", i)
for j := 0; j < 5; j++ {
if j < 2 {
continue
}
if j == input {
goto Exit //跳出到Exit
}
}
}
return
Exit:
fmt.Println("loop3: Exit")
}

结果如下:

请输入分数(0-5):1
loop1: 0
loop1: 1
loop1: 2
loop1: 3
loop1: 4
loop2: 0
loop2: break Loop
loop3: 0
loop3: 1
loop3: 2
loop3: 3
loop3: 4 请输入分数(0-5):2
loop1: 0
loop1: 1
loop1: 2
loop1: break
loop2: 0
loop2: 1
loop2: 2
loop2: 3
loop2: 4
loop3: 0
loop3: Exit

continue

跳过本次循环

break

没有加标签的就是跳过本层循环

加标签的就是跳过被标签标记的循环

goto

跳到被标签标记的循环,使用goto在处理一些同意的错误或者统一的出口而降低代码的冗余,增加代码可读性。这里挖个坑,这里会在go-etl展示goto的魅力

注意:很多书籍指出goto会破环代码结构,降低代码可读性,那是因为这些书籍讲述使用goto的场景错了

Leetcode习题69

我们以leetcode习题开始,而现在有以一道Leetcode习题结束

题目描述

69. x 的平方根

给你一个非负整数 x ,计算并返回 x算术平方根

由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。

注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5

题目分析

这道题会比Leetcode习题1更加困难些,这次数据范围是int32的非负整数范围,由于不能使用指数函数和算符,为此,在这里我们需要使用二分法,即通过二分[a,b](mid = a + (b-a)/2, 第一轮a=0,b=x)去获取mid=x/2,如果mid*mid<x 那么此时二分[a,mid-1],反之二分[mid+1,b], 这样不断二分下去直到 mid*mid=x或者a<b。好的,这样我们获得了解题思路,但是还有个问题,选择y的数据类型是什么,如果选择int32,那么相乘必然超过int32, 为此我们必须选择int64,注意:在Leetcode习题9中得出了结论,int是64位的,所以不用改为int64

代码编写

func mySqrt(x int) int {
a, b := 0, x //多返回值赋值
for a <= b { // 无;结构的for
mid := a + (b-a)/2 //二分区间
if mid*mid == x { //if语句
return mid
}
if mid*mid < x { //if-else语句
a = mid + 1 //选择较大的区间
} else {
b = mid - 1 //选择较小的区间
}
}
return b
}

本篇小结

恭喜你已经完成了所有控制结构的学习,你以及知道了所有控制结构用到的保留字和注意点。另外,通过Leetcode习题69和Leetcode习题9,你已经知道在编程时选择数据类型的重要性,并且练习了所有控制结构。这里的相关代码放在go语言学习的go-base/3中,请下载后进行实际的练习

注意:之后的Leetcode题目解答以及使用工具的编程中,数据类型的选择以及控制结构的应用是非常重要的,也是最为基础的

下篇预告

go语言复合类型

3.你所不知道的go语言控制语句——Leetcode习题69的更多相关文章

  1. 你所不知道的五件事情--java.util.concurrent(第二部分)

    这是Ted Neward在IBM developerWorks中5 things系列文章中的一篇,仍然讲述了关于Java并发集合API的一些应用窍门,值得大家学习.(2010.06.17最后更新) 摘 ...

  2. 你所不知道的Html5那些事(一)

    文章简介:       关于html5相信大家早已经耳熟能详,但是他真正的意义在具体的开发中会有什么作用呢?相对于html,他又有怎样的新的定义与新理念在里面呢?为什么一些专家认为html5完全完成后 ...

  3. 你所不知道的C++

    C++与C的不同 C++从诞生之初就号称和C是兼容的,正是这种兼容,使C++得以迅猛发展,然而也正是这种兼容,让C++背上了沉重的历史包袱.且不论其利弊,让我们来看看C++在兼容C的那部分中,与C语言 ...

  4. [转帖]你所不知道的C和C++运行库

    [C-C++]你所不知道的C和C++运行库 https://blog.csdn.net/humanking7/article/details/85887884 原作者也是转的blog 最近一个物理机上 ...

  5. js值----你所不知道的JavaScript系列(6)

    1.数组 在 JavaScript 中,数组可以容纳任何类型的值,可以是字符串.数字.对象(object),甚至是其他数组(多维数组就是通过这种方式来实现的) .----<你所不知道的JavaS ...

  6. js类型----你所不知道的JavaScript系列(5)

    ECMAScirpt 变量有两种不同的数据类型:基本类型,引用类型.也有其他的叫法,比如原始类型和对象类型等. 1.内置类型 JavaScript 有七种内置类型: • 空值(null) • 未定义( ...

  7. Android Context完全解析,你所不知道的Context的各种细节

    Context相信所有的Android开发人员基本上每天都在接触,因为它太常见了.但是这并不代表Context没有什么东西好讲的,实际上Context有太多小的细节并不被大家所关注,那么今天我们就来学 ...

  8. 你所不知道的 CSS 阴影技巧与细节 滚动视差?CSS 不在话下 神奇的选择器 :focus-within 当角色转换为面试官之后 NPOI 教程 - 3.2 打印相关设置 前端XSS相关整理 委托入门案例

    你所不知道的 CSS 阴影技巧与细节   关于 CSS 阴影,之前已经有写过一篇,box-shadow 与 filter:drop-shadow 详解及奇技淫巧,介绍了一些关于 box-shadow  ...

  9. 你所不知道的库存超限做法 服务器一般达到多少qps比较好[转] JAVA格物致知基础篇:你所不知道的返回码 深入了解EntityFramework Core 2.1延迟加载(Lazy Loading) EntityFramework 6.x和EntityFramework Core关系映射中导航属性必须是public? 藏在正则表达式里的陷阱 两道面试题,带你解析Java类加载机制

    你所不知道的库存超限做法 在互联网企业中,限购的做法,多种多样,有的别出心裁,有的因循守旧,但是种种做法皆想达到的目的,无外乎几种,商品卖的完,系统抗的住,库存不超限.虽然短短数语,却有着说不完,道不 ...

  10. 一些你所不知道的VS Code插件

    摘要: 你所不知道的系列. 原文:提高 JavaScript 开发效率的高级 VSCode 扩展之二! 作者:前端小智 Fundebug经授权转载,版权归原作者所有. 作为一名业余爱好者.专业人员,甚 ...

随机推荐

  1. 2020-12-30:生产环境 CPU 占用过高,你如何解决?

    福哥答案2020-12-30: 1.top + H 指令找出占用 CPU 最高的进程的 pid. 2.top -H -p.在该进程中找到,哪些线程占用的 CPU 最高的线程,记录下 tid. 3.js ...

  2. 2021-06-04:给定三个参数:二叉树的头节点head,树上某个节点target,正数K,从target开始,可以向上走或者向下走。返回与target的距离是K的所有节点。

    2021-06-04:给定三个参数:二叉树的头节点head,树上某个节点target,正数K,从target开始,可以向上走或者向下走.返回与target的距离是K的所有节点. 福大大 答案2021- ...

  3. 2021-05-26:给定一个char[][] matrix

    2021-05-26:给定一个char[][] matrix,也就是char类型的二维数组,再给定一个字符串word,可以从任何一个某个位置出发,可以走上下左右,能不能找到word?char[][] ...

  4. status能否设置为布尔值类型,前端采用复选框形式

    是的,可以将status设置为布尔类型,这样可以在前端使用复选框形式展示.在模型中的定义可以如下: class Acceptance(models.Model): # ... status = mod ...

  5. 人手一个 Midjourney,StableStudio 重磅开源!

    人手一个 Midjourney,StableStudio 重磅开源! Stability AI 公司在上个月 19 号推出了 Alpha 版本 StableLM 大语言模型,包含了 30 亿和 70 ...

  6. adb server version (31) doesn't match this client (41); killing...

    使用用 adb devices 提示如下错误 C:\Users\Lenovo>adb devices adb server version (31) doesn't match this cli ...

  7. Python 标准类库-并发执行之multiprocessing-基于进程的并行

    实践环境 Python3.6 介绍 multiprocessing是一个支持使用类似于线程模块的API派生进程的包.该包同时提供本地和远程并发,通过使用子进程而不是线程,有效地避开了全局解释器锁.因此 ...

  8. 洛谷 P4859 已经没有什么好害怕的了

    题目描述 学姐 4 了. 有 \(n\) 个糖果和 \(n\) 个药片,它们要进行一一配对.每个糖果或药片都具有互不相同的能量值,要求配对后,糖果比药片能量高的对数,比剩下的对数恰好多 \(k\),求 ...

  9. 【python基础】文件-文件路径

    1.文件路径 我们发现不管是写入还是写出操作,我们提供的都是文件名,其实这里准确说应该是文件路径.当我们简单把文件名传递给open函数时,Python将在当前执行程序的文件所在的目录中查找文件名所代表 ...

  10. 【后端面经-Java】AQS详解

    目录 1. AQS是什么? 2. AQS核心思想 2.1 基本框架 2.1.1 资源state 2.1.2 CLH双向队列 2.2 AQS模板 3. 源码分析 3.1 acquire(int) 3.1 ...