【C++ 进阶】语句:从基础到实践

目录

一、输入输出体系的范式革命

1.1 C语言的格式化

1.2 C++的流抽象革命

二、字符串处理的抽象跃迁

2.1 C语言的字符指针

2.2 C++的string类革命

三、结构体到类的类型系统进化

3.1 C语言的结构体局限

3.2 C++类的革命性演进

四、基础控制语句差异

4.1 条件语句:if-else 与 switch

4.1.1 if-else 语句

4.1.2 switch 语句

4.2 循环语句:for、while 和 do-while

4.2.1 for 循环

4.2.2 while 和 do-while 循环

五、函数相关语句差异

5.1 函数定义和声明

5.1.1 函数重载

5.1.2 默认参数

5.2 函数调用和返回语句

5.2.1 函数调用

 5.2.2 返回语句

六、类和对象相关语句差异

6.1 类定义和对象创建语句

6.2 成员访问和方法调用语句

七、异常处理语句差异

7.1 C 语言的错误处理

7.2 C++ 的异常处理

八、总结

九、参考资料


C 语言作为一门经典的编程语言,以其高效性和可移植性闻名,广泛应用于系统软件和嵌入式开发等领域。而 C++ 是在 C 语言基础上发展而来的面向对象编程语言,它在兼容 C 语言的同时,引入了众多新特性,极大地增强了语言的表达能力和灵活性。本文将深入探讨 C++ 和 C 语言在语句方面的不同点,更好地理解和运用这两门语言。

一、输入输出体系的范式革命

1.1 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左对齐)实现精确控制
  • 内存操作本质:通过指针直接操作内存地址,&运算符显式获取变量地址

1.2 C++的流抽象革命

C++通过iostream库引入流抽象层:

// C++示例
int a;
double b = 3.1415926;
cin >> a;
cout << "a=" << setw(5) << a << "\nb=" << fixed << setprecision(2) << b;
  • 类型安全流>><<运算符自动处理类型转换
  • 操纵器系统setwfixed等操纵器实现格式化控制
  • 链式调用特性:支持cout << a << b << endl的连续输出

二、字符串处理的抽象跃迁

2.1 C语言的字符指针

C语言通过字符数组和指针实现字符串操作:

char str1[] = "Hello";
char str2[] = "World";
char result[20];strcpy(result, str1);
strcat(result, " ");
strcat(result, str2);
printf("%s\n", result); // 输出:Hello World
  • 函数依赖:需要手动调用strcpystrcat等库函数
  • 缓冲区风险:需预先计算缓冲区大小防止溢出

2.2 C++的string类革命

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管理安全性增强

三、结构体到类的类型系统进化

3.1 C语言的结构体局限

C语言结构体仅为数据容器: 

struct Student {int id;char name[20];
};void printStudent(struct Student s) {printf("ID:%d Name:%s", s.id, s.name);
}
  • 函数分离:操作函数需单独定义
  • 无封装性:所有成员默认公开访问

3.2 C++类的革命性演进

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实现封装
  • 构造函数:支持初始化列表语法
  • 成员函数:方法直接关联对象

四、基础控制语句差异

4.1 条件语句:if-else 与 switch

4.1.1 if-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 语言中,由于没有类和运算符重载的概念,无法实现这样的用法。

4.1.2 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;
}

4.2 循环语句:forwhile 和 do-while

4.2.1 for 循环

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;
}

4.2.2 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;
}

五、函数相关语句差异

5.1 函数定义和声明

5.1.1 函数重载

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 语言中,函数名必须唯一,不支持函数重载。

5.1.2 默认参数

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 语言不支持默认参数。

5.2 函数调用和返回语句

5.2.1 函数调用

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;
}

 5.2.2 返回语句

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 语言中,返回复杂数据结构通常需要手动管理内存,没有移动语义这样的特性。 

六、类和对象相关语句差异

6.1 类定义和对象创建语句

①类定义

C++ 引入了类的概念,类可以包含数据成员和成员函数,并且可以使用访问控制符(publicprivateprotected)来控制成员的访问权限。

// 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 成员访问和方法调用语句

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 语言没有多态和虚函数的概念。

七、异常处理语句差异

7.1 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;
}

7.2 C++ 的异常处理

C++ 引入了异常处理机制,使用 trycatch 和 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 异常处理机制

