C++初阶(三)---C++入门(下)

目录
一、内联函数
1.内联函数的定义与底层机制
0x01.内联函数的定义
0x02.内联函数的底层机制
2.内联函数的优缺点
优点:
缺点:
3.内联函数的使用建议
4.内联函数的注意事项
二、auto关键字(C++11)
1.代码示例
2.auto使用场景
0x01.迭代器遍历
0x02. Lambda表达式
0x03.范围for循环
0x04.复杂的类型推导
0x05.与decltype结合使用
3.使用auto关键字注意事项
0x01. 初始化是必需的
0x02.auto 不能作为函数的参数
0x03.auto 不能直接用来声明数组
0x04.避免过度使用
0x05.注意const和volatile的保留
0x06.小心引用和指针的推导
0x07.初始化表达式中的类型转换
0x08.与模板结合使用时的小心
4.auto关键字总结
三、基于范围的for循环(C++11)
1.范围for的语法
2. 范围for的使用条件
3.底层实现原理
4.细节和注意事项
5.范围for总结
四、指针空值 nullptr(C++11)
1.nullptr的引入背景
2.nullptr与NULL的区别
3.nullptr的使用场景
0x01.初始化指针
0x02.比较指针
0x03.函数参数和返回值
0x05.避免类型混淆
4.注意事项
5.总结
一、内联函数
在C++编程中,内联函数(Inline Function)是一种强大的优化手段,它通过减少函数调用的开销来提高程序的执行效率。这里将深入探讨C++内联函数的底层机制、优缺点以及最佳实践,并插入一些示例代码以帮助你更好地理解。
1.内联函数的定义与底层机制
内联函数是C++语言中的一种特性,它允许程序员请求编译器将函数的定义(实现)直接插入到所有调用该函数的地方,而不是创建一个新的函数调用栈帧。这意味着当函数被调用时,它的代码会直接嵌入到调用处,而不是跳转到函数定义处执行。
0x01.内联函数的定义
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。
正常函数调用

内联函数调用
从这里可以看到内联函数并没有建立栈帧,减少建立栈帧的开销从而提高程序的效率。
0x02.内联函数的底层机制
-
内联请求与编译器决策:
- 当程序员使用
inline关键字声明一个函数时,他们实际上是在向编译器提出一个内联请求。 - 编译器会根据函数的复杂性、大小、调用频率以及编译器的优化策略来决定是否接受这个请求。
- 如果编译器决定不接受内联请求,该函数将被视为普通函数进行处理。
- 当程序员使用
-
内联函数的展开:
- 当编译器接受内联请求时,它会在每个调用该函数的地方插入该函数的代码。
- 这意味着每次函数调用都会被替换为函数体的实际代码。
- 内联函数的展开是在编译时进行的,而不是在运行时。
-
内联函数的局限性:
- 内联函数不能包含复杂的控制结构(如循环和递归),否则编译器可能会拒绝内联请求。
- 内联函数通常用于小型、频繁调用的函数,以避免代码膨胀和编译时间增加。
2.内联函数的优缺点
优点:
- 提高执行效率:内联函数避免了函数调用的开销,包括堆栈帧分配、参数传递和返回操作。
- 改善代码可读性:对于小型、简单的函数,内联函数可以使代码更易于阅读和理解。
缺点:
- 代码膨胀:内联函数会导致调用处的代码膨胀,因为每次调用都会插入函数体的代码。
- 编译时间增加:编译器需要处理更多的代码,这可能会增加编译时间。
- 调试困难:由于代码被展开到调用点,调试时可能难以跟踪到原始的函数定义。
3.内联函数的使用建议
- 选择小型函数:仅内联小型函数,因为大型函数会产生代码膨胀,影响程序的执行效率。
- 避免递归函数:内联递归函数会导致堆栈溢出或编译器拒绝内联。
- 使用
inline关键字:虽然inline只是一个建议,但使用它可以增加编译器内联函数的可能性。 - 剖析代码:使用剖析工具来识别哪些函数受益于内联。
- 函数定义放在头文件中:为了确保编译器在编译每个调用该函数的源文件时都能看到函数定义,通常将内联函数的定义放在头文件中。否则内联函数会认为在调用的地方展开,导致不生成地址。
4.内联函数的注意事项
inline关键字只是建议:inline关键字只是向编译器提出内联请求的建议,编译器可以选择是否接受这个请求。- 避免过度使用:过度使用内联函数可能会导致代码膨胀和编译时间增加,从而降低程序的性能。
- 考虑代码的可移植性:在某些情况下,内联函数可能会导致代码在不同编译器或平台上的行为不一致。因此,在编写跨平台代码时,应谨慎使用内联函数。
二、auto关键字(C++11)
在C++11标准中,auto关键字被赋予了新的使命——类型推导。在此之前,C++中的auto主要用于声明变量的存储期为自动,即局部变量。然而,从C++11开始,auto关键字主要用于根据变量的初始化表达式自动推导其类型。
1.代码示例
int main()
{auto i = 42; // i的类型将被推断为int auto ch = 'a';// ch的类型将被推断为charauto d = 3.14; // y的类型将被推断为double auto z = "hello"; // z的类型将被推断为const char*cout << typeid(i).name() << endl; // icout << typeid(ch).name() << endl; // ccout << typeid(d).name() << endl; // dcout << typeid(z).name() << endl; // Preturn 0;
}
运行结果如下 :

