Objective-C 是 C 语言的超集,它在 C 语言的基础上添加了面向对象的特性。

(图片来源网络,侵删)
下面我们从几个维度来详细对比和解释它们的关系。
核心关系:超集与扩展
可以把 C 语言看作是 Objective-C 的“地基”,Objective-C 完全兼容 C 语言的所有特性,你可以在 Objective-C 代码中无缝地使用 C 语言的语法、函数、指针、数据结构等。
示例:
一个有效的 C 代码文件(test.c)可以直接改名为 .m(Objective-C 的源文件后缀)并正常编译。
// C 代码
#include <stdio.h>
void sayHello() {
printf("Hello from C!\n");
}
int main() {
sayHello();
return 0;
}
这段代码在 Objective-C 中(文件后缀为 .m)是完全合法的。

(图片来源网络,侵删)
反过来不成立。 C 语言不认识 Objective-C 的特有关键字和语法,所以你不能在纯 C 编译器(如 gcc)中编译 Objective-C 代码。
关键区别:面向对象 vs. 过程式
这是两者最根本的区别。
C 语言:过程式编程
C 语言是一种过程式编程语言,它的核心思想是“函数”,程序被看作是一系列按顺序执行的函数调用,数据和处理数据的函数是分离的。
- 数据结构:使用
struct来组织数据。 - 函数:函数是独立的操作单元,可以操作任何数据。
- 代码组织:通过函数和文件来组织代码。
- 内存管理:手动管理,使用
malloc和free。
示例:C 语言实现一个“人”
#include <stdio.h>
#include <string.h>
// 数据结构
struct Person {
char name[50];
int age;
};
// 操作函数
void printPerson(struct Person p) {
printf("Name: %s, Age: %d\n", p.name, p.age);
}
int main() {
// 创建一个 Person 实例
struct Person person1;
strcpy(person1.name, "Zhang San");
person1.age = 30;
// 调用函数来操作数据
printPerson(person1);
return 0;
}
在这个例子中,struct Person 只是一个数据的集合,printPerson 是一个独立的函数,两者没有内在的绑定关系。
Objective-C:面向对象编程
Objective-C 在 C 的基础上引入了面向对象编程 的思想,它的核心是“对象”和“消息”。
- 类:使用
@interface和@implementation关键字来定义类,它包含了数据(成员变量/实例变量)和操作这些数据的方法。 - 对象:类的实例。
- 消息:对象之间通过发送消息来通信,调用一个方法,在 Objective-C 中被称为“向对象发送一个消息”。
- 继承:支持单继承。
- 动态性:Objective-C 是一门动态语言,很多操作(如方法调用、类型检查)在运行时才确定,这赋予了它极大的灵活性。
- 内存管理:早期是手动管理(
retain,release),后来引入了自动引用计数机制,现在由 ARC(Automatic Reference Counting)自动管理。
示例:Objective-C 实现一个“人”
// Person.h (接口文件,相当于头文件)
#import <Foundation/Foundation.h>
// @interface 定义类的公共接口
@interface Person : NSObject // 继承自根类 NSObject
@property (nonatomic, copy) NSString *name; // 属性,自动生成成员变量和 getter/setter
@property (nonatomic, assign) NSInteger age;
// 方法声明
- (void)printInfo;
@end
// Person.m (实现文件)
#import "Person.h"
// @implementation 定义类的具体实现
@implementation Person
// 方法实现
- (void)printInfo {
// 使用 self 访问对象的成员变量或调用其他方法
NSLog(@"Name: %@, Age: %ld", self.name, (long)self.age);
}
@end
// main.m
#import <Foundation/Foundation.h>
#import "Person.h"
int main(int argc, const char * argv[]) {
@autoreleasepool {
// 1. 创建对象 (发送 alloc 消息)
Person *person1 = [[Person alloc] init];
// 2. 通过点语法或 setter 方法给对象赋值 (发送 setName: 和 setAge: 消息)
person1.name = @"Li Si";
person1.age = 25;
// 3. 调用对象的方法 (发送 printInfo 消息)
[person1 printInfo];
}
return 0;
}
在这个例子中:
Person是一个类,它封装了数据(name,age)和行为(printInfo)。person1是一个Person类的对象。[person1 printInfo]是向person1对象发送printInfo消息。
详细对比表格
| 特性 | C 语言 | Objective-C |
|---|---|---|
| 编程范式 | 过程式编程 | 面向对象编程 (同时支持过程式) |
| 语法 | 简洁、底层 | 语法独特,使用大量方括号 [] 和 符号 |
| 核心概念 | 函数、数据结构 | 对象、类、消息传递 |
| 内存管理 | 手动 (malloc, free) |
自动引用计数,也可手动管理 |
| 运行时 | 静态链接,编译时确定大部分事情 | 动态运行时,很多操作在运行时决定 |
| 标准库 | C 标准库 | C 标准库 + Foundation框架 (提供字符串、数组、集合等高级对象) |
| 类型系统 | 静态类型,编译时检查 | 静态类型,但运行时支持动态类型 (id 类型) |
| 继承 | 不支持 | 支持单继承 |
| 字符串 | char* 字符数组,需要手动管理内存 |
NSString 对象,自动管理内存,功能强大 |
| 平台 | 跨平台 | 传统上强绑定于 macOS 和 iOS,但现在也可跨平台 |
总结与演进
-
历史与定位:
- C 语言:诞生于 20 世纪 70 年代,是现代操作系统的基石(如 Windows, Linux, macOS 内核),它追求效率和对硬件的直接控制,是系统编程、嵌入式开发的首选。
- Objective-C:诞生于 80 年代,由 Smalltalk 语言演化而来,它在 C 的基础上加入了 Smalltalk 的面向对象消息传递机制,它在 90 年代成为 NeXTSTEP(后来是 macOS 和 iOS)的开发语言,因此成为了苹果生态系统的“官方语言”。
-
现代应用:
- C 语言:至今依然活跃,用于操作系统内核、驱动程序、高性能计算、游戏引擎、嵌入式系统等对性能和内存控制要求极高的领域。
- Objective-C:主要用于维护和开发遗留的 macOS 和 iOS 项目,苹果公司已经推出了新的编程语言 Swift 来取代它,Swift 更现代、更安全、更易用,已成为苹果平台开发的首选和未来,由于庞大的存量代码和底层框架(如 UIKit)仍由 Objective-C 写成,Objective-C 在可预见的未来仍会是一个重要的技能。
-
如何选择:
- 如果你想学习系统底层、嵌入式开发或追求极致的性能,学习 C 语言 是基础。
- 如果你想维护旧的苹果项目,或者需要深入理解苹果框架的内部实现,你需要学习 Objective-C。
- 如果你想进行新的苹果平台(iOS, macOS, watchOS, tvOS)应用开发,你应该直接学习 Swift。
一个形象的比喻:
- C 语言 像是一套工具箱和蓝图,你需要自己动手用扳手、螺丝刀(
malloc,free)按照蓝图(struct)来搭建一个东西。 - Objective-C 像是给你一个智能化的机器人工厂,你先设计好机器人的蓝图(
@interface),然后工厂(alloc)会根据蓝图给你生产出一个个机器人(对象),你不需要关心机器人内部的螺丝是怎么拧的,你只需要给它发指令([robot doSomething]),它就会执行。
希望这个详细的解释能帮助你彻底理解 Objective-C 和 C 语言的关系与区别!
