C++初阶1

news2024/11/18 18:34:30

目录

介绍:

一,命名空间

1-1,命名空间的定义

1-2,命名空间的使用

1-3,C++标准官方命名空间

二,缺省参数

2.1,缺省参数分类

三,函数重载

四,引用

4-1,引用的使用

4-2,常引用

4-3,引用的使用场景

4-4,引用的效率分析以及与指针的关系

五,内联函数


介绍:

        本文开始从C到C++的过度,C++是C的进阶版,在C中,本身存在很多不足和不安全性,C++是进一步弥补了C的不足并提供了更高级的用法,不仅如此,大部分C++编译器还支持C语言的用法,但C语言不支持C++的用法,这样一来C++即包括了C语言的优点,还拥有了自己的独特优势,在后面的写入中笔者会将两者语言掺和起来,以方便学者们理解。在平常区分C语言和C++我们可直接根据两者的后缀名,C语言的基础文件都是以".c"为后缀,而C++的基础文件都以".cpp"为后缀。

一,命名空间

        在C/C++中,变量、函数和以后我们要学习的类都是大量存在的,但如果变量或函数名重复了又当会如何?C语言本身是无法解决此问题,一旦重复系统将报错,而C++将会使用命名空间解决此问题。在C++中专门有命名空间关键字namespace

#include <stdio.h>
int rand = 0;
int main() {
    //系统将会报错,因为在C语言库文件中就已定义了rand函数,不可再次进行定义
    fprintf(stdout, "rand: %d", rand);
    return 0;
}

1-1,命名空间的定义

        定义:namespace 命名空间的名字,然后下面接一堆{}即可,{}中即为空间中的成员。

        解析:命名空间相当于定义了一个新的作用域,该空间中的所有内容都局限于该空间中,不被外面影响,因此,它完美的解决了名称相同的问题。当要使用此空间中的成员时,需要用到域的作用限定符,即"::"。使用方法:命名空间名字::成员。要注意的是,使用结构体成员时:struct 命名空间的名字::结构体名称,并且,命名空间还可以嵌套使用。

#include <stdio.h>
//str是命名空间的名字
namespace str {
    //命名空间里可以是任意类型
    int rand = 0;
    int Add(int a, int b) {
        return a + b;
    }
    struct student {
        int age;
        int height;
    };

    //命名空间的嵌套使用
    namespace bitee {
        int a = 6;
    }
}
int main() {
    //整型类型的运用,其它类型同理
    fprintf(stdout, "rand = %d\n", str::rand);
    //结构体类型的运用
    struct str::student a1;
    a1.age = 2;
    fprintf(stdout, "结构体的运用: %d\n", a1.age);
    //函数的运用
    fprintf(stdout, "Add(1, 2) = %d\n", str::Add(1, 2));
    //命名空间的嵌套使用
    fprintf(stdout, "嵌套使用: %d\n", str::bitee::a);
    return 0;
}

        注意:在这里要说明的是C++允许同一个工程中存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中,但同一个文件下不允许存在相同名称的命名空间,因为这样运用的话当两者同时定义相同的变量名时编译器将"不知所措"。例如:一个工程中的test.h和test.cpp文件中都有namespace std,运行时两个的std会被合成一个。


1-2,命名空间的使用

        命名空间的使用有三种方法,其中,以上运用域的限定符"::"只是其中最普通的一种。接下来我们观察以下两种。

        1,使用using将命名空间中某个成员引入

#include <stdio.h>
//str是命名空间的名字
namespace str {
    //命名空间里可以是任意类型
    int rand = 0;
    int Add(int a, int b) {
        return a + b;
    }
    struct student {
        int age;
        int height;
    };
    namespace bitee {
        int a = 6;
    }
}

//使用using后系统直接默认使用,这时不用域的限定符即可表示使用里面的数据
using str::rand;
using str::bitee::a;
int main() {
    fprintf(stdout, "%d %d\n", rand, a);
    return 0;
}

        2,使用using namespace 命名空间名称 将其全部引入

