C++与C的基本不同

devtools/2025/3/29 7:54:09/

文章目录

      • 变量定义规则
        • 1. 基本语法
        • 2. 初始化
        • 3. 作用域
        • 4. 存储类别
      • 函数定义规则
        • 1. 基本语法
        • 2. 函数声明和定义
        • 3. 默认参数
        • 4. 内联函数
    • 解析
      • 输出流
      • void BluetoothA2DPSink::start(const char* name)
      • class BluetoothA2DPSink : public BluetoothA2DPCommon

C++是在C语言基础上发展而来的,它保留了C语言的大部分特性,同时增加了许多新特性。下面详细介绍C++定义函数与变量的基本规则,并与C语言进行对比。

变量定义规则

1. 基本语法

C和C++在变量定义的基本语法上是相同的,都是类型 变量名; 。例如:

// C语言示例
int num;
float price;
// C++示例
int num;
float price;
2. 初始化
  • C语言:可以在定义变量时进行初始化,也可以后续赋值。例如:
// 定义时初始化
int a = 10;
// 后续赋值
int b;
b = 20;
  • C++:除了上述方式,还支持使用构造函数语法进行初始化,同时引入了列表初始化(C++11及以后)。例如:
// 传统初始化
int a = 10;
// 构造函数语法初始化
int b(20);
// 列表初始化
int c{30};
3. 作用域
  • C语言:变量的作用域主要分为局部作用域和全局作用域。局部变量在函数内部定义,只能在函数内部使用;全局变量在函数外部定义,可以在整个程序中使用。
#include <stdio.h>// 全局变量
int global_var = 100;void test() {// 局部变量int local_var = 200;printf("Global var: %d, Local var: %d\n", global_var, local_var);
}int main() {test();return 0;
}
  • C++:除了局部和全局作用域,还引入了命名空间作用域和类作用域。命名空间可以避免全局命名冲突,类作用域用于类的成员变量。
#include <iostream>// 命名空间
namespace MyNamespace {int var = 10;
}class MyClass {
public:int member_var = 20;
};int main() {// 使用命名空间中的变量std::cout << "Namespace var: " << MyNamespace::var << std::endl;// 使用类的成员变量MyClass obj;std::cout << "Class member var: " << obj.member_var << std::endl;return 0;
}
4. 存储类别
  • C语言:有四种存储类别,分别是autostaticregisterextern
#include <stdio.h>// extern声明外部变量
extern int external_var;void test() {// auto变量auto int local_auto = 10;// static变量static int local_static = 20;printf("Local auto: %d, Local static: %d\n", local_auto, local_static);local_static++;
}int main() {test();test();return 0;
}// 外部变量定义
int external_var = 30;
  • C++:保留了这些存储类别,同时增加了一些新的特性,如constexpr(C++11及以后)用于定义编译时常量。
#include <iostream>// constexpr常量
constexpr int constant_value = 40;int main() {std::cout << "Constant value: " << constant_value << std::endl;return 0;
}

函数定义规则

1. 基本语法

C和C++在函数定义的基本语法上也是相同的,都是返回类型 函数名(参数列表) { 函数体 } 。例如:

// C语言示例
int add(int a, int b) {return a + b;
}
// C++示例
int add(int a, int b) {return a + b;
}
2. 函数声明和定义
  • C语言:函数可以先声明后定义,也可以直接定义。声明时需要指定函数的返回类型和参数列表。
#include <stdio.h>// 函数声明
int subtract(int a, int b);int main() {int result = subtract(10, 5);printf("Result: %d\n", result);return 0;
}// 函数定义
int subtract(int a, int b) {return a - b;
}
  • C++:同样支持函数声明和定义的分离,并且可以使用函数重载(C语言不支持)。函数重载允许定义多个同名函数,但参数列表不同。
#include <iostream>// 函数声明
int add(int a, int b);
double add(double a, double b);int main() {int int_result = add(1, 2);double double_result = add(1.1, 2.2);std::cout << "Int result: " << int_result << std::endl;std::cout << "Double result: " << double_result << std::endl;return 0;
}// 函数定义
int add(int a, int b) {return a + b;
}double add(double a, double b) {return a + b;
}
3. 默认参数
  • C语言:不支持默认参数。
  • C++:允许在函数声明或定义时为参数指定默认值。调用函数时,如果没有提供该参数的值,则使用默认值。
#include <iostream>// 带有默认参数的函数
int multiply(int a, int b = 1) {return a * b;
}int main() {int result1 = multiply(5);  // 使用默认参数int result2 = multiply(5, 2);  // 提供参数值std::cout << "Result 1: " << result1 << std::endl;std::cout << "Result 2: " << result2 << std::endl;return 0;
}
4. 内联函数
  • C语言:没有内联函数的概念,但可以使用宏来实现类似的功能。