九、参考资料

  •  《C++ Primer(第 5 版)》这本书是 C++ 领域的经典之作,对 C++ 的基础语法和高级特性都有深入讲解。
  • 《Effective C++(第 3 版)》书中包含了很多 C++ 编程的实用建议和最佳实践。
  • 《C++ Templates: The Complete Guide(第 2 版)》该书聚焦于 C++ 模板编程,而using声明在模板编程中有着重要应用,如定义模板类型别名等。
  • C++ 官方标准文档:C++ 标准文档是最权威的参考资料,可以查阅最新的 C++ 标准(如 C++11、C++14、C++17、C++20 等)文档。例如,ISO/IEC 14882:2020 是 C++20 标准的文档,可从相关渠道获取其详细内容。
  • cppreference.com:这是一个非常全面的 C++ 在线参考网站,提供了详细的 C++ 语言和标准库文档。
  • LearnCpp.com:该网站提供了系统的 C++ 教程,配有丰富的示例代码和清晰的解释,适合初学者学习和理解相关知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38818.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言操作符

&#x1f31f; 各位看官好&#xff0c;我是maomi_9526&#xff01; &#x1f30d; 种一棵树最好是十年前&#xff0c;其次是现在&#xff01; &#x1f680; 今天来学习C语言的相关知识。 &#x1f44d; 如果觉得这篇文章有帮助&#xff0c;欢迎您一键三连&#xff0c;分享给更…

PostgreSQL:语言基础与数据库操作

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;精通Java编…

KMP算法

KMP算法 为什么叫做KMP呢。 因为是由这三位学者发明的&#xff1a;Knuth&#xff0c;Morris和Pratt&#xff0c;所以取了三位学者名字的首字母。所以叫做KMP next数组就是一个前缀表&#xff08;prefix table&#xff09;。 前缀表是用来回退的&#xff0c;它记录了模式串与…

3D点云数据处理中的聚类算法总结

1.欧式聚类&#xff1a; 基于点的空间距离&#xff08;欧几里得距离&#xff09;来分割点云&#xff0c;将距离较近的点归为同一簇。 欧式聚类需要的参数&#xff1a;邻域半径R,簇的最小点阈值minPts&#xff0c;最大点数阈值maxPts。 实现效率&#xff1a; O(n * log n) 实现…

WRC世界机器人大会-2024年展商汇总

2024世界机器人大会 时间&#xff1a;2024年8月21日至25日 地点&#xff1a;北京经济技术开发区北人亦创国际会展中心 大会主题&#xff1a;共育新质生产力&#xff0c;共享智能新未来 2024世界机器人博览会亮点纷呈&#xff0c;20余款人形机器人整机将亮相博览会&#xff…

拉取镜像,推送到阿里云镜像仓库

需求背景&#xff1a;在学习k8s&#xff0c;虚拟机无法正常拉取 wangyanglinux/tools:busybox 镜像。 解决办法&#xff1a;将墙外镜像拉到国内&#xff08;阿里云&#xff09;再使用 准备工作需要创建对应的镜像仓库&#xff0c;然后再进行推送 1. 拉取镜像 docker pull …

DeepSeek和Kimi在Neo4j中的表现

以下是2个最近爆火的人工智能工具&#xff0c; DeepSeek:DeepSeek Kimi: Kimi - 会推理解析&#xff0c;能深度思考的AI助手 1、提示词&#xff1a; 你能帮我生成一个知识图谱吗&#xff0c;等一下我会给你一篇文章&#xff0c;帮我从内容中提取关键要素&#xff0c;然后以N…

哈尔滨工业大学DeepSeek公开课人工智能:大模型原理 技术与应用-从GPT到DeepSeek|附视频下载方法

导 读INTRODUCTION 今天继续哈尔滨工业大学车万翔教授带来了一场主题为“DeepSeek 技术前沿与应用”的报告。 本报告深入探讨了大语言模型在自然语言处理&#xff08;NLP&#xff09;领域的核心地位及其发展历程&#xff0c;从基础概念出发&#xff0c;延伸至语言模型在机器翻…

redis解决缓存穿透/击穿/雪崩

文章目录 1.缓存穿透1.1 概念1.2 解决方案1.2.1 缓存空对象1.2.2 布隆过滤 1.2 店铺查询使用缓存穿透解决方案1.2.1 流程 2.缓存雪崩2.1 什么是缓存雪崩&#xff1f;2.2 雪崩解决方案 3.缓存击穿3.1 什么是缓存击穿&#xff1f;3.2解决方案3.2.1 基于互斥锁解决缓存击穿问题&am…

