golang与c指针对比

golang中的指针

总结一下golang中的指针与C语言的指针的用法.

总体一致: 
C的代码:
    int *number;
    number = (int *) malloc(sizeof(int));
    *number = 3;
    printf("%d\n", *number);


golang的代码:
    var pointer *int;
    pointer = new(int);
    *pointer = 3;
    fmt.Println(*pointer);


多重指针情况:
C的代码:
    int **outer;
    int *inter;
    inter = (int *) malloc(sizeof(int));


    *inter = 3;
    outer = &inter;
    //地址一样
    printf("%p\n", inter);
    printf("%p\n", *outer);
    //值一样
    printf("%d\n", *inter);
    printf("%d\n", **outer);


golang的代码:
    var outer **int;
    var inter *int;
    inter = new(int);
    *inter = 3;
    outer = &inter;
    //地址一样
    fmt.Println(inter);
    fmt.Println(*outer);
    //值一样
    fmt.Println(*inter);
    fmt.Println(**outer);


C语言的下面这种方式在golang里实现:
    int **outer;
    int *inter;
    inter = (int *) malloc(sizeof(int));
    outer = (int **) malloc(sizeof(int));
   
    *inter = 3;
    *outer = inter;
    //地址一样
    printf("%p\n", inter);
    printf("%p\n", *outer);
    //值一样
    printf("%d\n", *inter);
    printf("%d\n", **outer);


在golang中:
    var inter *int;
    var outer **int;
    inter = new(int);
    *inter = 3;
    outer = new(*int);
    *outer = inter;
    //地址一样
    fmt.Println(inter);
    fmt.Println(*outer);
    //值一样
    fmt.Println(*inter);
    fmt.Println(**outer);


上面都是在玩指针, 下面看看基本的数据结构


基本的数据结构有: 数组与结构体 (map和树之类的不在討論范围)


golang中的数组与C中的数组有很大的差别


golang中的数组是这样说的: Arrays are values, not implicit pointers as in C.


0. 数组做参数时, 需要被检查长度.
1. 变量名不等于数组开始指针!
2. 不支持C中的*(ar + sizeof(int))方式的指针移动. 需要使用到unsafe包
3. 如果p2array为指向数组的指针, *p2array不等于p2array[0]
例子0 数组做参数时, 需要被检查长度.


func use_array( args [4]int ){
    args[1] = 100;
}


func main() {
    var args = [5]int{1, 2, 3, 4, 5};
    use_array(args);
    fmt.Println(args);
}


编译出错: cannot use args (type [5]int) as type [4]int in function argument, 需要有长度上的检查
例子1 变量名不等于数组开始指针!


func use_array( args [4]int ){
    args[1] = 100;
}


func main() {
    var args = [5]int{1, 2, 3, 4, 5};
    use_array(args);
    fmt.Println(args);
}


输出結果是 [1 2 3 4], 没有保存結果, 数组名的用法与C的不一样. 在golang里是这样的:


// 又长度检查, 也为地址传参
func use_array( args *[4]int ){
    args[1] = 100;  //但是使用还是和C一致, 不需要别加"*"操作符
}
            
func main() {        
    var args = [4]int{1, 2, 3, 4};
    use_array(&args); //数组名已经不是表示地址了, 需要使用"&"得到地址
    fmt.Println(args);
}


例子2 如果p2array为指向数组的指针, *p2array不等于p2array[0]
对比一下C和golang在这方面的差别:
void main(int argc, char *argv[]){
    int *p2array;
    p2array = (int *) malloc(sizeof(int) * 3);
    //等于p2array[0]
    *p2array = 0;
    printf("%d\n", *p2array + 1);
}
* 输出为1


func main() {
    var p2array *[3]int ;
    p2array = new([3]int);
    fmt.Printf("%x\n", *p2array + 1); //不管p2array是指针变量还是数组变量, 都只能使用"[]"方式使用
}
* 报错.
golang中的结构体也与C中的有差别




下面的方式是相当一致的:
C版本的:
    typedef struct
    {  
        int x;
        int y;
    } Point;


    Point p;
    p.x = 10;
    p.y = 20;
   
    //开始地址
    printf("%p\n", &p);
    //某元素地址
    printf("%p\n", &(p.x));


golang版本的:
    type Point struct{
        x int;
        y int;
    };
   
    var p Point;
    p.x = 10;
    p.y = 20;
    fmt.Printf("%p\n", &p);
    fmt.Printf("%p\n", &(p.x));


使用allocate的方式:
C代码:
    typedef struct
    {  
        int x;
        int y;
    } Point;


    Point *p;
    p = (Point *) malloc(sizeof(Point));
    p->x = 10;
    p->y = 20;
   
    //开始地址
    printf("%p\n", p); //地址
    //某元素地址
    printf("%p\n", &(p->x));


golang代码:
    type Point struct{
        x int;
        y int;
    };
   
    var p *Point;
    p = new(Point);
    p.x = 10;
    p.y = 20;
    fmt.Printf("%p\n", p); //地址
    fmt.Printf("%p\n", &(p.x));


也可以说是一样的, 只不过在使用结构中的元素时没有了"->"操作符:
There is no -> notation for structure pointers. Go provides the indirection for you.   


结构体的地址传参与数组的方式一样, 当然, 和C的风格也是一模一样的. 如下例子:


C代码:
#include <stdio.h>
#include <stdlib.h>
typedef struct
    {
        int x;
        int y;
    } Point;
    
