当前位置: 首页 > news >正文

探索 C 与 Java/Kotlin 的语言差异:从指针到高阶函数

作为一名熟悉 Java 和 Kotlin 的开发者,初次接触 C/C++ 时常会遇到一系列概念上的“文化冲击”。本文将从几个关键点出发,帮助你更好地理解 C/C++ 与 Java/Kotlin 在语言设计上的核心区别。


1. 指向未知类型的指针 void*、结构体指针访问 ->、空指针常量 nullptr

(1) void*:可以指向任何类型的指针

在 C 中,void* 是一种通用指针类型,常用于参数类型不确定的场景。

void print_value(void* ptr, int type) {if (type == 0) printf("%d", *(int*)ptr);else if (type == 1) printf("%f", *(float*)ptr);
}

你可以将 void* 转换为具体类型后使用,相当于 Java 中的 Object,但它完全没有类型安全保障。


(2) ->:结构体指针访问成员的语法

如果你有一个结构体指针,可以用 -> 操作符访问它的成员。

struct Person {int age;
};Person p = {20};
Person* ptr = &p;
printf("%d", ptr->age);  // 等价于 (*ptr).age

这相当于 Kotlin 中的 person.age,不过这里访问的是指针指向的结构体成员。


(3) nullptr:C++ 中的空指针常量

C++ 引入了 nullptr,它是一个类型安全的空指针替代 NULL

int* p = nullptr; // 安全地表示一个空指针

类似于 Java/Kotlin 中的 null,但 nullptr 是一个关键字,不会误用为整数 0。


2. 栈对象 vs 堆对象:C++ 中对象的创建方式

(1) 栈上创建对象

Person p{20}; // 栈上对象,生命周期随作用域结束自动释放

(2) 堆上创建对象

Person* p = new Person(20); // 堆上对象,需手动 delete

在 Kotlin 中,所有对象都是在堆上创建,由 JVM 的垃圾回收机制管理内存;而 C++ 给了开发者更多控制权,但也带来了内存管理的负担。


3. C 语言的结构体能定义函数指针,Java 的类只能定义变量/方法

在 Java 中,类中只能写方法和变量,方法不能被当作值赋给变量。
但在 C 中,结构体除了能声明变量,还能声明“函数指针”,如下所示:

struct Greeter {void (*sayHello)();
};void greet() {printf("Hello!\n");
}int main() {Greeter g = { greet };g.sayHello(); // 调用函数指针return 0;
}

这就像是给结构体添加了“行为”,尽管 C 并不是面向对象语言。


4. C 的函数指针 = Kotlin 的高阶函数?

C 语言中的函数指针,本质上就是“可以把函数当作变量”的方式:

void greet() {printf("Hi\n");
}void run_twice(void (*func)()) {func(); func();
}

而 Kotlin 的高阶函数也做了类似的事,只是语法更现代:

fun runTwice(action: () -> Unit) {action()action()
}fun greet() = println("Hi")fun main() {runTwice(::greet)
}

可以认为 Kotlin 把 C 的函数指针“包装”成了类型安全、可推断的高阶函数。


总结:不同语言,相似理念

特性CJavaKotlin
函数作为值✅ 函数指针❌(Java 8 前不支持)✅ 高阶函数
通用指针/对象void*ObjectAny?
空指针NULL / nullptrnullnull
方法指针函数指针Lambda (Java 8+)函数类型 / Lambda
对象内声明函数函数指针变量方法(不能赋值)可以将函数存为变量

学习 C/C++ 的过程,其实是补足你对内存、函数本质和语言底层的理解,非常适合有 Java/Kotlin 背景的开发者进阶。


如果你正在从 Java/Kotlin 走向底层世界,C/C++ 会是你绕不开的一站。理解这些基础概念,就像打开一扇通往计算机世界核心的大门 🚪

相关文章:

  • 深入定制 QSlider——实现精准点击跳转与拖拽区分
  • 用Python手搓一个简单的饭店管理系统(上篇)
  • 依赖注入(DI)与自动装配的深度分析:优势、局限与实践考量
  • 智慧城市:如同为城市装上智能大脑,开启智慧生活
  • 用 Depcheck 去除Vue项目没有用到的依赖
  • GitHub action中的 jq 是什么? 常用方法有哪些
  • 计算机保研机试准备——C++算法题
  • 【cmake-笔记】
  • CANDENCE 原理图元件有多个相同名称引脚报错
  • 2.区间dp
  • QML TableView:基础用法和自定义样式实现
  • ROW_NUMBER 函数
  • 嵌入式开发_电能计量芯片HLW8110与HLW8112
  • Mysql-视图和存储过程
  • 在 K8s 上构建和部署容器化应用程序(Building and Deploying Containerized Applications on k8s)
  • THCON 2025
  • 向量数据库Qdrant 安装 不使用docker
  • Windows进行磁盘分区/扩容
  • vue3项目如何在index.html中根据环境(开发,生产)动态切换js src路径
  • 事件触发控制与响应驱动控制的定义、种类及区别
  • 广东音像城清退,发烧友紧急“淘宝”,曾见证广州音乐黄金期
  • 为溶血性疾病治疗提供新靶点,专家团队在《细胞》发文
  • 数智时代出版专业技能人才培养研讨会在沪举行
  • 徐州沛县一村委会因无资质处理固废,被环保部门罚款19万元
  • 一季度全社会用电量同比增长2.5%,3月增速显著回升
  • 女子报警称醉酒后疑似被性侵,长沙警方:嫌犯邱某某已被刑拘