C++-Golang的数组类型异同

1. 本文章的必要性

C++的存在像一把瑞士军刀,继承了C语言的设计理念——“充分相信程序员”,几乎将所有的底层细节都暴露在外,程序员可以自由控制。在最近详细学习Golang的过程中,发现Golang中的常用结构的设计理念与C++截然不同,为许多常用的操作都提供了语言设计者所认为的“最佳实践”。本文章仅讨论Golang中数组和切片。

2. Golang数组 和 C++数组(Array)

例子

C++ version

// const常量长度初始化
// 显然非常量无法作为初始化的长度,因为编译器在编译期无法确定要为此数组分配的内存长度
const int len = 10;
int cpp_arr[len];
 
// 初始化赋值
int cpp_arr[] = {1, 2, 3, 4, 5};

Golang version

// const常量长度初始化
// 显然非常量无法作为初始化的长度,理由同上
const len := 10
var golang_arr [len]int
 
// 初始化赋值
golang_arr := [...]int{1, 2, 3, 4, 5}
 
// Golang额外提供了语法,用于初始化数组为同一元素
// 将golang_arr初始化为具有100个元素-1的数组
golang_arr := [...]int{100:-1}

内存模型

两者一样,都是线性的内存结构。数组的本质,即为编译器在编译期在数据段分配常量长度的内存,再填充上指定的数据。从这方面很容易理解,两者的数组的长度是不容许修改的。

参数传递

1658072-20190618193921734-1247277430.png

C++ version
C++的数组传参都只能靠指针
但对于指针的移动偏移无任何限制,只能靠程序员手动管理,如果读写越界,可能会破坏堆栈

int passArray(int arr[])
{
    // 合法
    arr[0] = 0;   
    // 不合法!可能会破坏进程地址空间中的内存布局
    arr[-1000] = 0;
}
 
int main()
{
    int arr[] = {1, 2, 3, 4, 5};
    passArray(&arr[0]);
    return 0;
}

golang version

// 通过改变ptr的指向,将ptr所指的内存置为空
// 原来的内存,GC可通过引用计数探测,将其释放
func passArrayByPointer(ptr *[32]int) {
  *ptr = [32]int{}
}
 
// 无效,只是对拷贝进行了一次赋值
func passArrayByValue(arr [32]int) {
    arr = [32]int{}
}
  • Golang对C++传递数组进行了限制和优化,将数组类型作为函数的形参时,必须显式的指定该数组的长度。在编译期,编译器也会对传入数组的长度与声明的长度进行比对,如果不相等则无法编译通过。
  • 和其他高级语言不同(比如Java),语言中内置的类型有的为引用类型(在作为函数参数时直接传递引用),有的为值类型(在作为函数参数时传递一份拷贝),Golang在这方面引入了指针,可以自由控制给函数传递的数组是拷贝,还是指针(这是传参时,与C++最大的不同)

    总结

  1. 语法格式不同(废话)
  2. 作为参数传递时,长度Golang有严格的长度检查机制,防止写坏内存
  3. Golang中的数组是值语义,数组名即代表整个数组,而不像C/C++隐含为第一个元素的地址

  4. 内存布局一致
  5. 分配特性一致,即数组长度在编译期即确定,无法改变

 

 

 

 

这篇文章转自 https://www.cnblogs.com/jo3yzhu/p/11047177.html

为了便于理解  不同点中的3.Golang中的数组是值语义,数组名即代表整个数组,而不像C/C++隐含为第一个元素的地址

我写了两个小例子,来供大家进一步的理解

galang-version  test.go


package main
  
import "fmt"

func modify(array [5]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)
}

执行go代码   go run test.go  输出结果为

In modify(),array values: [10 2 3 4 5]
In main(),array values: [1 2 3 4 5]
 C++ -version 

#include<iostream>
#include<windows.h>
#include<vector>
#include<string>
#include <fstream>
using namespace std;
int modifyfun(int a[5])
{
	a[0] = 100;
	for (int i = 0; i < 5; i++)
	{
		cout << a[i] << endl;
	}
	return 0;
}
int main()
{
	int array[5]{1, 2, 3, 4, 5};
	modifyfun(array);
	for (int i = 0; i < 5; i++)
	{
		cout << array[i] << endl;
	}
	
		return 0;
}

运行输出结果为

100
2
3
4
5
100
2
3
4
5
请按任意键继续. . .

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值