
C 语言作为一门经典的编程语言,以其高效性和可移植性闻名,广泛应用于系统软件和嵌入式开发等领域。而 C++ 是在 C 语言基础上发展而来的面向对象编程语言,它在兼容 C 语言的同时,引入了众多新特性,极大地增强了语言的表达能力和灵活性。本文将深入探讨 C++ 和 C 语言在语句方面的不同点,更好地理解和运用这两门语言。
C语言的scanf/printf体系构建了一个精细的格式控制王国:
// C语言示例
int a;
double b = 3.1415926;
scanf("%d", &a);
printf("a=%-5d\nb=%6.2f", a, b);%d、%f等基础类型符配合修饰符(如%-5d左对齐)实现精确控制&运算符显式获取变量地址C++通过iostream库引入流抽象层:
// C++示例
int a;
double b = 3.1415926;
cin >> a;
cout << "a=" << setw(5) << a
<< "\nb=" << fixed << setprecision(2) << b;>>和<<运算符自动处理类型转换setw、fixed等操纵器实现格式化控制cout << a << b << endl的连续输出C语言通过字符数组和指针实现字符串操作:
char str1[] = "Hello";
char str2[] = "World";
char result[20];
strcpy(result, str1);
strcat(result, " ");
strcat(result, str2);
printf("%s\n", result); // 输出:Hello Worldstrcpy、strcat等库函数C++引入std::string类实现面向对象操作:
#include <string>
using namespace std;
string str1 = "Hello";
string str2 = "World";
string result = str1 + " " + str2;
cout << result << endl; // 输出:Hello World+直接拼接字符串substr()、find()等高级方法性能对比表:
操作类型 | C语言实现 | C++实现 | 时间复杂度 |
|---|---|---|---|
字符串拼接 | O(n) 需手动计算长度 | O(1) 运算符重载 | 优化显著 |
子串查找 | O(n) 遍历比较 | O(n) 但算法优化 | 效率提升 |
内存管理 | 手动malloc/free | 自动RAII管理 | 安全性增强 |
C语言结构体仅为数据容器:
struct Student {
int id;
char name[20];
};
void printStudent(struct Student s) {
printf("ID:%d Name:%s", s.id, s.name);
}C++类实现完整面向对象特性:
class Student {
private:
int id;
string name;
public:
Student(int i, string n) : id(i), name(n) {}
void print() {
cout << "ID:" << id << " Name:" << name;
}
};private/public实现封装if-else 与 switchif-else 语句在 C 和 C++ 中,if-else 语句的基本语法相似,但 C++ 支持更复杂的条件表达式。例如,C++ 可以使用类对象的布尔转换运算符作为条件。
// C++ 示例
#include <iostream>
class BooleanWrapper {
private:
bool value;
public:
BooleanWrapper(bool val) : value(val) {}
operator bool() const { return value; }
};
int main() {
BooleanWrapper wrapper(true);
if (wrapper) {
std::cout << "Wrapper is true." << std::endl;
}
return 0;
}
在 C 语言中,由于没有类和运算符重载的概念,无法实现这样的用法。
switch 语句C++ 的 switch 语句在功能上与 C 语言基本相同,但 C++ 允许 switch 表达式为枚举类型,并且可以使用 constexpr 变量。
// C++ 枚举类型在 switch 中的使用
#include <iostream>
enum Color { RED, GREEN, BLUE };
int main() {
Color myColor = RED;
switch (myColor) {
case RED:
std::cout << "The color is red." << std::endl;
break;
case GREEN:
std::cout << "The color is green." << std::endl;
break;
case BLUE:
std::cout << "The color is blue." << std::endl;
break;
default:
std::cout << "Unknown color." << std::endl;
}
return 0;
}
for、while 和 do-whilefor 循环C++11 引入了范围 for 循环,这是 C 语言所没有的。范围 for 循环可以方便地遍历容器和数组。
// C++ 范围 for 循环示例
#include <iostream>
#include <vector>
int main() {
std::vector<int> numbers = {1, 2, 3, 4, 5};
for (int num : numbers) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
在 C 语言中,需要使用传统的 for 循环来遍历数组。
// C 语言传统 for 循环遍历数组示例
#include <stdio.h>
int main() {
int numbers[] = {1, 2, 3, 4, 5};
int size = sizeof(numbers) / sizeof(numbers[0]);
for (int i = 0; i < size; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
return 0;
}
while 和 do-while 循环while 和 do-while 循环在 C 和 C++ 中的基本语法相同,但 C++ 可以使用更复杂的条件表达式,例如包含类对象的比较操作。
// C++ 中 while 循环使用类对象比较示例
#include <iostream>
class Counter {
private:
int count;
public:
Counter(int c) : count(c) {}
bool operator>(int value) const { return count > value; }
void decrement() { count--; }
};
int main() {
Counter counter(5);
while (counter > 0) {
std::cout << counter > 0;
counter.decrement();
}
std::cout << std::endl;
return 0;
}C++ 支持函数重载,即可以定义多个同名函数,但它们的参数列表必须不同(参数个数、类型或顺序不同)。
#include <iostream>
class Counter {
private:
int count;
public:
Counter(int c) : count(c) {}
bool operator>(int value) const { return count > value; }
void decrement() { count--; }
// 添加输出运算符重载(可选)
friend std::ostream& operator<<(std::ostream& os, const Counter& c) {
os << c.count;
return os;
}
};
int main() {
Counter counter(5);
while (counter > 0) {
std::cout << (counter > 0); // 输出布尔值(1/0)
counter.decrement();
}
std::cout << std::endl;
return 0;
}
在 C 语言中,函数名必须唯一,不支持函数重载。
C++ 允许为函数参数设置默认值,调用函数时可以省略这些参数。
// C++ 默认参数示例
#include <iostream>
int add(int a, int b = 10) {
return a + b;
}
int main() {
int result1 = add(1);
int result2 = add(1, 2);
std::cout << "Result 1: " << result1 << std::endl;
std::cout << "Result 2: " << result2 << std::endl;
return 0;
}
C 语言不支持默认参数。
C++ 支持函数对象(仿函数)的调用,这是 C 语言所没有的。函数对象是一个重载了 () 运算符的类对象。
// C++ 函数对象示例
#include <iostream>
class Adder {
public:
int operator()(int a, int b) {
return a + b;
}
};
int main() {
Adder adder;
int result = adder(1, 2);
std::cout << "Result: " << result << std::endl;
return 0;
}
C++ 可以返回类对象,并且支持移动语义,避免不必要的拷贝。
// C++ 返回类对象并使用移动语义示例
#include <iostream>
#include <vector>
class MyVector {
private:
std::vector<int> data;
public:
MyVector(std::vector<int> vec) : data(std::move(vec)) {}
MyVector(MyVector&& other) noexcept : data(std::move(other.data)) {}
void print() {
for (int num : data) {
std::cout << num << " ";
}
std::cout << std::endl;
}
};
MyVector createVector() {
std::vector<int> vec = {1, 2, 3};
return MyVector(vec);
}
int main() {
MyVector myVec = createVector();
myVec.print();
return 0;
}
在 C 语言中,返回复杂数据结构通常需要手动管理内存,没有移动语义这样的特性。
①类定义
C++ 引入了类的概念,类可以包含数据成员和成员函数,并且可以使用访问控制符(public、private、protected)来控制成员的访问权限。
// C++ 类定义示例
#include <iostream>
class Rectangle {
private:
int width;
int height;
public:
Rectangle(int w, int h) : width(w), height(h) {}
int area() {
return width * height;
}
};
int main() {
Rectangle rect(3, 4);
std::cout << "Area: " << rect.area() << std::endl;
return 0;
}
C 语言没有类的概念,使用结构体来组织数据,但结构体中不能包含成员函数。
// C 语言结构体示例
#include <stdio.h>
typedef struct {
int width;
int height;
} Rectangle;
int area(Rectangle rect) {
return rect.width * rect.height;
}
int main() {
Rectangle rect = {3, 4};
printf("Area: %d\n", area(rect));
return 0;
}
②对象创建
C++ 可以使用构造函数来初始化对象,并且支持多种对象创建方式,如栈上创建和堆上创建。
// C++ 对象创建示例
#include <iostream>
class Circle {
private:
double radius;
public:
Circle(double r) : radius(r) {}
double area() {
return 3.14 * radius * radius;
}
};
int main() {
// 栈上创建对象
Circle circle1(2.0);
std::cout << "Circle 1 area: " << circle1.area() << std::endl;
// 堆上创建对象
Circle* circle2 = new Circle(3.0);
std::cout << "Circle 2 area: " << circle2->area() << std::endl;
delete circle2;
return 0;
}
在 C 语言中,使用结构体时需要手动初始化成员变量。
6.2.1 成员访问
C++ 可以使用 . 和 -> 运算符访问类的成员,同时还可以通过成员函数访问私有成员。
// C++ 成员访问示例
#include <iostream>
class Person {
private:
std::string name;
public:
Person(const std::string& n) : name(n) {}
std::string getName() {
return name;
}
};
int main() {
Person person("John");
std::cout << "Name: " << person.getName() << std::endl;
Person* personPtr = &person;
std::cout << "Name: " << personPtr->getName() << std::endl;
return 0;
}
C 语言使用 . 和 -> 运算符访问结构体成员,但没有私有成员的概念。
6.2.2 方法调用
C++ 的成员函数可以使用 this 指针来引用当前对象,并且支持虚函数和多态。
// C++ 方法调用和多态示例
#include <iostream>
class Shape {
public:
virtual void draw() {
std::cout << "Drawing a shape." << std::endl;
}
};
class Circle : public Shape {
public:
void draw() override {
std::cout << "Drawing a circle." << std::endl;
}
};
void drawShape(Shape& shape) {
shape.draw();
}
int main() {
Circle circle;
drawShape(circle);
return 0;
}
C 语言没有多态和虚函数的概念。
C 语言通常使用返回值来表示错误,调用者需要检查返回值来判断函数是否执行成功。
// C 语言错误处理示例
#include <stdio.h>
#include <stdlib.h>
int divide(int a, int b, int* result) {
if (b == 0) {
return -1; // 表示错误
}
*result = a / b;
return 0; // 表示成功
}
int main() {
int result;
int status = divide(10, 0, &result);
if (status == -1) {
printf("Error: division by zero!\n");
} else {
printf("Result: %d\n", result);
}
return 0;
}
C++ 引入了异常处理机制,使用 try、catch 和 throw 关键字来处理异常。
// C++ 异常处理示例
#include <iostream>
int divide(int a, int b) {
if (b == 0) {
throw "Division by zero!";
}
return a / b;
}
int main() {
try {
int result = divide(10, 0);
std::cout << "Result: " << result << std::endl;
} catch (const char* msg) {
std::cout << "Error: " << msg << std::endl;
}
return 0;
}
C++ 在兼容 C 语言语句的基础上,引入了众多新特性,如函数重载、默认参数、类和对象、异常处理等,使得 C++ 在表达能力和灵活性上有了很大的提升。这些新特性能够更方便地编写复杂的程序,提高代码的可维护性和可扩展性。然而,C 语言由于其简洁性和高效性,在一些对性能要求极高的场景中仍然有着广泛的应用。开发者可以根据具体的需求选择合适的编程语言。
对比点 | C 语言 | C++ |
|---|---|---|
条件语句 | 基本语法简单,条件表达式较单一 | 支持更复杂条件表达式,如类对象布尔转换 |
循环语句 | 传统 for、while、do - while 循环 | 增加范围 for 循环,可方便遍历容器 |
函数定义 | 函数名唯一,不支持重载和默认参数 | 支持函数重载和默认参数 |
函数调用 | 普通函数调用 | 支持函数对象调用 |
类和对象 | 无类概念,用结构体组织数据 | 引入类,有访问控制和多态等特性 |
异常处理 | 通过返回值判断错误 | 引入 try - catch - throw 异常处理机制 |
using声明在模板编程中有着重要应用,如定义模板类型别名等。