Go语言编程 学习笔记整理 第2章 顺序编程 前半部分

news2024/11/13 16:22:59
前言:《Go语言编程编著 许式伟 吕桂华 等

1.1 变量

var v1 int
var v2 string
var v3 [10]int // 数组
var v4 []int // 数组切片
var v5 struct { 
 f int
} 
var v6 *int // 指针
var v7 map[string]int // map,key为string类型,value为int类型
var v8 func(a int) int
var 关键字的另一种用法是可以将若干个需要声明的变量放置在一起,免得程序员需要重复
var 关键字,如下所示:
var ( 
 v1 int
 v2 string
)
对于声明变量时需要进行初始化的场景, var 关键字可以保留,但不再是必要的元素,如下
所示:
var v1 int = 10 // 正确的使用方式1 
var v2 = 10 // 正确的使用方式2,编译器可以自动推导出v2的类型
v3 := 10 // 正确的使用方式3,编译器可以自动推导出v3的类型
以上三种用法的效果是完全一样的。与第一种用法相比,第三种用法需要输入的字符数大大
减少,是懒程序员和聪明程序员的最佳选择。
当然,出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误,比如下面这个
写法:
var i int 
i := 2 
会导致类似如下的编译错误:
no new variables on left side of :=
Go 语言中提供了 C/C++ 程序员期盼多年的多重赋值功 能,比如下面这个交换i和 j 变量的语句:
i, j = j, i
在不支持多重赋值的语言中,交互两个变量的内容需要引入一个中间变量:
t = i; i = j; j = t;

2.匿名变量

在使用传统的强类型语言编程时,经常会出现这种情况,即在调用函数时为了获取一个
值,却因为该函数返回多个值而不得不定义一堆没用的变量。在 Go 中这种情况可以通过结合使
用多重返回和匿名变量 来避免这种丑陋的写法,让代码看起来更加优雅。
假 设 GetName() 函数的定义如下,它返回 3 个值,分别为 firstName lastName
nickName
func GetName() (firstName, lastName, nickName string) { 
 return "May", "Chan", "Chibi Maruko" 
}
若只想获得 nickName ,则函数调用语句可以用如下方式编写:
_, _, nickName := GetName()

3.常量

常量可以是数值类型(包括整型、 浮点型和复数类型)、布尔类型、字符串类型等。
3.1 字面常量( literal ),是指程序中硬编码的常量
-12 
3.14159265358979323846 // 浮点类型的常量
3.2+12i // 复数类型的常量
true // 布尔类型的常量
"foo" // 字符串常量

3.2 常量定义,通过const关键字,可以给字面常量指定一个友好的名字:

const Pi float64 = 3.14159265358979323846 
const zero = 0.0 // 无类型浮点常量
const (
 size int64 = 1024 
 eof = -1 // 无类型整型常量
) 
const u, v float32 = 0, 3 // u = 0.0, v = 3.0,常量的多重赋值
const a, b, c = 3, 4, "foo" 
// a = 3, b = 4, c = "foo", 无类型整型和字符串常量
Go 的常量定义可以限定常量类型,但不是必需的。如果定义常量时没有指定类型,那么它
与字面常量一样,是无类型常量。
(1) 常量定义的右值也可以是一个在编译期运算的常量表达式,比如
const mask = 1 << 3
(2)由于常量的赋值是一个编译期行为,所以右值不能出现任何需要运行期才能得出结果的表达
式,比如试图以如下方式定义常量就会导致编译错误:
const Home = os.GetEnv("HOME")
因为 os.GetEnv() 只有在运行期才能知道返回结果,在编译期并不能确定,所以无法作为常量定义的右值。
4.预定义常量
Go 语言预定义了这些常量: true false iota
iota 比较特殊,可以被认为是一个可被编译器修改的常量,在每一个const关键字出现时被 重置为0,然后在下一个const出现之前,每出现一次iota,其所代表的数字会自动增1。
const ( // iota被重设为0
 c0 = iota // c0 == 0 
 c1 = iota // c1 == 1 
 c2 = iota // c2 == 2 
)

