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语言:有四种存储类别,分别是
auto
、static
、register
和extern
。
#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 的值,最后换行
-
std::cout
std::cout 是 C++ 标准库 iostream 中的一个对象,其类型为 std::ostream,它代表标准输出流,一般和控制台屏幕相关联。
std 是 C++ 标准库所使用的命名空间,借助作用域解析运算符 :: 能够访问该命名空间里的元素。 -
<< 运算符
<< 是输出流插入运算符,在 C++ 里被重载用于 std::ostream 对象。它的作用是把右侧的数据插入到左侧的输出流里。
此运算符能够进行链式调用,也就是可以在同一个语句中多次使用,从而把多个数据依次插入到输出流。 -
"Namespace var: "
这是一个字符串字面量,其类型为 const char[]。借助 << 运算符,这个字符串会被插入到 std::cout 输出流中。
-
MyNamespace::var
MyNamespace 属于用户自定义的命名空间,用于防止全局命名冲突。
var 是定义在 MyNamespace 命名空间中的变量。通过作用域解析运算符 ::,能够访问这个命名空间里的 var 变量。
这个变量的值会被插入到 std::cout 输出流中。 -
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 接收器的具体功能。