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

C++与C的基本不同

文章目录

      • 变量定义规则
        • 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.kler.cn/a/591256.html

相关文章:

  • 2025年Go语言面试中常见的50道面试题,涵盖基础语法、并发编程、数据结构、错误处理
  • K8s的部署
  • 【Linux编程】IPC之消息队列从踩坑到实战:核心原理、实战案例与C++封装详解(含完整代码)
  • Leetcode 刷题笔记1 图论part01
  • Java 大视界 -- Java 大数据在智能家居设备联动与场景自动化中的应用(140)
  • 【VS小知识】VS如何保存UTF8
  • python-列表的操作以及切片
  • Groove 清除环境变量,以防应用程序因为环境变量设置了错误的 Qt 插件路径而启动失败
  • OpenHarmony子系统开发 - 电话服务
  • 整体二分算法讲解及例题
  • 自然语言处理|Top-K 采样如何解锁文本生成的多样性?
  • php开发转go的学习计划及课程资料信息
  • 速通大厂测开
  • 爱普生 SG-8200CG可编程晶振在智能手表的应用
  • 从零构建大语言模型全栈开发指南:第一部分:数学与理论基础-1.1.1语言模型演进:从N-gram到Transformer
  • 【从零开始学习计算机科学】软件测试(六)软件开发中的软件测试过程 与 验收测试
  • 本地知识库RAG总结
  • 1.排序算法(学习自用)
  • 每日一题--计算机网络
  • deepseek连续对话与API调用机制