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

C++Cherno 学习笔记day15 [57]-[60] 静态数组、函数指针、lambda、using namespace std

b站Cherno的课[57]-[60]

  • 一、C++的静态数组(std::array)
  • 二、C++的函数指针
  • 三、C++的lambda
  • 四、为什么不使用using namespace std

一、C++的静态数组(std::array)

#include <iostream>
#include <array>

int main()
{
	std::array<int, 5> data;
	data[0] = 2;
	data[4] = 1;

	std::array<int, 5> dataOld;
	dataOld[0] = 0;

	std::cin.get();
}

二、C++的函数指针

原始函数指针(raw funtion pointer)
函数指针,是将一个函数赋值给一个变量的方法

函数指针是一种指向函数的指针变量,允许在运行时动态选择并调用函数。
它是实现回调机制、策略模式和动态行为扩展的基础工具。
尽管现代 C++ 提供了更安全的替代方案(如 std::function 和 Lambda 表达式),理解函数指针仍对底层编程和兼容 C 代码至关重要。

在这里插入图片描述

可以用auto/ typedef/ using来使用函数指针

#include <iostream>

void HelloWorld()
{
	std::cout << "Hello World!" << std::endl;
}

int main()
{
	HelloWorld();

	std::cin.get();
}

在这里插入图片描述

#include <iostream>

void HelloWorld()
{
	std::cout << "Hello World!" << std::endl;
}

int main()
{
// 使用auto
	auto function = HelloWorld;

	function();
	function();

	std::cin.get();
}

在这里插入图片描述

#include <iostream>

void HelloWorld(int a)
{
	std::cout << "Hello World! Value:" << a << std::endl;
}

int main()
{
	/*void(*function)();
	auto function = HelloWorld;*/
	// 使用typedef
	typedef void(*HelloWorldFunction)(int);
	HelloWorldFunction function = HelloWorld;

	function(8);

	std::cin.get();
}

在这里插入图片描述

#include <iostream>
#include <vector>

void PrintValue(int value)
{
	std::cout << "Value:" << value << std::endl;
}
void ForEach(const std::vector<int>& values, void(*func)(int))
{
	for (int value : values)
		func(value);
}
	
int main()
{
	std::vector<int> values = { 1, 5, 4, 2, 3 };
	// ForEach(values, PrintValue);
	// []叫做 捕获方式,如何传入传出参数
	ForEach(values, [](int value) { std::cout << "Value:" << value << std::endl; });

	std::cin.get();
}

在这里插入图片描述
在这里插入图片描述
优先使用 std::function 或 Lambda 以实现更安全的回调。

仅在需要兼容 C 或极致性能时使用函数指针。

避免强制转换函数指针类型(除非明确知晓风险)。

三、C++的lambda

本质是一种匿名函数的方式
像快速的一次性函数,展示运行的代码
只要有一个函数指针,就可以在C++里使用lambda 捕获上下文变量

lambda是我们不需要通过函数定义,就可以定义一个函数的方法
用法:在设置函数指针指向函数的任何地方,都可以将它设置为lambda
查看lambda捕获值

// 核心结构
[捕获列表] (参数列表) mutable(可选) 异常属性(可选) -> 返回类型(可选) {
    // 函数体
}

auto sum = [](int a, int b) -> int { 
    return a + b; 
};
cout << sum(3, 5); // 输出 8

通过值传递= 或 引用传递&捕获变量

非捕获lambda可以隐式转换为函数指针,而有捕获lambda不可以。
在这里插入图片描述
mutable修饰符
constexpr修饰符

#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>

void ForEach(const std::vector<int>& values, const std::function<void(int)>& func)
{
	for (int value : values)
		func(value);
}
	
int main()
{
	std::vector<int> values = { 1, 5, 4, 2, 3 };
	// 返回一个迭代器
	auto it = std::find_if(values.begin(), values.end(), [](int value) { return value > 3; });
	std::cout << *it << std::endl;

	int a = 5;
	auto lambda = [=](int value) { std::cout << "Value:" << value << " " << a << std::endl; };
	
	ForEach(values, lambda);
	std::cin.get();
}

在这里插入图片描述

在这里插入图片描述
总结

Lambda 表达式是现代 C++ 中提升代码表达力的利器,尤其适合以下场景:

短小的一次性逻辑(如 STL 算法中的谓词)。

需要捕获上下文的闭包(如异步回调、状态保存)。

替代传统的函数对象(减少样板代码)。

牢记原则:

慎用引用捕获,避免悬空引用。

优先使用显式捕获列表。

在性能关键路径考虑内联优化可能性。

四、为什么不使用using namespace std

using namespace 命名空间

// ctrl+H 替换

帕斯卡命名法
(每个单词首字母大写,中间不能有空格或下划线等,
和驼峰的区别是,驼峰首字母小写)

而c++(标准库)则喜欢这种snake case格式
蛇形命名法:小写单词,中间用下划线连接)

#if 0
// 注释
#endif

使用using namespace std:在足够小的作用域去使用

不要在头文件使用!!!

http://www.dtcms.com/a/109416.html

相关文章:

  • DataX实战教程
  • 【性能优化点滴】odygrd/quill在编译期做了哪些优化
  • AI辅助开发插件
  • PMP中,资源平衡和资源平滑的区别
  • CentOS Linux升级内核kernel方法
  • JSON 对象
  • 【C++11】lambda表达式 可变参数模板 移动构造与移动赋值 包装器
  • 厄瓜多尔主流收单方式:Pago Efectivo支付
  • 【Linux】进程信号的捕捉处理
  • 镜片防雾性能测试仪在自动驾驶与无人机领域的创新应用
  • 虚拟试衣间微信小程序解决方案
  • CSRF跨站请求伪造——入门篇【DVWA靶场low级别writeup】
  • Android学习总结之handler源码级
  • Reactive编程入门:Project Reactor 深度指南
  • 网络:华为数通HCIA学习:IP路由基础
  • vuex自存例子
  • linux_sysctl_fs_file_nr监控项
  • LeetCode刷题 -- 48. 旋转图像
  • 2025身份证号码前六位地区代码对照表
  • Android A/B 分区 OTA 如何查看升级的 img 分区
  • zk基础—4.zk实现分布式功能二
  • Ansible:playbook的高级用法
  • Unity中 JobSystem使用整理
  • LeetCode 接雨水问题详解 - 动态规划解法
  • CentOS 7安装hyperscan
  • LLM驱动的智能体:基于GPT的对话智能体开发指南
  • 如何学习一门编程语言
  • flux绘画模型介绍
  • Java学习总结-字符集
  • 项目之Boost搜索引擎