const ( 
 a = 1 << iota // a == 1 (iota在每个const开头被重设为0) 
 b = 1 << iota // b == 2 
 c = 1 << iota // c == 4 
)

const ( 
 u = iota * 42 // u == 0 
 v float64 = iota * 42 // v == 42.0
 w = iota * 42 // w == 84 
) 
const x = iota // x == 0 (因为iota又被重设为0了) 
const y = iota // y == 0 (同上)
如果两个const的赋值语句的表达式是一样的,那么可以省略后一个赋值表达式。因此,上 面的前两个const语句可简写为:
const ( // iota被重设为0
 c0 = iota // c0 == 0 
 c1 // c1 == 1 
 c2 // c2 == 2 
) 
const ( 
 a = 1 <<iota // a == 1 (iota在每个const开头被重设为0) 
 b // b == 2 
 c // c == 4 
)

5. 枚举

(1)Go 不支持支持的enum关键字

(2)可以用在const后跟一对圆括号的方式定义一组常量,这种定义法在Go语言中通常用于定义

枚举值
const ( 
 Sunday = iota
 Monday 
 Tuesday 
 Wednesday 
 Thursday 
 Friday 
 Saturday 
 numberOfDays // 这个常量没有导出 
)

注意:

  • ① 同Go语言的其他符号(symbol)一样,以大写字母开头的常量在包外可见
  • ② 以上例子中numberOfDays包内私有,其他符号则可被其他包访问
6. 类型
  • 布尔类型:bool
  • 整型:int8byteint16intuintuintptr
  • 浮点类型:float32float64
  • 复数类型:complex64、complex128
  • 字符串:string
  • 字符类型:rune
  • 错误类型:error
