第二章 运算

作者: 牧码人爱跑马 | 来源:发表于2018-07-11 21:12 被阅读0次

2.1 运算符

全部运算符及分隔符列表

运算符及分隔符列表.png

优先级

一元运算符优先级最高,二元则分成五个级别,从高向低分别是:


优先级.png

位运算符

位运算符.png

需要注意的是,位清除是go独有的,和位异或是不同的。它将左右操作数对应二进制位都位1的重置为0(有些类似位图),以达到一次清楚多个标记的目的。

package main

import "fmt"

const (
    exec   byte = 1 << iota
    write
    read
    freeze
)

func main() {
    a := read | write | freeze
    b := read | freeze | exec
    c := a &^ b //相当于a ^ read ^ freeze, 但不包括exec
    fmt.Printf("%04b &^ %04b = %04b\n", a, b, c)

}

输出:

1110 &^ 1101 = 0010

自增

自增自减不再是运算符,只能作为独立语句,不能用于表达式。
另,go中没有形如++a这种。

指针

内存地址和指针是不同的。

内存地址是内存中每个字节单元的唯一编号,而指针则是一个实体。 指针会分配内存空间,相当于一个专门用来保存地址的整型变量。

内存地址和指针.png
  • 取值运算符“&”用于获取对象地址。
  • 指针运算符“*”用于间接引用目标对象。
  • 二级指针*T,如包含包名则协程package.T。

并非所有对象都能进行取地址操作,但变量总是能正确返回。指针运算符为左值时,我们可更新目标对象状态;而为右值时则是为了获取目标状态。

package main

func main() {
    x := 10
    var p *int = &x  //获取地址,保存到指针变量
    *p += 20    //用指针间接引用,并更新对象
    println(&p,p, *p)   //输出指针本身的地址,所存储的地址,以及目标对象
}

输出:

0xc04202ff68 0xc04202ff58 30

    m:=map[string]int{"a":2}
    println(&m["a"])     //报错:不能取地址

指针类型支持相等运算符,但不能作加减法和类型转换。如果两个指针指向同一地址或都为nil,那么他们相等。

   x:=10
   p:=&x
   println(*p) //10
   *p++
   //var p2 *int = *p + 2  //报错,*int和int不能相加
   println(*p)  //11
   p3 := &x
   println(p == p3)

可通过unsafe.Pointer将指针转换为uintpr后进行加减法运算,但可能会造成非法访问。

Pinter 类似C中的void*万能指针,可用来转换指针类型。它能安全持有对象或对象成员,但uintptr不行。后者仅是一种特殊整型,并不引用目标对象,无法阻止垃圾回收器回收对象内存。

指针没有专门指向成员的“->”运算符,统一使用“.”选择表达式。

package main

func main() {
    var a struct{
        x int
    }
    //a:= struct {
    //  x int
    //}{}         //同上,不同写法
    a.x = 100
    p := &a
    p.x += 100
    println(p.x)
}

零长度对象的地址是否相等和具体的实现版本有关,不过肯定不等于nil。

package main

func main() {
    var a,b struct{}
    println(&a,&b)
    println(&a == &b,&a == nil)
}

输出:

0xc04202ff70 0xc04202ff70
false false

即便长度为0,可该对象依然是“合法存在”的,拥有合法内存地址,这与nil语义完全不同。
在runtime/malloc.go里有个zerobase全局变量,所有通过mallocgc分配的零长度对象都使用该地址。不过上栗中,对象a,b在栈上分配,并未调用mallocgc函数。

相关文章

  • 第三节课

    第二章 运算方法和运算器 2.1 数据与文字的表示方法 2.1.1 数据格式 定点数的表示    符号   ...

  • python基础2

    第二章 运算符 2.1 赋值运算符(=) 使用格式 将要赋值的变量=赋值目标例:a = 1b = "我是粽子" 2...

  • 语法目录

    第二章 Swift教程 2.1 基础部分(The Basics) 2.2 基本运算符(Basic Operator...

  • 回味JS(二)运算符及语法

    本篇文章总结自阮一峰的教程 JavaScript教程第二章运算符。 加法的不同类型运算规则? 两个number类型...

  • js成神之路:目录

    目录 第一章:js常用易错运算符 第二章:js函数特性

  • 第二章 运算

    2.1 运算符 全部运算符及分隔符列表 优先级 一元运算符优先级最高,二元则分成五个级别,从高向低分别是: 位运算...

  • 「组成原理」数据的信息表示-表示

    第二章(本章)和第三章分别可以学习到数据信息的表示,以及数据信息之间的基础运算。加减乘除基础运算在电脑中是非常基础...

  • 第二章

    title: 第二章grammar_cjkRuby: true [TOC] 一.线性表的概念及运算方法 线性表的逻...

  • 2020年3月11日 第二章 基本数据类型、运算符和表达式 -1

    第二章 基本数据类型、运算符和表达式 -1 1.基本数据类型 2.运算符 3.常用内置函数 4.表达式、赋值语句与...

  • 第二章⑤运算符

    对基本数据类型的常量与变量进行加工的过程称为:运算 表示各种不同运算的符号叫:运算符 参与运算的数据称为:操作数 ...

网友评论

    本文标题:第二章 运算

    本文链接:https://www.haomeiwen.com/subject/exyhpftx.html