#include <stdio.h>// 宏定义
#define MAX(a, b) ((a) > (b) ? (a) : (b))int main() {int max_val = MAX(10, 20);printf("Max value: %d\n", max_val);return 0;
}
  • C++:引入了内联函数的概念,使用inline关键字声明。编译器会尝试将内联函数的代码直接嵌入到调用处,以减少函数调用的开销。
#include <iostream>// 内联函数
inline int max(int a, int b) {return (a > b) ? a : b;
}int main() {int max_val = max(10, 20);std::cout << "Max value: " << max_val << std::endl;return 0;
}

综上所述,C++在变量和函数定义方面保留了C语言的基本规则,同时增加了许多新特性,如命名空间、类作用域、函数重载、默认参数和内联函数等,这些特性使得C++更加灵活和强大。

解析

输出流

 std::cout << "Namespace var: " << MyNamespace::var << std::endl;

把一条信息输出到标准输出流(通常为控制台)。输出的信息包含一段固定的字符串 "Namespace var: " 以及命名空间 MyNamespace 里变量 var 的值,最后换行

  1. std::cout

    std::cout 是 C++ 标准库 iostream 中的一个对象,其类型为 std::ostream,它代表标准输出流,一般和控制台屏幕相关联。
    std 是 C++ 标准库所使用的命名空间,借助作用域解析运算符 :: 能够访问该命名空间里的元素。

  2. << 运算符

    << 是输出流插入运算符,在 C++ 里被重载用于 std::ostream 对象。它的作用是把右侧的数据插入到左侧的输出流里。
    此运算符能够进行链式调用,也就是可以在同一个语句中多次使用,从而把多个数据依次插入到输出流。

  3. "Namespace var: "

    这是一个字符串字面量,其类型为 const char[]。借助 << 运算符,这个字符串会被插入到 std::cout 输出流中。

  4. MyNamespace::var

    MyNamespace 属于用户自定义的命名空间,用于防止全局命名冲突。
    var 是定义在 MyNamespace 命名空间中的变量。通过作用域解析运算符 ::,能够访问这个命名空间里的 var 变量。
    这个变量的值会被插入到 std::cout 输出流中。

  5. std::endl

    std::endl 同样是 C++ 标准库 iostream 中的一个操纵符,其类型为 std::ostream& (*)(std::ostream&)。
    它的作用有两个:一是向输出流插入换行符 ‘\n’;二是刷新输出流缓冲区,确保数据立即被输出。

输出结果会是:

Namespace var: 10

void BluetoothA2DPSink::start(const char* name)

成员函数的声明,函数名为 start,它属于 BluetoothA2DPSink 类。此函数的返回类型为 void,意味着它不会返回任何值,并且它接收一个 const char* 类型的参数 name。

BluetoothA2DPSink::

BluetoothA2DPSink 是一个类名,表明 start 函数是 BluetoothA2DPSink 类的成员函数。
:: 是作用域解析运算符,其作用是明确指定函数所属的类。借助这个运算符,能够在类的外部定义类的成员函数。

start

start 是函数的名称。通常,函数名会反映其功能,从这个名称推测,这个函数可能用于启动蓝牙 A2DP 接收器的相关操作。

(const char* name)

这是函数的参数列表,该函数接收一个参数。const char* 是参数的类型,它代表一个指向常量字符的指针,也就是指向一个以 '\0' 结尾的字符串。const 关键字表明这个指针所指向的字符内容不能被修改。name 是参数的名称,在函数内部可以使用这个名称来引用传入的字符串。
#include <iostream>
#include <cstring>// 定义 BluetoothA2DPSink 类
class BluetoothA2DPSink {
public:// 成员函数声明void start(const char* name);
};// 成员函数定义
void BluetoothA2DPSink::start(const char* name) {std::cout << "Starting Bluetooth A2DP Sink with name: " << name << std::endl;// 这里可以添加更多的启动逻辑
}int main() {BluetoothA2DPSink sink;const char* deviceName = "MyBluetoothDevice";sink.start(deviceName);return 0;
}

class BluetoothA2DPSink : public BluetoothA2DPCommon

定义了一个名为 BluetoothA2DPSink 的类,并且采用了继承机制,继承自 BluetoothA2DPCommon 类。

class 关键字

  • class 是 C++ 中用于定义类的关键字。当使用 class 定义一个类时,会创建一个新的数据类型,这个类型可以包含数据成员(变量)和成员函数(方法)。