//将命名空间全部导入系统,这时会默认使用str
using namespace str;
int main() {
    fprintf(stdout, "%d %d\n", rand, bitee::a);
    return 0;
}


1-3,C++标准官方命名空间

        之前就说过,C++是C的进阶,C++高级功能的其中之一就体现在C++有自己的官方命名空间std,C++将标准库的定义实现都放到这个命名空间中,而std的使用通常与C++的里<iostream>标准库文件密不可分,两者一般是配合使用。

C++常用标准函数:

        1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件 以及按命名空间使用方法使用std。

        2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。

        3. <<是流插入运算符,>>是流提取运算符。

        4. 使用C++输入输出更方便,不需要像C中printf/scanf输入输出时那样,需要手动控制格式。 C++的标准输入输出可以自动识别变量类型。

注意:关于cout和cin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等等。因为C++兼容C语言的用法,这些又用得不是很多,我们这里就不展开学习了。后续如果有需要,笔者会详细跟大家介绍。

//引用头文件

#include <iostream>
//标准命名空间的定义
using namespace std;
int main() {
    int a = 5;
    float b = 3.5;
    char str[] = "abcdf";
    cout << "a = " << a << endl << "b = " << b << endl << "str = " << str << endl;
    return 0;
}


二,缺省参数

        缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。

#include <iostream>
using namespace std;
void Fun(int a = 5) {
    cout << "a = " << a << endl;
}
int main() {
    Fun(); //a = 5,采用该函数的缺省值5
    Fun(10);//a = 10,有了实参就用该实参的值10
    return 0;
}

2.1,缺省参数分类

1,全缺省参数

        全缺省参数是函数参数中全部指定缺省值,如下:

void Func(int a = 10, int b = 20, int c = 30) {
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

2,半缺省参数

        半缺省参数是函数参数中部分指定缺省值,但这里有两条注意事项:1,半缺省参数必须从右往左依次来给出,不能间隔着给。2. 缺省参数不能在函数声明和定义中同时出现如下:

//参数从右到左必须依次给出

void Func(int a, int b = 20, int c = 30) {
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

//错误运用

void Func(int a = 10, int b, int c = 30) {
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}

//缺省参数的使用注意

#include <iostream>
using namespace std;
//函数定义和声明中不能同时给缺省值,因为编译器无法确定用哪个缺省值
//缺省值最好在声明中指定,因为我们运用函数一般都是先声明完之后在定义,如果系统先查看声明,里面没有缺省参数而定义中存在缺省参数将会报错

void fund(int a = 5) {
    cout << a << endl;
}
int main() {
    void fund(int a);
    fund();//将会报错,因为运行到函数声明时里面没有缺省参数而定义中指定缺省参数
    return 0;
}

        当出现缺省参数时,函数传参也必须要从右到左依次给出,如下:

#include <iostream>
using namespace std;
void Func(int a = 10, int b = 20, int c = 30) {
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
}
int main() {
    Func();//a = 10,b = 20,c = 30
    Func(2);//a = 2,b = 20,c = 30
    Func(1, 2);//a = 1,b = 2, c = 30
    Func(1, 2, 3);//a = 1,b = 2, c = 3
    Func(, 3, );//错误用法
    return 0;
}


三,函数重载

        函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数或类型或类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

        函数重载的注意要点其实主要根据编译器的识别。当函数名相同时,只要当我们运用重名函数时能够区分两者的不同即可通过。如当传参时参数的类型不同或个数不同或顺序不同。如下:

例一:

#include <iostream>
using namespace std;
int Func(int a = 10, int b = 20, int c = 30) {
    return a + b + c;
}
int Func(int a = 1, int b = 2) {
    return a + b;
}
int main() {
    Func();//系统将报错,因为此时两个重名函数都满足条件,编译器无法区分用哪个
    Func(2);//系统报错,同理
    Func(1, 2);//系统报错,同理
    Func(1, 2, 3);//参数数量不同,可以区分,正常运行
    return 0;
}

例二:

#include <iostream>
using namespace std;
void Func(int a = 10, int b = 20, int c = 30) {
    cout << a + b + c << endl;
}
int Func(int a = 1, int b = 2, int c = 3) {
    return a + b;
}
int main() {
    Func(1, 2, 3);//函数类型虽不同,但当调用时两者仍都满足,所以出错
    return 0;
}


四,引用

4-1,引用的使用

       在C++中出现了与指针效果相同的引用概念,引用与指针不同的是引用不是新定义一个变量,而是给已存在的变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间,即可通过引用来改变变量,与指针一样。

使用方法:类型& 引用变量名(对象名) = 引用实体。

void TestRef()

{    

        int a = 10;

        int& b = a;//定义引用类型

        //输出两者的地址一样,即b的改变也会影响a的改变    

        printf("%p\n", &a);

        printf("%p\n", &b);

}

图解:

其中引用的使用要有以下注意要点:

        1,引用类型必须和引用实体是同种类型的,指针可以不同。

        例如:int a = 5;chr &b = a;将会出错,因为变量a的类型为int,指向a的引用b的类型也必须为int。

        2,引用在定义时必须初始化。

        例如:int &c;将会出错,因为引用没有初始化

        3,一个变量可以有多个引用。

        例如:int a = 5;int &b = a;int &c = a;也就是说一个变量可有多个别名,当a、b、c其中一个改变时,这些别名和a的值都会被改变。

        4,引用一旦引用一个实体,再不能引用其他实体。

        例如:int a = 7, b = 6;int &c = a;&c = b;错误,因为引用c已经指向了一个实体,不能改变引用的指向,但是类似于c = b,c = 9等操作是赋值操作,没有改变引用的指向,是可以的。 


4-2,常引用

        常引用通常是引用常量的,也可引用变量。具体定义:const 类型& 引用变量名(对象名) = 常量。

解析说明:

        首先,我们先要明白,无论什么变量,只要加上const关键字修饰后相当于将变量的权限缩小了,即此时的变量成为了常量,不可改变,而常引用就是将引用的权限缩小,即局限了引用的作用范围,当常引用指向变量时,是将别名的权限限制了,但变量名本身还可以改变。之所以常引用可以指向变量是因为在规定中,权限小的可以指向权限大的,权限大的不可指向权限小的,而变量的值可以改变,常量的值不可改变,因此变量的权限要比常量的权限大。之所以要如此规定是因为当大权限的引用一旦指向常量时,引用改变时常量也要改变,显示是错误的,而使用const修饰后的引用本身其实就是别名,当指向大权限变量时,其实只是将别名限制,跟变量本身权限无关。指针与此也是同理。

        还有,在平常我们变量赋值操作时,如果会发生类型转换,中间都会产生一个临时变量,赋值的操作不是变量之间直接赋值,是将这个临时变量赋值,而这种临时变量具有常性,也就是此时是将常量赋值。没有类型转换将不会发生此事情,将直接赋值。如下图:

void TestConstRef()
{
    const int a = 10;
    //int& ra = a;// 该语句编译时会出错,a为常量,权限大的不可指向权限小的
    const int& ra = a;
    //int& b = 10;// 该语句编译时会出错,b为常量,权限大的不可指向权限小的
    const int& b = 10;

    //权限小的指向权限大的
    int c = 5;
    const int& e = c;//别名权限缩小
    cout << "c = " << e << endl;//输出5
    c = 6;
    cout << "c = " << e << endl;//输出6

    //产生临时变量的情况

    double d = 12.34;

    //int& rd = d; // 该语句编译时会出错,类型不同,系统将具有常属性的临时变量进行赋值

    const int& rd = d;//相当于const int& rd = 12,rd = 12。
}


4-3,引用的使用场景

        引用的使用场景其实跟指针的使用场景一样,唯一要注意的是引用作为函数返回值的情况。当引用作为函数的返回值时,请注意,不要返回局部变量的引用,因为局部变量是存放在内存中的栈区中,栈区的数据会随着函数栈帧的销毁而销毁,一旦栈帧销毁了局部变量的值将会随机,但是如果编译器没有及时销毁函数栈帧,这时里面的数据还存在,将不会出现错误。如下:

#include <iostream>
using namespace std;
int& ADD(int a, int b) {
    int c = a + b;
    return c;
}
int main() {
    cout << "ADD(2, 3): " << ADD(2, 3) << endl;
    cout << "ADD(2, 3): " << ADD(2, 3) << endl;
    cout << "ADD(2, 3): " << ADD(2, 3) << endl;
    return 0;
}

运行图:

        可发现,本人的编译器没有及时销毁函数栈帧,即系统没有及时回收内存。但是有些编译器会及时回收内存,即销毁函数栈帧,所以,要想返回局部变量的引用,我们可用关键字static将其放入到静态区中存储,静态区中的数据只会在整个程序结束后才回收内存,不会随着函数栈帧的销毁而销毁。即如下:

#include <iostream>
using namespace std;
int& ADD(int a, int b) {
    static int c = a + b;
    return c;
}
int main() {
    cout << "ADD(2, 3): " << ADD(2, 3) << endl;
    cout << "ADD(2, 3): " << ADD(2, 3) << endl;
    cout << "ADD(2, 3): " << ADD(2, 3) << endl;
    return 0;
}    

分析:

        在计算机中,当函数返回值时,其实系统先将此值进行了保存,将此数据临时拷贝到了寄存器中,当返回时其实就是从寄存器中返回。所以,在以上返回局部变量的引用时笔者调用了多次,因为寄存器保留了此数据,当我们第二次调用此数据就彻底清空了,所以,只调用一次是不能确定函数栈帧是否被及时回收。

         大多数情况下,我们运用引用作为函数的返回值时是为了修改数值,在后面的学习中我们会深入运用,在这里先了解下即可。


4-4,引用的效率分析以及与指针的关系

引用的本质:

        引用的本质在C++内部实现是一个指针常量,说白了引用其实是按照指针方式来实现的,并且,在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

1,变量引用的使用

 int a = 10;

int& p = a;//系统内部自动转换为int* const p = &a;其中指针常量是指针的指向不可改,也就说明了为什么引用不可更改的原因

 p = 20;//内部发现p是引用,自动转化为*p = 20;

2,常引用的使用

 const int& p = 10;//加上const修饰后,系统内部将代码转换为int a = 10;const int& p = a;

引用跟指针和普通数值之间的效率比较:

        首先,我们来分析以值作为参数或者返回值类型的情况,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。当我们运用指针时,指针可是要在内存中开辟空间,在运算时,指针在内存中要经过复杂转换和相关逻辑的连接,这些复杂运算很容易产生错误而且可读性也差,在传值和指针作为传参以及返回值类型上效率相差就很大。引用的使用可达到指针的相同效果,虽然当函数调用时仍要给形参分配存储空间,但是引用本身就不另开空间,运算时也是跟引用指向的实体运算一样,没有复杂的逻辑结构。综上所述,引用无论在效率上还是安全性上都要比指针高。

        引用虽然相对于指针比较安全和高效,但引用本身也不是绝对安全,如果一旦使用不当也将会产生危险性。


五,内联函数

       在讲解内联函数之前我们先回顾下C语言中的宏。宏的用法跟函数类似,它比函数高效的是宏的使用不用建立函数栈帧,但宏本身也存在很多问题,我们先观察以下代码:

#define ADD(x, y) x + y;

//int a = ADD(1, 2) * 5;转换后a = 1 + 2 * 5 = 11,不符合我们的要求
#define ADD(x, y) (x + y)

//int a = ADD(1 | 2, 1 & 2); 转换后a = (1 | 2 + 1 & 2),不符合我们的要求
#define ADD(x, y) (x) + (y)

//int a = ADD(1, 2) * 5;转换后a = 1 + 2 * 5 = 11,不符合我们的要求
#define ADD(x, y) ((x) + (y));

//写法正确

        不难发现,宏的使用虽然在效率上比函数高,但本身存在很多细节观念,复杂的宏使用很容易掉坑,所以,宏有以下优缺点:

        优点: 1.增强代码的复用性。

                            2.提高性能。

        缺点: 1.不方便调试宏。(因为预编译阶段进行了替换,也就是不能调试,难以发现错误)

                    2.宏导致代码可读性差,可维护性差,容易出错。

                    3.没有类型安全的检查 。

        由于宏的这些原因,C++使用了以下两中方法进行改进:

                1,使用常量定义,换用const enum(即枚举)

                2,使用短小函数的内联函数

        枚举在这里我们先不讨论,我们先观察内联函数。C++中用的关键字inline修饰的函数叫做内联函数,编译时,C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,从这方面可看出,内联函数提升了程序运行的效率。

解析:

        1,inline其实是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,系统会用函数体替换函数调用,这样一来可能就会使目标文件变大,但少了调用开销,提高了程序的整体运行效率。

        2,inline虽然几乎解决了宏的所有缺陷,但是inline的使用使空间消耗太大了,所以,当函数规模较小时,编译器才会决定使用内联函数,当函数规模较大或运用了递归时,编译器将直接忽略了这种请求,即内部还是没有使用内联函数。笔者建议,对于函数规模较小且频繁调用时采用inline修饰。 

        3,不同编译器内联函数的实现机制可能有所不同,具体还要根据编译器的内部功能而定。

        4,inline函数不支持声明和定义分离开,因为编译器一旦将一个函数作为内联函数处理,就会在调用位置展开,即该函数是没有地址的,也不能在其他源文件中调用,故一般都是直接在源文件中定义内联函数的。总的来说就是inline不支持头文件的定义。

        5,可以在同一个项目的不同源文件定义函数名相同但实现功能不同的内联函数。

举例如下:

//内部规模小,系统将展开

inline int Add(int x, int y) {
    int c = x + y;
    return c;
}

//内部规模较大,系统不会展开

inline int Add(int x, int y) {
    int c = x + y;
    int c1 = x + y;
    int c2 = x + y;
    int c3 = x + y;
    int c4 = x + y;
    int c5 = x + y;
    int c6 = x + y;
    int c7 = x + y;
    int c8 = x + y;
    int c9 = x + y * c8;
    int c10 = x + y;
    int c11 = x + y;
    return c1 + c10 - c9;
}

//运用了递归,系统将不会展开

typedef struct Node {
    int val;
    struct Node* left;
    struct Node* right;
}Node;
inline int Tree(Node* root) {
    if (!root) {
        return 0;
    }
    int leftsize = Tree(root->left);
    int rightsize = Tree(root->right);
    return leftsize + rightsize;
}

        内联函数的运用虽然具有局限性,但是它的优点不可忽视,在后期的运用也是很重要的。它可以调试,运用效率高,语法也简单,更不用建立栈帧,大大的提升了效率。


补充:本文讲解很多细节其实是为后面打基础,部分内容设计到了很多原理,这不仅是为了后面的开发打基础,还是为了后面的深入学习做铺垫,所以,一定要理解这些原理和理清这些思路,否则后面的文章学习中将会感到很困惑。最后要说的是,C++的学习本身就有很大的难度,开头其实还好,后面越深入难度越大,我们一定要有个好的心态并积极练习才能学好这门技术。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1142072.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

论文阅读——ELECTRA

论文下载&#xff1a;https://openreview.net/pdf?idr1xMH1BtvB 另一篇分析文章&#xff1a;ELECTRA 详解 - 知乎 一、概述 对BERT的token mask 做了改进。结合了GAN生成对抗模型的思路&#xff0c;但是和GAN不同。 不是对选择的token直接用mask替代&#xff0c;而是替换为…

中国两轮“技术派”绿源,为全球电动市场带来跨越式方案

历史越长的行业&#xff0c;遇到变革之时&#xff0c;需要经历的考验、做出的突破就越多。两轮电动车&#xff0c;这个非常本土化的赛道&#xff0c;就是如此。 中国是两轮电动车产销大国&#xff0c;自上世纪晚期开始&#xff0c;中国两轮电动车迅速发展&#xff0c;绿源等一…

【Linux】虚拟机部署与发布J2EE项目(Windows版本)

&#x1f389;&#x1f389;欢迎来到我的CSDN主页&#xff01;&#x1f389;&#x1f389; &#x1f3c5;我是Java方文山&#xff0c;一个在CSDN分享笔记的博主。&#x1f4da;&#x1f4da; &#x1f31f;推荐给大家我的专栏《微信小程序开发实战》。&#x1f3af;&#x1f3a…

优思学院|精益管理的八步法

精益管理是什么&#xff1f;所谓的精&#xff0c;即少而精&#xff0c;不投入多余的生产要素&#xff0c;只是在适当的时间生产必要数量的市场急需产品&#xff08;或下道工序急需的产品&#xff09;&#xff1b;所谓的益&#xff0c;即所有经营活动都要有益有效&#xff0c;具…

【C语言】字符函数与字符串函数

简单不先于复杂&#xff0c;而是在复杂之后。 目录 0. 前言 1. 函数介绍 1.1 strlen 1.1.1 介绍 1.1.2 strlen 函数模拟实现 1.1.2.1 计数器方法 1.1.2.2 递归方法 1.1.2.3 指针 - 指针方法 1.2 strcpy 1.2.1 介绍 1.2.2 strcpy 函数模拟实现 1.3 strcat 1…

TSINGSEE青犀睡岗离岗检测算法——确保加油站安全运营

众所周知&#xff0c;加油站是一个需要24小时营业的场所&#xff0c;由于夜间加油人员较少&#xff0c;员工极易处于疲劳或者睡眠状态&#xff0c;为保障安全和效率&#xff0c;通过TSINGSEE青犀睡岗离岗检测算法在加油站场景中&#xff0c;可以及时发现工作人员的疲劳状况&…

Python---while循环中else的基本语法(是同级关系)

为什么需要在while循环中添加else结构 循环可以和else配合使用&#xff0c; else下方缩进的代码指的是当循环正常结束之后要执行的代码。 强调&#xff1a; 循环 正常结束&#xff0c;else之后要执行的代码。 非正常结束&#xff0c;其else中的代码是不会执行的。&#…

【软考系统架构设计师】2023年系统架构师冲刺模拟习题之《数据库系统》

在数据库章节中可能会考察以下内容&#xff1a; 文章目录 数据库完整性约束&#x1f31f;数据库模式&#x1f31f;&#x1f31f;ER模式&#x1f31f;关系代数&#x1f31f;&#x1f31f;并发控制&#x1f31f;数据仓库与数据挖掘&#x1f31f;&#x1f31f;反规范化技术&#x…

【卖断货攻略】抢先看:美国全品类30天爆量近2亿刀!

距离10月27日黑五大促正式上线不足6小时&#xff0c;你上车了吗&#xff1f; 看到TikTok美国市场近期的GMV走势图&#xff0c;就感觉这届黑五将不简单。 为助力跨境商家在这个关键节点做好最后准备&#xff0c;本期超店有数将从选品、营销两大角度为大家盘点现阶段TikTok Shop…

体系结构评估——(三)风险承担者

风险承担者分为系统生产者、系统消费者、系统服务人员和其他四大类。 其中系统生产者有&#xff1a;软件系统架构师、开发人员、维护人员、集成人员、测试人员、标准专家、 性能工程师、安全专家、项目经理、产品线经理。 系统消费者有&#xff1a;客户、最终用户、应用开发…

特征工程优化

参考链接 https://www.bilibili.com/video/BV1WN4y1k7R1/?buvidXU0E30D0C6006B7F1EE1425156434CFEC440F&from_spmidtm.recommend.0.0&is_story_h5false&midfMtk7pz9LsVpSyGt0Mcizg%3D%3D&p1&plat_id116&share_fromugc&share_mediumandroid&sh…

政务钉钉扫码登录(前端)

前提 使用 iframe 嵌入专有钉钉二维码页面&#xff0c;本篇仅说前端&#xff1b;需要申请 client_id 应用标识&#xff0c;但这里不赘述。详见此处&#xff1b;回调地址 redirect_uri&#xff0c;与服务器相关人员确认&#xff0c;但这里不赘述&#xff1b;扫码登录官方说明 …

LeetCode 1465. 切割后面积最大的蛋糕

矩形蛋糕的高度为 h 且宽度为 w&#xff0c;给你两个整数数组 horizontalCuts 和 verticalCuts&#xff0c;其中&#xff1a; horizontalCuts[i] 是从矩形蛋糕顶部到第 i 个水平切口的距离 verticalCuts[j] 是从矩形蛋糕的左侧到第 j 个竖直切口的距离 请你按数组 horizontalC…

【优选算法系列】第二节.双指针(202. 快乐数和11. 盛最多水的容器)

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;优选算法系列 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&#xff01…

了解接口测试只需3分钟

为什么要做接口测试&#xff1f; 在公司里&#xff0c;客户端和服务端通常是由不同的团队开发的&#xff0c;在项目开发过程中&#xff0c;客户端和服务端开发的进度不一致&#xff0c;比如服务端先开发完了&#xff0c;这个时候可以先对服务端进行接口测试&#xff0c;确保服…

douyin ios 8404六神参数学习记录

玩那么久安卓了&#xff0c;也终于换一换ios终端分析分析&#xff0c;还是熟悉的x-gorgon&#xff0c;x-argus&#xff0c;x-medusa那些参数。 随便抓个抖音 ios版本的接口&#xff1a; 像评论接口&#xff1a; https://api26-normal-hl.amemv.com/aweme/v2/comment/list/?…

OpenCV官方教程中文版 —— 傅里叶变换

OpenCV官方教程中文版 —— 傅里叶变换 前言一、原理二、Numpy 中的傅里叶变换三、OpenCV 中的傅里叶变换四、为什么拉普拉斯算子是高通滤波器&#xff1f; 前言 本小节我们将要学习&#xff1a; • 使用 OpenCV 对图像进行傅里叶变换 • 使用 Numpy 中 FFT&#xff08;快速…

Linux下进程地址空间初步理解

进程地址空间 进程地址空间是操作系统为每个进程分配的一块内存空间&#xff0c;用于存储进程的代码、数据和堆栈等信息。进程地址空间是逻辑上独立而相互隔离的&#xff0c;每个进程拥有自己独立的地址空间&#xff0c;进程之间不能直接访问彼此的地址空间。 代码段&#xff…

<多线程章节四>如何使用synchronized解决线程不安全问题(原子性、内存可见性…)等等

文章目录 &#x1f4a1;专栏导读&#x1f4a1;文章导读&#x1f490;线程不安全示例&#x1f490;锁的特性&#x1f490;产生线程不安全的原因&#xff1a;&#x1f490;加锁的三种方式&#xff1a; &#x1f4a1;专栏导读 本篇文章收录于多线程&#xff0c;也欢迎翻阅博主的其…

mavros黑白名单设置

链接: mavros设置黑白名单 设置mavros黑白名单主要是通过插件的参数进行设置&#xff0c;如下&#xff1a; 这里是在px4_pluginlists.yaml参数文件中设置 plugin_blacklist: # common - safety_area - 3dr_radio - actuator_control - hil_controls - ftp - global_position …