此外, Go 语言也支持以下这些复合类型:
  • 指针(pointer
  • 数组(array
  • 切片(slice
  • 字典(map
  • 通道(chan
  • 结构体(struct
  • 接口(interface
7. 布尔类型
var v1 bool
v1 = true
v2 := (1 == 2) // v2也会被推导为bool类型
布尔类型不能接受其他类型的赋值,不支持自动或强制的类型转换。以下的示例是一些错误的用法,会导致编译错误:
var b bool
b = 1 // 编译错误
b = bool(1) // 编译错误
以下的用法才是正确的:
var b bool
b = (1!=0) // 编译正确 
fmt.Println("Result:", b) // 打印结果为Result: true

8.整型

int int32 Go语言里被认为是两种不同的类型,编译器也不会帮你自动做类型转换
var value2 int32
value1 := 64 // value1将会被自动推导为int类型
value2 = value1 // 编译错误
编译错误类似于:
cannot use value1 (type int) as type int32 in assignment。
使用强制类型转换可以解决这个编译错误:
value2 = int32(value1) // 编译通过
两个不同类型的整型数不能直接比较,比如 int8 类型的数和 int 类型的数不能直接比较,但各种类型的整型变量都可以直接与字面常量(literal )进行比较,比如:
var i int32
var j int64
i, j = 1, 2 
if i == j { // 编译错误
 fmt.Println("i and j are equal.") 
} 
if i == 1 || j == 2 { // 编译通过
 fmt.Println("i and j are equal.") 
}

9. 浮点型

Go 语言定义了两个类型 float32和float64,其中:
  • float32等价于C语言的float类型
  • float64等价于C语言的double类型
var fvalue1 float32
fvalue1 = 12 
fvalue2 := 12.0 // 如果不加小数点,fvalue2会被推导为整型而不是浮点型
对于以上例子中类型被自动推导的 fvalue2 ,需要注意的是其类型将被自动设为 float64 , 而不管赋给它的数字是否是用32 位长度表示的。因此,对于以上的例子,下面的赋值将导致编译错误:
fvalue1 = fvalue2

而必须使用这样的强制类型转换:

fvalue1 = float32(fvalue2)

注意:浮点数的比较

直接用==来判断两个浮点数是否相等是不可行的,这可能会导致不稳定的结果
下面是一种推荐的替代方案:
import "math" 
// p为用户自定义的比较精度,比如0.00001 
func IsEqual(f1, f2, p float64) bool { 
 return math.Fdim(f1, f2) < p 
}

10. 复数类型

var value1 complex64 // 由2个float32构成的复数类型
value1 = 3.2 + 12i 
value2 := 3.2 + 12i // value2是complex128类型
value3 := complex(3.2, 12) // value3结果同 value2

11.字符串

Go 语言中字符串的声明和初始化非常简单,举例如下:
var str string // 声明一个字符串变量
str = "Hello world" // 字符串赋值
ch := str[0] // 取字符串的第一个字符


fmt.Printf("The length of \"%s\" is %d \n", str, len(str))
fmt.Printf("The first character of \"%s\" is %c.\n", str, ch)


输出结果为:
The length of "Hello world" is 11 
The first character of "Hello world" is H.
字符串的内容可以用类似于数组下标的方式获取,但与数组不同, 字符串的内容不能在初始
化后被修改 ,比如以下的例子:
str := "Hello world" // 字符串也支持声明时进行初始化的做法
str[0] = 'X' // 编译错误

编译器会报类似如下的错误:
cannot assign to str[0]
Go 编译器支持 UTF-8 的源代码文件格式。这意味着源代码中的字符串可以包含非 ANSI 的字
符,比如“ Hello world. 你好,世界!”可以出现在 Go 代码中。但需要注意的是,如果你的 Go 代 码需要包含非ANSI 字符,保存源文件时请注意编码格式必须选择 UTF-8 。特别是 Windows 下一 般编辑器都默认存为本地编码,比如中国地区可能是GBK 编码而不是 UTF-8 ,如果没注意这点在 编译和运行时就会出现一些意料之外的情况。

(1)字符串操作 

 

(2)字符串遍历

str := "Hello,世界"
n := len(str) 
for i := 0; i < n; i++ { 
 ch := str[i] // 依据下标取字符串中的字符,类型为byte 
 fmt.Println(i, ch) 
}

这个例子的输出结果为:
0 72 
1 101 
2 108 
3 108 
4 111 
5 44 
6 32 
7 228 
8 184 
9 150 
10 231 
11 149 
12 140
可以看出,这个字符串长度为 13 。尽管从直观上来说,这个字符串应该只有 9 个字符。这是
因为每个中文字符在 UTF-8 中占 3 个字节,而不是 1 个字节。
另一种是以Unicode字符遍历:
str := "Hello,世界"
for i, ch := range str { 
 fmt.Println(i, ch)//ch的类型为rune 
} 
输出结果为:
0 72 
1 101 
2 108 
3 108 
4 111 
5 44 
6 32 
7 19990 
10 30028 

以Unicode字符方式遍历时,每个字符的类型是rune(早期的Go语言用int类型表示Unicode字符),而不是byte。

12.数组

[32]byte // 长度为32的数组,每个元素为一个字节
[2*N] struct { x, y int32 } // 复杂类型数组
[1000]*float64 // 指针数组
[3][5]int // 二维数组
[2][2][2]float64 // 等同于[2]([2]([2]float64))
从以上类型也可以看出,数组可以是多维的,比如 [3][5]int 就表达了一个 3 5 列的二维整
型数组,总共可以存放 15 个整型元素。
数组的长度是该数组类型的一个内置常量,可以用Go语言的内置函数len()来获取:
arrLength := len(arr)

(1)元素访问

for i := 0; i < len(array); i++ { 
 fmt.Println("Element", i, "of array is", array[i]) 
}
for i, v := range array { 
 fmt.Println("Array element[", i, "]=", v) 
}
在上面的例子里可以看到, range 具有两个返回值,第一个返回值是元素的数组下标,第二
个返回值是元素的值
(2)值类型
所有的值类型变量在赋值和作为参数传递时都将产生一次复制动作。如果将数组作为函数的参数类型,则在函数调用时该参数将发生数据复制。因此,在函数体中无法修改传入的数组的内容,因为函数内操作的只是所传入数组的一个副本。
package main 
import "fmt" 
func modify(array [10]int) { 
 array[0] = 10 // 试图修改数组的第一个元素
 fmt.Println("In modify(), array values:", array) 
}

func main() { 
 array := [5]int{1,2,3,4,5} // 定义并初始化一个数组
 modify(array) // 传递给一个函数,并试图在函数体内修改这个数组内容
 fmt.Println("In main(), array values:", array) 
}

该程序的执行结果为:
In modify(), array values: [10 2 3 4 5] 
In main(), array values: [1 2 3 4 5]
从执行结果可以看出,函数 modify() 内操作的那个数组跟 main() 中传入的数组是两个不同的实
例。
13.数组切片
数组的特点:
  • 数组的长度在定义之后无法再次修改;
  • 数组是值类型, 每次传递都将产生一份副本。显然这种数据结构无法完全满足开发者的真实需求。
数组切片(slice) 这个非常酷的功能来弥补数组的不足
数组切片实际上它拥有自己的数据结构,而不仅仅是个指针
数组切片的数据结构可以抽象为以下 3 个变量:
  • 一个指向原生数组的指针
  • 数组切片中的元素个数
  • 数组切片已分配的存储空
基于数组,数组切片添加了一系列管理功能,可以随时动态扩充存放空间,并且可以被随意传递而不会导致所管理的元素被重复复制
(1)创建数组切片
创建方法:
  • ① 基于数组
  • ② 直接创建
slice.go
package main 
import "fmt" 
func main() { 
 // 先定义一个数组
 var myArray [10]int = [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} 
 // 基于数组创建一个数组切片
 var mySlice []int = myArray[:5] 
 fmt.Println("Elements of myArray: ") 
 for _, v := range myArray { 
 fmt.Print(v, " ") 
 } 
 fmt.Println("\nElements of mySlice: ") 
 for _, v := range mySlice { 
 fmt.Print(v, " ") 
 } 
 fmt.Println() 
}

运行结果为:
Elements of myArray: 
1 2 3 4 5 6 7 8 9 10 
Elements of mySlice: 
1 2 3 4 5
Go 语言支持用 myArray[first:last]这样的方式 来基于数组生成一个数组切片,而且这个用法还很灵活,比如下面几种都是合法的。
  • 基于数组
// 基于myArray的所有元素创建数组切片:
mySlice = myArray[:]

// 基于myArray的前5个元素创建数组切片:
mySlice = myArray[:5]

// 基于从第5个元素开始的所有元素创建数组切片:
mySlice = myArray[5:]
  • 直接创建

并非一定要事先准备一个数组才能创建数组切片。Go语言提供的内置函数make()可以用于灵活地创建数组切片

// 创建一个初始元素个数为5的数组切片,元素初始值为0:
mySlice1 := make([]int, 5)

// 创建一个初始元素个数为5的数组切片,元素初始值为0,并预留10个元素的存储空间:
mySlice2 := make([]int, 5, 10)

// 直接创建并初始化包含5个元素的数组切片:
mySlice3 := []int{1, 2, 3, 4, 5}
当然,事实上还会有一个匿名数组被创建出来,只是不需要我们来操心而已。

(2)元素遍历

操作数组元素的所有方法都适用于数组切片,比如数组切片也可以按下标读写元素,用 len() 函数获取元素个数,并支持使用range 关键字来快速遍历所有元素。
// 传统的元素遍历方法如下:
for i := 0; i <len(mySlice); i++ { 
 fmt.Println("mySlice[", i, "] =", mySlice[i]) 
}

// 使用range关键字可以让遍历代码显得更整洁。range表达式有两个返回值,第一个是索引,第二个是元素的值:
for i, v := range mySlice { 
 fmt.Println("mySlice[", i, "] =", v) 
}
对比上面的两个方法,我们可以很容易地看出使用 range 的代码更简单易懂
(3)动态增减元素
与数组相比,数组切片多了一个存储能力(capacity )的概念,即元素个数和分配的空间可以是两个不同的值。合理地设置存储能力的值, 可以大幅降低数组切片内部重新分配内存和搬送内存块的频率 ,从而大大提高程序性能。
  • 数组切片支持Go语言内置的cap()函数和len()函数
package main 
import "fmt" 
func main() { 
 mySlice := make([]int, 5, 10) 
 fmt.Println("len(mySlice):", len(mySlice)) 
 fmt.Println("cap(mySlice):", cap(mySlice)) 
}

该程序的输出结果为:
len(mySlice): 5 
cap(mySlice): 10
  • 如果需要往上例中mySlice已包含的5个元素后面继续新增元素,可以使用append()函数
mySlice = append(mySlice, 1, 2, 3)
函数 append() 的第二个参数其实是一个不定参数,我们可以按自己需求添加若干个元素, 甚至直接将一个数组切片追加到另一个数组切片的末尾:
mySlice2 := []int{8, 9, 10}
// 给mySlice后面添加另一个数组切片
mySlice = append(mySlice, mySlice2...)
func SliceLenCap() {
	mySlice := make([]int, 5, 10)
	for i := range mySlice {
		mySlice[i] = i
	}
	fmt.Println("len(mySlice):", len(mySlice))
	fmt.Println("cap(mySlice):", cap(mySlice))

	fmt.Println("可以从尾端给mySlice加上3个元素:5,6,7")
	mySlice = append(mySlice, 5, 6, 7)
	for _, v := range mySlice {
		fmt.Print(v, " ")
	}
	fmt.Println()

	fmt.Println("给mySlice后面添加另一个数组切片")
	mySlice2 := []int{8, 9, 10}
	// 给mySlice后面添加另一个数组切片
	mySlice = append(mySlice, mySlice2...)
	for _, v := range mySlice {
		fmt.Print(v, " ")
	}
	fmt.Println()
}
数组切片会自动处理存储空间不足的问题。如果追加的内容长度超过当前已分配的存储空间
(即 cap() 调用返回的信息),数组切片会自动分配一块足够大的内存。
(4) 基于数组切片创建数组切片
  • 类似于数组切片可以基于一个数组创建,数组切片也可以基于于另一个数组切片创建
oldSlice := []int{1, 2, 3, 4, 5}
newSlice := oldSlice[:3] // 基于oldSlice的前3个元素构建新数组切片

14.map

  • Go中,使用map不需要引入任何库,并且用起来也更加方便
func MapCase() {
	var personDB map[string]PersonInfo
	personDB = make(map[string]PersonInfo)

	// 往这个map里插入几条数据
	personDB["100001"] = PersonInfo{"100001", "张三", "Room 203"}
	personDB["100002"] = PersonInfo{"100002", "李四", "Room 204"}

	// 从这个map查找键为"100001"的信息
	person, ok := personDB["100001"]
	// ok 是一个返回的bool型,返回true表示找到了对应的数据
	if ok {
		fmt.Println("Found person", person.Name, "with ID 100001.")
	} else {
		fmt.Println("Cannot find person with ID 100001.")
	}
}
上面这个简单的例子基本上已经覆盖了 map 的主要用法,下面对其中的关键点进行细述:
(1)变量声明
map 的声明基本上没有多余的元素,比如:
var myMap map[string] PersonInfo

其中,myMap是声明的map变量名,string是键的类型,PersonInfo则是其中所存放的值类型。

(2)创建

可以使用Go语言内置的函数make()来创建一个新map

myMap = make(map[string] PersonInfo)

也可以选择是否在创建时指定该map的初始存储能力,下面的例子创建了一个初始存储能力为100map:

myMap = make(map[string] PersonInfo, 100)

创建并初始化map代码如下:

myMap = map[string] PersonInfo{ 
 "1234": PersonInfo{"1", "Jack", "Room 101,..."}, 
}

(3)元素赋值

// 是将键和值用下面的方式对应起来即可:
myMap["1234"] = PersonInfo{"1", "Jack", "Room 101,..."}

(4)元素删除

// Go语言提供了一个内置函数delete(),用于删除容器内的元素
delete(myMap, "1234")

(5)元素查找

Go 语言中,要从map 中查找一个特定的键,可以通过下面的代码来实现:
value, ok := myMap["1234"] 
if ok { // 找到了
 // 处理找到的value 
}
判断是否成功找到特定的键,不需要检查取到的值是否为 nil ,只需查看第二个返回值 ok , 这让表意清晰很多。配合:= 操作符,让你的代码没有多余成分,看起来非常清晰易懂。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1945196.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

神经网络理论(机器学习)

motivation 如果逻辑回归的特征有很多&#xff0c;会造出现一些列问题&#xff0c;比如&#xff1a; 线性假设的限制&#xff1a; 逻辑回归是基于线性假设的分类模型&#xff0c;即认为特征与输出之间的关系是线性的。如果特征非常多或者特征与输出之间的关系是非线性的&#…

职场新人必备神器:四款PDF转Word在线转换工具大比拼

关于PDF文件格式转换这件事&#xff0c;其实已经变成了职场人都要会的基础技能了&#xff0c;那么要如何才能够快速且完成的PDF转换为Word呢&#xff1f;今天就让我用自己的毕生所学给大家说说四款pdf转word在线转换免费的工具吧&#xff0c;下面一起来了解一下吧。 一、福昕PD…

【C++】流插入和流提取运算符重载

目录 前言ostream和istream自定义类型的流插入重载自定义类型的流提取重载解决私有问题日期类总接口 前言 我们在上一节实现日期类时&#xff0c;在输入和输出打印时&#xff0c;经常会调用两个函数&#xff1a; void Insert()//输入函数{cin >> _year;cin >> _mo…

ARDUINO 上传失败:上传错误:退出状态 2常见原因及解决方法Failed uploading: uploading error: exit status

前言&#xff1a; 串口监视器可显示各种ESP32打印信息 下述均为USB TYPEC 数据线正常的情况下的报错&#xff0c;如果数据线或串口有问题 原因1&#xff1a;无法连接到ESP32&#xff1a;串行数据流停止&#xff1a;可能存在串行噪音或损坏 解决方法&#xff1a;ESP32电路板是…

一文速览llama 3.1及其微调:长度终于到128K,故可让paper-review数据集直接微调

前言 llama3 刚出来时&#xff0c;其长度只有8K对于包括我司在内的大模型开发者是个小小的缺憾&#xff0c;好在很快&#xff0c;在7.23日&#xff0c;Meta发布了Llama 3.1&#xff0c;其意义在于 很明显&#xff0c;随着llama的影响力越来越大&#xff0c;Meta想让llama类似…

(雷达数据处理中的)跟踪算法(1) --- 整体目录

说明 目标跟踪是雷达数据处理中核心的步骤之一&#xff0c;基于雷达的各项应用往往需要跟踪模块所输出的结果。比如在车载雷达领域&#xff0c;目标跟踪位于点云聚类和ADAS功能实现之间(关于聚类&#xff0c;可以参考我之前的博文[1]&#xff1a;&#xff08;毫米波雷达数据处理…

macOS 10.15中屏蔽Microsoft Edge浏览器的更新提示

文章目录 1.效果对比2.安装描述文件3.停用描述文件4.高级操作&#xff08;可选&#xff09;参考文献 最近在macOS10.15系统&#xff0c;打开Microsoft Edge浏览器&#xff0c;每次打开都有个烦人的提示“ 要获取将来的 microsoft edge 更新&#xff0c;需要 macos 10.15 或更高…

C#实战 | 天行健、上下而求索

本文介绍C#开发入门案例。 01、项目一&#xff1a;创建控制台应用“天行健&#xff0c;君子以自强不息” 项目说明&#xff1a; 奋斗是中华民族的底色&#xff0c;见山开山&#xff0c;遇水架桥&#xff0c;正是因为自强不息的奋斗&#xff0c;才有了辉煌灿烂的中华民族。今…

单向链表知识汇总

提示&#xff1a;本文章参考知乎大佬和一位博主大佬 单向链表 1.前置知识(部分最好记忆)1.1 链表组成1.2 链表插入分三种情况1.2.1头插1.2.2 中间插1.2.2 结尾插 1.3 链表的删除1.51.61.7 2.链表各种接口的实现2.1 链表的打印2.1 链表的节点的申请2.2 单链表节点增加2.2.1 单链…

【常微分方程】

框架 常微分方程的概念一阶微分方程可变离分量齐次方程一阶线性微分方程可降阶的高阶微分方程二阶常系数齐次线性微分方程二阶常系数非齐次线性微分方程 讲解 【1】 常微分方程&#xff1a;是微分方程的特殊情况&#xff1b; 阶&#xff1a;是方程未知函数的最高阶导数的阶数&…

关于pycharm上push项目到gitee失败原因

版权声明&#xff1a;本文为博主原创文章&#xff0c;如需转载请贴上原博文链接&#xff1a;https://blog.csdn.net/u011628215/article/details/140577821?spm1001.2014.3001.5502 前言&#xff1a;最近新建项目push上gitee都没有问题&#xff0c;但是当在gitee网站进行了一个…

【笔记:3D航路规划算法】二、RRT*

目录 一、RRT*于RRT的不同之处1、路径优化&#xff1a;2、成本计算&#xff1a;3、重连线步骤&#xff1a; 二、图解1、初始化2、路径搜索3、效果展示 3D路径规划是在三维空间中寻找从起点到终点的最短或最优路径的一种技术。它广泛应用于无人机导航、机器人运动规划、虚拟现实…

开源软件项目:趋势、参与经验与收获

在当今这个全球经济与科技日新月异的时代&#xff0c;开源软件项目&#xff08;Open Source Software, OSS&#xff09;正以前所未有的速度蓬勃发展&#xff0c;成为推动技术创新、促进产业合作、加速知识共享的重要力量。随着云计算、大数据、人工智能等技术的兴起&#xff0c…

C#入门与精通

C#精通 本文章主要是对于学习C#基础难点进行学习以及与java语言的不同点&#xff0c;详细学习可见官网&#xff1a;https://dotnet.microsoft.com/en-us/learn 文章目录 C#精通VSVS基本设置 C#是什么C#程序控制台输出变量内插占位符C#foreach循环类型转换操作数组内置方法格式设…

Java智慧养老养老护理帮忙代办陪诊陪护小程序系统源码

&#x1f31f;智慧养老新风尚&#xff0c;护理代办陪诊小程序来帮忙✨ &#x1f3e1;【开篇&#xff1a;关爱老人&#xff0c;从智慧养老开始】&#x1f3e1; 随着社会的进步&#xff0c;智慧养老已成为新时代孝心的体现。面对忙碌的生活节奏&#xff0c;如何更好地照顾家中长…

三、基础语法2(30小时精通C++和外挂实战)

三、基础语法2&#xff08;30小时精通C和外挂实战&#xff09; B-02内联函数B-04内联函数与宏B-05_constB-06引用B-07引用的本质B-08-汇编1-X86-X64汇编B-09-汇编2-内联汇编B-10-汇编3-MOV指令C-02-汇编5-其他常见指令C-05-汇编8-反汇编分析C-07-const引用、特点 B-02内联函数 …

智能时代的伦理困境:如何应对AI引发的社会问题

文章目录 每日一句正能量前言构建可靠的AI隐私保护机制1. **数据最小化原则**2. **数据匿名化和去标识化**3. **加密技术**4. **访问控制**5. **数据使用透明度**6. **用户控制权**7. **数据保护影响评估**8. **法规遵从性**9. **隐私设计**10. **安全意识教育和培训**11. **持…

C++自定义字典树结构

代码 #include <iostream> using namespace std;class TrieNode { public:char data;TrieNode* children[26];bool isTerminal;TrieNode(char ch){data ch;for (int i 0; i < 26; i){children[i] NULL;}isTerminal false;} }; class Trie { public:TrieNode* ro…

Transformer和预训练模型是什么

目前我们使用的OpenAI的ChatGPT是一种基于GPT-3.5或GPT-4的聊天机器人&#xff0c;能够实现人与机器之间的自然语言交互。那么GPT是什么呢&#xff1f; GPT是一种语言模型&#xff0c;它是由OpenAI实验室于2018年推出的基于Transformer架构的预训练语言模型&#xff0c;通过处理…

matlab y = 1/√x图像和y = 1/x图像

matlab y 1/√x图像和y 1/x图像 y 1/√x与y 1/x绘制结果y√x y 1/√x与y 1/x clc, clear, close all; length 3; axis_len 5;% Create a range of x values x linspace(0.01, length^2, 1000); % Avoid x 0 for 1/√x% Compute the corresponding y values y1 1 .…