BluetoothA2DPSink

  • 这是定义的类的名称。在 C++ 里,类名遵循标识符的命名规则,通常采用大写字母开头的驼峰命名法,以提高代码的可读性。这里的 BluetoothA2DPSink 可能代表蓝牙 A2DP(Advanced Audio Distribution Profile,高级音频分发配置文件)的接收器类。

: 符号

  • 在类定义中,: 符号用于表示继承关系,它表明 BluetoothA2DPSink 类将继承自另一个类。
    public 访问说明符

public 是一种访问说明符,它决定了基类的成员在派生类中的访问权限。当使用 public 继承时:

基类的 public 成员在派生类中仍然是 public 的,这意味着派生类的对象和外部代码都可以访问这些成员。
基类的 protected 成员在派生类中仍然是 protected 的,派生类的成员函数可以访问这些成员,但外部代码无法访问。
基类的 private 成员在派生类中仍然是不可访问的,即使是派生类的成员函数也不能直接访问。

BluetoothA2DPCommon

  • 这是基类的名称。BluetoothA2DPSink 类将继承 BluetoothA2DPCommon 类的所有 public 和 protected 成员。BluetoothA2DPCommon 可能包含了蓝牙 A2DP 相关的通用功能和属性,BluetoothA2DPSink 类可以在此基础上添加或重写特定的功能,以实现蓝牙 A2DP 接收器的具体功能。

http://www.ppmy.cn/devtools/170600.html

相关文章

数据库—sql语法基础

目录 一.sql(Structured Query Language) 1.什么是sql语言&#xff1f; 2.特点 分支1&#xff1a;DDL 1.什么是DDL语言&#xff1f; 2.常用的语句 3.应用示例 1>.创建一个数据库 2>.修改字符集 3>.删除数据库 4.设计表 1>.字符 2>.日期 3>.整数…

C#通过API接口返回流式响应内容---SignalR方式

1、背景 在上两篇《C#通过API接口返回流式响应内容—分块编码方式》和《C#通过API接口返回流式响应内容—SSE方式》实现了流式响应的内容。 上面的这两个主要是通过HTTP的一些功能&#xff0c;除了这些之外&#xff0c;还有WebSocket的方式。C#中的WebSocket的有比较多的方案&…

ROM(只读存储器) 、SRAM(静态随机存储器) 和 Flash(闪存) 的详细解析

在嵌入式系统和其他计算机系统中&#xff0c;存储器是不可或缺的组成部分。不同类型的存储器各有其特点和应用场景。以下是 ROM&#xff08;只读存储器&#xff09;、SRAM&#xff08;静态随机存储器&#xff09; 和 Flash&#xff08;闪存&#xff09; 的详细解析。 1. ROM&am…

汽车免拆诊断案例 | 2024 款路虎发现运动版车无法正常识别智能钥匙

故障现象  一辆2024款路虎发现运动版车&#xff0c;搭载2.0 L发动机&#xff0c;累计行驶里程约为5 000 km。车主反映&#xff0c;使用遥控器无法解锁车门&#xff0c;随后使用机械钥匙打开车门&#xff0c;踩下制动踏板&#xff0c;按压起动按钮&#xff0c;仪表盘提示“将智…

如何设置家用威联通 NAS UPS 断电后自动关机并通知其他设备?

场景 &#x1f4dd;备注: 求轻喷, 求放过. &#x1f605; 我真的是个理线方面的白痴. 这已经是我的极限了. &#x1f602; 我的家庭实验室 Homelab 服务器集群配置如下. 上半部分之前已经介绍过了, 这里就不再赘述了. 今天重点介绍介绍 UPS 和 NAS 部分. 1台 UPS, 型号为 APC B…

windows下安装并使用node.js

一、下载Node.js 选择对应你系统的Node.js版本下载 Node.js官网下载地址 Node.js中文网下载地址??? 这里我选择的是Windows64位系统的Node.js20.18.0&#xff08;LTS长期支持版本&#xff09;版本的.msi安装包程序 官网下载&#xff1a; 中文网下载&#xff1a; 二、安…

【Uniapp】关于核心页面生命周期流程详解

UniApp 的页面生命周期继承自 Vue 组件生命周期&#xff0c;本文将解析核心页面生命周期流程&#xff0c;介绍对应的触发时机、作用并给出示例。 页面生命周期触发顺序 onLoad → onShow → onReady → onHide → onUnload 各个页面生命周期介绍 一、onLoad 触发时机&…

【MySQL】事务

目录 基本概念事务操作自动提交事务开启事务提交事务回滚事务代码示例 事务的特性 ACID事务的隔离级别读未提交 read uncommitted读已提交 read committed可重复读 repeatable read序列化&#xff08;串行&#xff09; serializable操作示例 基本概念 在 MySQL 中的事务&#…