void use_struct(Point *arg){
    arg->x = 100;
}


void main(int argc, char *argv[]){
    
    Point *p;
    p = (Point *) malloc(sizeof(Point));
    p->x = 10;
    p->y = 20;
    
    use_struct(p);
    printf("%d\n", p->x);


}


golang代码:
import "fmt"


type Point struct{
    x int;
    y int;
};


func use_sturct( p *Point ){
    p.x = 100;
}


func main() {


    var p *Point;
    p = new(Point);
    p.x = 10;
    p.y = 20;
    use_sturct(p);
    fmt.Printf("%d\n", p.x);
}


总的来说......


在传参方面, 大体上看与C的相同:


  f(ar);    // passes a copy of ar 


  fp(&ar);  // passes a pointer to ar
* 只是变量名是不是表示首个地址 有区别




"&" 与C语言一样是得到变量的指针. 与C有点不同, 取golang中指针指针的内容的值是不需要使用"*"操作符的, 但是指针的指针(或者继续多层时)需要显式使用"*"符号.
在http://golang.org/doc/go_spec.html#Selectors 一节中有描述。


* 三层以上的指针使用是比较少的. 两层还是常见, 如main函数的参数char * argv[]

<think>嗯,用户想了解Golang、Java和C语言之间的主要区别和适用场景。首先,我需要回忆这三种语言的特点。C语言是古老的系统级语言,主要用于底层开发,比如操作系统和嵌入式系统。Golang是Google推出的,强调简洁和高并发,适合网络服务和分布式系统。Java是面向对象的企业级语言,跨平台,有强大的生态系统。 接下来,用户可能需要知道它们在设计哲学上的差异。C注重效率和硬件控制,手动内存管理。Java有JVM自动管理内存,面向对象,跨平台。Golang编译为本地代码,语法简洁,内置并发支持。 然后要比较性能。C最快,但需要手动优化。Golang性能接近C,但并发模型更好。Java由于JVM可能有启动延迟,但JIT优化后性能不错。引用中提到Golang在特定场景性能更好,但多数情况下Java差异不大,需要指出这点。 语法方面,C的语法较基础,需要更多代码。Java较冗长,但结构化好。Golang简洁,比如没有类,用结构体和方法。 并发模型是关键区别。C需要依赖线程库,Java有线程和并发包,Golang有goroutine和channel,更轻量级。 内存管理方面,C手动,Java和Golang自动GC,但GC机制不同,Golang的GC更高效,延迟低。 生态系统部分,Java最丰富,适合企业应用。Golang的生态在云原生方面强,如Docker和K8s。C的库底层,适合系统开发。 适用场景需要分情况讨论。C适合底层和嵌入式。Java适合大型企业应用和安卓。Golang适合高并发和云服务。引用中的资料提到Golang适合高性能和并发,Java适合企业级应用,需要引用[^1][^3]。 最后,生成相关问题,可能涉及如何选择语言,具体场景下的性能比较,学习曲线等。确保问题覆盖用户可能关心的其他方面,比如内存管理细节或并发实现的例子。</think>### Golang vs Java vs C: 主要区别适用场景 #### 1. **语言设计哲学** - **C语言**:面向过程,强调底层控制和硬件操作,语法简洁但需要手动管理内存。 - **Java**:面向对象,基于JVM实现“一次编写,到处运行”,依赖垃圾回收机制[^2]。 - **Golang**:结合过程式并发编程,语法极简,内置协程(goroutine)和通道(channel)支持高并发。 #### 2. **性能对比** - **C语言**:直接编译为机器码,性能最高,但依赖开发者的优化能力。 - **Golang**:编译为本地代码,性能接近C语言,协程模型在高并发场景下效率显著[^3]。 - **Java**:通过JIT编译优化,长期运行性能接近本地代码,但启动延迟较高[^4]。 #### 3. **语法特性** - **C语言**:需手动管理指针和内存,代码灵活性高但易出错,例如: ```c int* arr = (int*)malloc(10 * sizeof(int)); ``` - **Java**:强类型、面向对象,代码结构清晰但较冗长,例如: ```java public class Main { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); } } ``` - **Golang**:语法类似C但更简洁,例如: ```go func main() { slice := make([]int, 0) } ``` #### 4. **并发模型** - **C语言**:依赖第三方库(如pthread)实现多线程,复杂性高。 - **Java**:通过`java.util.concurrent`包提供线程池和锁机制。 - **Golang**:原生支持协程(goroutine),通过`go`关键字启动,例如: ```go go func() { fmt.Println("并发执行") }() ``` #### 5. **内存管理** - **C语言**:完全手动管理(`malloc/free`),易引发内存泄漏。 - **Java/Golang**:自动垃圾回收(GC),但Golang的GC延迟更低(通常<1ms)。 #### 6. **生态系统** - **C语言**:适用于操作系统、嵌入式开发,标准库功能有限。 - **Java**:企业级框架丰富(如Spring、Hibernate),安卓开发主流语言。 - **Golang**:云原生领域占优(如Docker、Kubernetes),适合微服务和API开发[^3]。 #### 7. **适用场景** - **C语言**:操作系统内核、嵌入式系统、高性能计算。 - **Java**:大型企业应用、安卓应用、金融系统。 - **Golang**:高并发服务(如实时通信)、云平台工具、分布式系统。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值