不连续平面提取

不连续平面提取 提取流程 #mermaid-svg-Y87uP8WsVRmPYriG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Y87uP8WsVRmPYriG .error-icon{fill:#552222;}#mermaid-svg-Y87uP8WsVRmPYriG .error-text{fill:#552222;s…

大语言模型-2.2/3-主流模型架构与新型架构

简介 本博客内容是《大语言模型》一书的读书笔记&#xff0c;该书是中国人民大学高瓴人工智能学院赵鑫教授团队出品&#xff0c;覆盖大语言模型训练与使用的全流程&#xff0c;从预训练到微调与对齐&#xff0c;从使用技术到评测应用&#xff0c;帮助学员全面掌握大语言模型的…

数据库操作练习

一.向heros表中新增一列信息&#xff0c;添加一些约束&#xff0c;并尝试查询一些信息 //向表中添加一列age信息 alter table heros add column age int;//id列添加主键约束&#xff0c;设置自增 alter table heros modify column id int auto_increment primary key;//name列…

CTF【WEB】学习笔记1号刊

Kali的小工具箱 curl www.xxx.com&#xff1a;查看服务器响应返回的信息 curl -I www.xxx.com:查看响应的文件头 一、cmd执行命令 ipconfig&#xff1a;ip地址配置等&#xff1b; 二、 Kali操作 1.sudo su&#xff1b; 2.msfconsole 3.search ms17_010 永恒之蓝&#xff…

在 SaaS 应用上构建 BI 能力的实战之路

SaaS 产品在持续运营过程中积累了大量数据&#xff0c;这些数据不仅是数字的记录&#xff0c;更是洞察市场趋势、优化产品功能、提升用户体验的宝贵资源。 因此&#xff0c;大部分的 SaaS 产品在发展到一定阶段后&#xff0c;都会开始构建自己的报表模块或分析模块&#xff0c;…

gonet开源游戏服务器环境配置

1.mysql搭建 搜索mysql-server apt安装包名 sudo apt search mysql-server 安装mysql-server sudo apt-get install mysql-server 安装完成后会&#xff0c;启动mysql服务及创建系统服务 查看服务状态 systemctl status mysql.service 使用超级权限登陆mysql sudo mysql 授…

STM32基础篇(五)------TIM定时器比较输出

简介 定时器的类型 在《STM32F10xxx参考手册&#xff08;中文&#xff09;.pdf》中可以看到下面三个章节 因此可以得到 高级定时器含有通用定时器的所有功能&#xff0c;通用定时器含有基本定时器的所有功能&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;…

基于STM32的两路电压测量仿真设计Proteus仿真+程序设计+设计报告+讲解视频

基于STM32两路电压测量仿真设计(Proteus仿真程序设计设计报告讲解视频&#xff09; 仿真图Proteus 8.9 程序编译器&#xff1a;keil 5 编程语言&#xff1a;C语言 设计编号&#xff1a;C0106 1.主要功能 基于STM32单片机设计一个双路电压检测器 1.系统可以测量两路输入电…

210、【图论】课程表(Python)

题目 思路 这道题本质上是一个拓扑排序。每次先统计每个点的入度个数、然后再统计点与点之间的邻接关系&#xff0c;找到入度为0的点作为起始遍历点。之后每遍历到这个点之后&#xff0c;就把这个点后续的邻接关系边的点入度减去一。当某个点入度为0时&#xff0c;继续被加入其…

react 杂记2 优化hook

useEffect 每个Fiber节点都会为该组件的所有effec对象​维护一个链表, 场景​类组件方法函数组件等效写法差异说明挂载时执行componentDidMount()useEffect(fn, [])useEffect 副作用在浏览器绘制后异步执行&#xff1b;componentDidMount 是同步的。更新时执行componentDidUp…

Java内存泄漏、CPU飙升排查

在Java应用开发中&#xff0c;内存泄漏和CPU飙升是两类高频出现的生产问题&#xff0c;也是常见的面试问题。这里通过一些demo进行实践。 内存泄漏 private static List<byte[]> leakList new ArrayList<>();GetMapping("/memory/leak") public void …