2.auto使用场景
0x01.迭代器遍历
在使用STL容器(如std::vector、std::list等)时,auto可以自动推导迭代器的类型,避免显式指定迭代器类型的繁琐。
#include <iostream>
#include <vector> int main()
{ std::vector<int> vec = {1, 2, 3, 4, 5}; for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } std::cout << std::endl; return 0;
}
0x02. Lambda表达式
#include <iostream>
#include <algorithm>
#include <vector> int main()
{ std::vector<int> vec = {1, 2, 3, 4, 5}; auto print = [](int x) { std::cout << x << " "; }; std::for_each(vec.begin(), vec.end(), print); std::cout << std::endl; return 0;
}
0x03.范围for循环
范围for循环是C++11引入的一种简化数组或容器遍历的语法,auto可以自动推导集合元素的类型。
#include <iostream>
#include <vector> int main()
{ std::vector<int> vec = {1, 2, 3, 4, 5}; for (auto num : vec) { std::cout << num << std::endl; } return 0;
}
0x04.复杂的类型推导
在处理复杂类型(如模板实例化后的类型、类型别名等)时,auto可以简化类型声明。
#include <iostream>
#include <map>
#include <string> int main()
{ std::map<std::string, int> myMap = {{"apple", 1}, {"banana", 2}}; for (const auto& pair : myMap) { std::cout << pair.first << ": " << pair.second << std::endl; } // 使用auto简化类型推导,避免显式指定std::pair<const std::string, int> auto it = myMap.find("apple"); if (it != myMap.end()) { std::cout << "Found apple with value: " << it->second << std::endl; } return 0;
}
0x05.与decltype结合使用
在某些情况下,你可能需要保留变量的const或volatile属性,或者需要推导出一个与现有变量相同类型的新变量。这时可以使用decltype与auto结合。
#include <iostream> int main()
{ int x = 10; decltype(auto) y = x; // y的类型是int,与x相同 const int z = 20; decltype(auto) w = z; // w的类型是const int,保留了z的const属性 std::cout << "y: " << y << ", w: " << w << std::endl; // 注意:不能修改w的值,因为它是const int类型 // w = 30; // 错误:不能给常量赋值 return 0;
}
3.使用auto关键字注意事项
0x01. 初始化是必需的
auto变量必须在使用前进行初始化,因为auto是通过初始化表达式来推导类型的。未初始化的auto变量将导致编译错误。
auto x; // 错误:auto变量必须初始化
auto y = 10; // 正确:y的类型被推导为int
0x02.auto 不能作为函数的参数
#include<iostream>
using namespace std;
// 此处代码编译失败,auto不能作为形参类型,因为编译器无法对a的实际类型进行推导
void TestAuto(auto a)
{}
0x03.auto 不能直接用来声明数组
#include<iostream>
using namespace std;
int main()
{int a[] = { 1,2,3 };auto b[] = { 4,5,6 };return 0;
}
0x04.避免过度使用
虽然auto可以简化代码,但过度使用可能会降低代码的可读性。特别是在类型信息对于理解代码逻辑很重要时,显式指定类型可能更清晰。
// 不推荐:过度使用auto可能导致代码难以阅读
auto a = 5;
auto b = "Hello";
auto c = std::make_pair(a, b); // 推荐:在类型明确且重要时,显式指定类型
int a = 5;
std::string b = "Hello";
std::pair<int, std::string> c = std::make_pair(a, b);
0x05.注意const和volatile的保留
auto在推导类型时不会保留顶层const和volatile限定符。如果你需要保留这些限定符,可以使用decltype(auto)。
const int x = 10;
auto y = x; // y的类型是int,丢失了const限定符
decltype(auto) z = x; // z的类型是const int,保留了const限定符
0x06.小心引用和指针的推导
当使用auto推导引用或指针类型时,要确保初始化表达式也是引用或指针,以避免意外的类型推导。
int x = 10;
int& ref = x;
auto a = ref; // a的类型是int,不是int&
auto& b = ref; // b的类型是int&,正确推导为引用 int* ptr = &x;
auto c = ptr; // c的类型是int*,不是int**
auto* d = ptr; // d的类型是int*,正确推导为指针
0x07.初始化表达式中的类型转换
如果初始化表达式涉及类型转换,auto将推导转换后的类型。
double d = 3.14;
auto e = static_cast<int>(d); // e的类型是int,因为进行了静态类型转换
0x08.与模板结合使用时的小心
在模板编程中,auto可以用于类型推导,但要小心模板参数的类型推导和auto的交互。
template<typename T>
void func(T x)
{ auto y = x; // y的类型与x相同
} int main()
{ func(42); // T被推导为int,y的类型也是int func(3.14); // T被推导为double,y的类型也是double
}
4.auto关键字总结
auto关键字在C++中主要用于类型推导,特别是在处理STL容器、Lambda表达式、范围for循环以及复杂类型时,auto可以大大简化代码的编写。然而,过度使用auto可能会降低代码的可读性,特别是在类型信息对于理解代码逻辑至关重要时。因此,在使用auto时,需要权衡代码的简洁性和可读性。
三、基于范围的for循环(C++11)
在C++11中,范围for循环(Range-based for loop)是一项重要的新特性,它提供了一种简洁且高效的方法来遍历容器或数组中的元素。下面将深入探讨这一特性,通过代码和图片详细解释其工作原理和底层实现。
1.范围for的语法
在C++98中如果要遍历一个数组,可以按照以下方式进行
void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };for (int i = 0; i < sizeof(array) / sizeof(array[0]); ++i){array[i] *= 2;cout << array[i] << " ";}cout<<endl;for (int* p = array; p < array + sizeof(array) / sizeof(array[0]); ++p){cout << *p <<" ";}cout << endl;
}int main()
{TestFor();return 0;
}
对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因 此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范 围内用于迭代的变量,第二部分则表示被迭代的范围。
void TestFor()
{int array[] = { 1, 2, 3, 4, 5 };for (auto& e : array)e *= 2;for (auto e : array)cout << e << " ";
}int main()
{TestFor();return 0;
}
注意:与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。
2. 范围for的使用条件
对于数组而言,就是数组中第一个元素和最后一个元素的范围;
对于类而言,应该提供 begin和end的方法,begin和end就是for循环迭代的范围。
注意:以下代码就有问题,因为for的范围不确定。
void TestFor(int array[]){for(auto& e : array)cout<< e <<endl;}
这里传递过来的是数组的首元素地址,并不是数组,它会不知道范围是多少,所以会 报错。
不仅如此,并且迭代的对象要实现 ++ 和 == 的操作。(关于迭代器这个问题,以后会讲,现在提一下,没办法讲清楚,现在uu了解一下就可以了)
3.底层实现原理
// 原始的范围for循环
for (int x : vec)
{ std::cout << x << std::endl;
} // 编译器可能生成的等价代码
auto it = vec.begin();
auto end = vec.end();
while (it != end)
{ int x = *it; std::cout << x << std::endl; ++it;
}
4.细节和注意事项
-
类型推导:范围for循环中的变量类型(如上面的
int x)是通过类型推导(type deduction)来确定的。编译器会根据容器或数组中的元素类型来推导变量的类型。 -
常量性:如果希望遍历过程中不修改容器中的元素,可以将变量声明为常量引用类型,例如
const auto& x : vec。 -
范围for循环的限制:范围for循环不能用于修改容器的大小(如添加或删除元素),因为它不提供对迭代器的直接访问。如果需要修改容器,应使用传统的基于迭代器的循环。
-
数组和容器的兼容性:范围for循环不仅适用于标准容器(如
std::vector、std::list等),还适用于原生数组和C风格的数组。 -
性能考虑:对于简单的容器和数组,范围for循环的性能与基于迭代器的循环相当。然而,在某些复杂情况下(如需要频繁修改迭代器或进行复杂的条件判断),手动管理迭代器可能会提供更精细的控制和可能的性能优化。
5.范围for总结
总的来说,范围for循环是C++11引入的一个非常有用的特性,它简化了容器和数组的遍历操作,并提高了代码的可读性和可维护性。尽管它在底层是通过编译器转换为基于迭代器的循环来实现的,但这一转换对用户来说是透明的,使得用户能够专注于更高层次的逻辑和算法实现。
四、指针空值 nullptr(C++11)
在C++编程中,指针是一个非常重要的概念,它允许我们直接操作内存地址。然而,指针的使用也伴随着一定的风险,特别是当指针未初始化或指向无效内存时。为了解决这个问题,C++11引入了一个新的关键字nullptr,以替代传统的空指针常量NULL或整数0。接下来将深入探讨nullptr的底层机制、使用场景以及它如何帮助提高代码的安全性和可读性。
1.nullptr的引入背景
在C++11之前,我们通常使用NULL或0来表示空指针。然而,这两种方式都存在一些问题:
NULL通常被定义为((void*)0),这是一个类型转换表达式,而不是一个真正的关键字。这可能导致在某些上下文中出现类型不匹配的问题。- 使用
0作为空指针常量虽然简单,但它与整数字面量0没有区别,这可能导致类型混淆和潜在的错误。
NULL实际是一个宏,在传统的C头文件(stddef.h)中,可以看到如下代码:
#ifndef NULL#ifdef __cplusplus#define NULL 0#else#define NULL ((void *)0)#endif#endif
可以看到,NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。不论采取何 种定义,在使用空值的指针时,都不可避免的会遇到一些麻烦,比如:
void f(int){cout<<"f(int)"<<endl;}void f(int*){cout<<"f(int*)"<<endl;}int main(){f(0);f(NULL);f((int*)NULL);return 0;}
该程序的本意是想通过 Func(NULL) 调用指针版本的 Func(int*) 函数,
但是由于 NULL 被定义成0,这么一来就不符合程序的初衷了。
在 C++98 中,字面常量 0 既可以是一个整型数字,也可以是无类型的指针 (void*) 常量,
但是编译器默认情况下会将其看成一个整型常量,
如果要将其按照指针方式来使用,必须对其进行强制类型转换 (void*)0 。
为了解决这些问题,C++11引入了nullptr,它是一个类型安全的空指针常量。
2.nullptr与NULL的区别
NULL是一个宏定义,而不是关键字。它在C++中通常被定义为0或((void*)0),这可能导致类型不匹配的问题。nullptr是一个关键字,它的类型是nullptr_t,是一个专门用于表示空指针的类型,与传统的空指针常量NULL(通常被定义为((void*)0)或0)不同,nullptr只能被隐式转换为指针类型,而不能被转换为整数或其他非指针类型。这种类型安全性有助于减少类型混淆和潜在的错误。具有类型安全性。
3.nullptr的使用场景
0x01.初始化指针
使用nullptr来初始化指针是一个好习惯,它可以帮助我们避免未初始化指针导致的未定义行为。
int* ptr = nullptr;
0x02.比较指针
使用nullptr来比较指针是否为空,可以提高代码的可读性和安全性。
if (ptr == nullptr)
{ // ptr is null
}
0x03.函数参数和返回值
在函数参数和返回值中使用nullptr可以明确表示一个指针参数或返回值是可选的或可以为空。
void* allocateMemory(size_t size)
{ if (size == 0) { return nullptr; } // Allocate memory and return pointer
}
0x05.避免类型混淆
使用nullptr可以避免将整数0误用作指针,从而减少类型混淆和潜在的错误。
int* ptr = nullptr; // Clear and safe
// int* ptr = 0; // Less clear and potentially error-prone
4.注意事项
- 避免类型混淆:不要将
nullptr与整数0混用,以避免类型混淆和潜在的错误。 - 初始化指针:始终在声明指针时初始化它,即使你暂时不知道它将指向什么。使用
nullptr是一个好选择。 - 检查空指针:在删除指针或访问指针所指向的内存之前,始终检查指针是否为空。
- 避免悬挂指针:在删除动态分配的内存后,将指针设置为
nullptr以避免悬挂指针的问题。 - 模板中的使用:当将
nullptr应用于模板时,模板会将其作为一个普通的类型来进行推导,并不会将其视为T*指针。因此,在模板函数中处理空指针时需要注意这一点。
5.总结
nullptr是C++11引入的一个非常重要的特性,它提高了指针操作的安全性和可读性。通过使用nullptr,我们可以避免类型混淆、减少潜在的错误,并编写更清晰、更健壮的代码。因此,在C++11及更高版本中,我们应该优先使用nullptr来替代传统的空指针常量NULL或整数0。
本篇博客到此结束,如有错误之处,望各位指正~
相关文章:
C++初阶(三)---C++入门(下)
目录 一、内联函数 1.内联函数的定义与底层机制 0x01.内联函数的定义 0x02.内联函数的底层机制 2.内联函数的优缺点 优点: 缺点: 3.内联函数的使用建议 4.内联函数的注意事项 二、auto关键字(C11) 1.代码示例 2.auto使…...
Linux--多路转接之epoll
上一篇:Linux–多路转接之select epoll epoll 是 Linux 下多路复用 I/O 接口 select/poll 的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统 CPU 利用率。它是 Linux 下多路复用 API 的一个选择,相比 select 和 poll,…...
自动化工具Nico,从零开始干掉Appium,移动端自动化测试框架实现
这篇将用较短的篇幅给大家介绍我是如何实现iOS和Android的inspector(元素审查工具)的。 实现原理 为了更方便的显示UI界面,且更容易制作,我选择了使用web端来承载整个元素树展示。同时我选用Flask一次性梭哈前后端(因…...
Fast CRC32
链接: Fast CRC32 Error Checking Real life data tends to get corrupted because machines (and humans) are never as reliable as we wish for. One efficient way is make sure your data wasnt unintendedly modifiied is to generate some kind of hash. T…...
生成一个带有二维数据和对应标签的螺旋形数据集(非线性可分数据集)的代码解析
def create_dataset():np.random.seed(1)m 400 # 数据量N int(m/2) # 每个标签的实例数D 2 # 数据维度X np.zeros((m,D)) # 数据矩阵Y np.zeros((m,1), dtypeuint8) # 标签维度a 4 for j in range(2):ix range(N*j,N*(j1))t np.linspace(j*3.12,(j1)*3.12,N) np.rando…...
PHP unset() 函数的作用
PHP 中的 unset() 函数用于销毁指定的变量。具体来说,它会解除变量名与其数据之间的关联,从而释放该变量所占用的内存。不过需要注意的是,unset() 并不是删除变量的内容,而是取消对变量名的引用。如果变量是数组中的某个元素或者对…...
长篇故事可视化方法Story-Adapter:能够生成更高质量、更具细腻交互的故事图像,确保每一帧都能准确地传达故事情节。
今天给大家介绍一个最新的长篇故事可视化方法Story-Adapter,它的工作原理可以想象成一个画家在创作一幅长画卷。首先,画家根据故事的文本提示画出初步的图像。这些图像就像是画卷的草图。接下来,画家会不断回顾这些草图,逐步添加细…...
C++基础面试题 | 什么是C++中的运算符重载?
文章目录 回答重点:示例: 运算符重载的基本规则和注意事项: 回答重点: C的运算符重载是指可以为自定义类型(如类或结构体)定义运算符的行为,使其像内置类型一样使用运算符。通过重载运算符&…...
深入 IDEA 字节码世界:如何轻松查看 .class 文件?
前言: 作为一名 Java 开发者,理解字节码对于优化程序性能、调试错误以及深入了解 JVM 运行机制非常重要。IntelliJ IDEA 作为最流行的开发工具之一,为开发者提供了查看 .class 文件字节码的功能。在本文中,我将带你一步步探索如何…...
NodeJS 利用代码生成工具编写GRPC
生成的 gRPC 代码优点 自动化和效率: 减少手动编码:生成代码自动处理了消息的序列化和反序列化、服务接口的定义等,减少了手动编码的工作量。一致性:生成的代码确保了客户端和服务器之间的一致性,避免了手动编码可能带来的错误。跨语言支持: 多语言兼容:gRPC 支持多种编…...
uni-app基础语法(一)
我们今天的学习目标 基础语法1. 创建新页面2.pages配置页面3.tabbar配置4.condition 启动模式配置 基础语法 1. 创建新页面 2.pages配置页面 属性类型默认值描述pathString配置页面路径styleObject配置页面窗口表现,配置项参考pageStyle 我们来通过style修改页面的…...
Linux:进程控制(三)——进程程序替换
目录 一、概念 二、使用 1.单进程程序替换 2.多进程程序替换 3.exec接口 4.execle 一、概念 背景 当前进程在运行的时候,所执行的代码来自于自己的源文件。使用fork创建子进程后,子进程执行的程序中代码内容和父进程是相同的,如果子进…...
LeetCode279:完全平方数
题目链接:279. 完全平方数 - 力扣(LeetCode) 代码如下 class Solution { public:int numSquares(int n) {vector<int> dp(n 1, INT_MAX);dp[0] 0;for(int i 1; i * i < n; i){for(int j i * i; j < n; j){dp[j] min(dp[j …...
python爬虫--某动漫信息采集
python爬虫--tx动漫 一、采集主页信息二、采集详情页信息三、代码供参考一、采集主页信息 略。 二、采集详情页信息 如上图所示,使用xpath提取详情页的标题、作者、评分、人气、评论人数等数据。 三、代码供参考 import csv import time import random import requests fr…...
使用Rollup.js快速开始构建一个前端项目
Rollup 是一个用于 JavaScript 项目的模块打包器,它将小块代码编译成更大、更复杂的代码,例如库或应用程序。Rollup 对代码模块使用 ES6 模块标准,它支持 Tree-shaking(摇树优化),可以剔除那些实际上没有被…...
10.15学习
1.程序开发的步骤 定义程序的目标→设计程序→编写代码(需要选择语言,一种语言对应一种编译器)→编译→运行程序→测试和调试程序→维护和修改程序 2.ANSI/ISO C标准 1989年ANSI批准通过,1990年ISO批准通过,因此被称…...
mongodb-7.0.14分片副本集超详细部署
mongodb介绍: 是最常用的nosql数据库,在数据库排名中已经上升到了前六。这篇文章介绍如何搭建高可用的mongodb(分片副本)集群。 环境准备 系统系统 BC 21.10 三台服务器:192.168.123.247/248/249 安装包:…...
C++运算出现整型溢出
考虑如下代码: int aINT_MAX; int b 1; long c ab; 这段代码没有编过! 原因是a和b都是int型,相加之后会溢出。 请记住,c语言没有赋值,只有表达式,右侧会存在一个暂存的int保存ab的值,而明…...
LeetCode岛屿数量
题目描述 给你一个由 1(陆地)和 0(水)组成的的二维网格,请你计算网格中岛屿的数量。 岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。 此外,你可以假设该网…...
Karmada核心概念
以下内容为翻译,原文地址 Karmada 是什么? | karmada 一、Karmada核心概念 一)什么是Karmada 1、Karmada:开放,多云,多集群Kubernetes业务流程 Karmada (Kubernetes Armada)是一个Kubernetes管理系统&…...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件
今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...
在 Nginx Stream 层“改写”MQTT ngx_stream_mqtt_filter_module
1、为什么要修改 CONNECT 报文? 多租户隔离:自动为接入设备追加租户前缀,后端按 ClientID 拆分队列。零代码鉴权:将入站用户名替换为 OAuth Access-Token,后端 Broker 统一校验。灰度发布:根据 IP/地理位写…...
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
k8s业务程序联调工具-KtConnect
概述 原理 工具作用是建立了一个从本地到集群的单向VPN,根据VPN原理,打通两个内网必然需要借助一个公共中继节点,ktconnect工具巧妙的利用k8s原生的portforward能力,简化了建立连接的过程,apiserver间接起到了中继节…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
