C++第一弹 -- C++基础语法上(命名空间 输入输出 缺省参数 函数重载 引用)

目录

  • 前言
  • 一. C++关键字(C++98)
  • 二. 命名空间
    • 1.命名空间的定义
    • 2.命名空间的使用
    • 3.其它部分
  • 三. C++输入&输出
  • 四. 缺省参数
    • 1. 缺省参数的概念
    • 2.缺省参数的分类
  • 五. 函数重载
    • 1.函数重载的概念
    • 2. 为什么C++支持函数重载, 而C语言不支持重载呢?
  • 六. 引用
    • 1.引用的概念
    • 2.引用的特性
    • 3.常引用
    • 4.引用场景
    • 5.引用和指针的区别

前言

C++是在C的基础之上,容纳进去了面向对象编程思想,并增加了许多有用的库,以及编程范式等。熟悉C语言之后,对C++学习有一定的帮助,本篇将介绍C++是如何对C语言设计不合理的地方进行优化的,比如:作用域方面、IO方面、函数方面、指针方面、宏方面等, 为后续类和对象学习打基础

更多好文点击 博客主页: 酷酷学!!! 期待您的关注!


正文开始

一. C++关键字(C++98)

C++总计63个关键字,C语言32个关键字

ps:下面我们只是看一下C++有多少关键字,不对关键字进行具体的讲解。后面我们学到以后再细讲。

在这里插入图片描述

二. 命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存在于全局作用域或者局部作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化,以避免命名冲突或名字污染namespace关键字的出现就是针对这种问题的。

使用命名空间也可以很好的解决我们和库之间或者多个程序员在进行一个项目时, 名称重复的问题, 如下面这个例子

#include<stdio.h>
#include<stdlib.h>

int rand = 10;

int main()
{
	printf("%d\n", rand);
	return 0;
}

这里会报错, 因为rand已经在<stdlib.h>头文件中定义过, 所以再次定义全局变量rand, 作用域都是全局, 会导致名称重复, C语言没办法解决类似这样的命名冲突问题,所以C++提出了namespace来解决.

在这里插入图片描述

编译后后报错:error C2365: “rand”: 重定义;以前的定义是“函数”

1.命名空间的定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{}即可,{}中即为命名空间的成员。

注意: 这里和结构体的区别在于结构体{}后有; 而命名空间没有

  1. 正常的命名空间的定义

命名空间可以定义变量/函数/类型

#include<stdio.h>
#include<stdlib.h>

//int rand = 10;

namespace kkx
{
	int rand = 10;

	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int val;
	};
}

int main()
{
	//int rand = 20;
	printf("%d\n", kkx::rand);
	return 0;
}
  1. 命名空间可以嵌套
//test.cpp
namespace N1
{
	int a;
	int b;
	int Add(int left, int right)
	{
		return left + right;
	}

	namespace N2
	{
		int c;
		int d;
		int Sub(int left, int right)
		{
			return left - right;
		}
	}
}
  1. 同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中.

PS:一个工程中的test.h和上面的test.cpp中两个N1会被合并成一个

//test.h
namespace N1
{
	int Mul(int left, int right)
	{
		return left * right;
	}
}

2.命名空间的使用

命名空间中成员该如何使用呢?比如:

namespace N
{
	int a = 10;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int val;
	};
}

int main()
{
	printf("%d\n", a);
	return 0;
}
// 编译报错:error C2065: “a”: 未声明的标识符

编译默认查找
a、当前局部域 : 自留地
b、全局域找 : 村子野地
不会到其他命名空间中去找

命名空间的使用有三种方式:

  • 加命名空间名称及作用域限定符
int main()
{
    printf("%d\n", N::a);
    return 0;    
}
  • 使用using将命名空间中某个成员引入
using N::b;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;    
}
  • 使用using namespace 命名空间名称 引入

编译默认查找
/a、当前局部域 : 自留地
b、全局域找 : 村子野地
c、到展开的命名空间中查找 : 相当于张大爷在自己的自留地加了声明,谁需要就来摘

using namespce N;
int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

3.其它部分

  • 不同域中可以存在同名的变量, 编译器默认会使用局部变量, 但是如果想使用全局变量时, 不写空间名称直接写作用域限定符即表示访问全局变量
int rand = 10;
int main()
{
	int rand = 20;
	printf("%d\n", ::rand);
	return 0;
}
  • 使用using namespace固然好用, 但不宜过度用, 不同命名空间中有相同的名称, 全部展开, 编译器会报错,例如

namespace N1
{
	int a = 10;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int val;
	};
}
namespace N2
{
	int a = 10;
	int b = 1;
	int Add(int left, int right)
	{
		return left + right;
	}

	struct Node
	{
		struct Node* next;
		int val;
	};
}
using namespace N1;
using namespace N2;

三. C++输入&输出

C++的输入输出需要包含头文件 < isotream > , 直接使用cout(console out 从控制台输出) 和 endl(end line 换行) 会发生报错, 这是因为官方为避免与我们自己定义的名称和库重复, 所以将库的函数名称包含在了std命名空间里面, 所以我们如果使用需要按照命名空间的使用方法使用std

#include<iostream>

int main()
{
	cout << "Hello World!!!" << endl;
	return 0;
}

在这里插入图片描述

正确用法:

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using namespace std;
int main()
{
	cout<<"Hello world!!!"<<endl;
	return 0;
}

//或者

#include<iostream>
// std是C++标准库的命名空间名,C++将标准库的定义实现都放到这个命名空间中
using std::cout;
using std::endl;
int main()
{
	cout<<"Hello world!!!"<<endl;
	return 0;
}

说明:

  1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。
  2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。
  3. <<是流插入运算符,>>是流提取运算符。
  4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。C++的输入输出可以自动识别变量类型。
  5. 实际上cout和cin分别是ostream和istream类型的对象,>>和<<也涉及运算符重载等知识,这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有一个章节更深入的学习IO流用法及原理。

注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间,规定C++头文件不带.h;旧编译器(vc 6.0)中还支持<iostream.h>格式,后续编译器已不支持,因此推荐使用+std的方式。

#include <iostream>
using namespace std;

int main()
{
	int a;
	double b;
	char c;

	// 可以自动识别变量的类型
	cin >> a;
	cin >> b >> c;

	cout << a << endl;
	cout << b << " " << c << endl;
	return 0;
}

ps:关于cout和cin还有很多更复杂的用法,比如控制浮点数输出精度,控制整形输出进制格式等等。因为C++兼容C语言的用法,这些又用得不是很多,我们这里就不展开学习了。后续如果有需要,我们再配合文档学习

std命名空间的使用惯例:
std是C++标准库的命名空间,如何展开std使用更合理呢?

  1. 在日常练习中,建议直接using namespace std即可,这样就很方便。
  2. using namespace std展开,标准库就全部暴露出来了,如果我们定义跟库重名的类型/对象/函数,就存在冲突问题。该问题在日常练习中很少出现,但是项目开发中代码较多、规模大,就很容易出现。所以建议在项目开发中使用,像std::cout这样使用时指定命名空间 + using std::cout展开常用的库对象/类型等方式。

四. 缺省参数

1. 缺省参数的概念

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

void Func(int a = 0)
{
	cout << a << endl;
}

int main()
{
	Func();// 没有传参时,使用参数的默认值
	Func(10);// 传参时,使用指定的实参
	return 0;
}

2.缺省参数的分类

  • 全缺省参数
 void Func(int a = 10, int b = 20, int c = 30)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }
  • 半缺省参数
 void Func(int a, int b = 10, int c = 20)
 {
     cout<<"a = "<<a<<endl;
     cout<<"b = "<<b<<endl;
     cout<<"c = "<<c<<endl;
 }

传值时只能顺序传,不能跳着传

int main()
{
	F2(1, 2, 3);
	F2(1, 2);
	F2(1);
	F2();

	// 必须顺序传,不能跳跃着传
	// F2(1, ,2);

注意:

  1. 半缺省参数必须从右往左依次来给出,不能间隔着给
  2. 缺省参数不能在函数声明和定义中同时出现, 如果缺省参数的声明和定义分离, 以声明的值为主.
  //a.h
  void Func(int a = 10);
  
  // a.cpp
  void Func(int a = 20)
 {}
  
  // 注意:注意:如果生命与定义位置同时出现,以声明为主
  1. 缺省值必须是常量或者全局变量
  2. C语言不支持(编译器不支持)

五. 函数重载

自然语言中,一个词可以有多重含义,人们可以通过上下文来判断该词真实的含义,即该词被重载了。
比如:以前有一个笑话,国有两个体育项目大家根本不用看,也不用担心。一个是乒乓球,一个是男足。前者是“谁也赢不了!”,后者是“谁也赢不了!”

1.函数重载的概念

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

即同一作用域, 参数个数不同, 参数类型不同, 类型顺序不同, 三种情况构造重载关系

#include<iostream>
using namespace std;

//1.参数类型不同
int Add(int left, int right)
{
	cout << "int Add(int left, int right)" << endl;
	return left + right;
}

double Add(double left, double right)
{
	cout << "double Add(double left, double right)" << endl;

	return left + right;
}

//2.参数个数不同

void f()
{
	cout << "f()" << endl;
}
void f(int a)
{
	cout << "void f(int a)" << endl;
}

//3.参数类型顺序不同

void f(int a, char b)
{
	cout << "void f(int a, char b)" << endl;
}

void f(char a, int b)
{
	cout << "void f(char a, int b)" << endl;
}

int main()
{
	Add(10, 20);
	Add(10.1, 20.2);

	f();
	f(10);

	f(10, 'a');
	f('a', 10);
	return 0;
}

不同作用域, 可以同名
同一作用域, 可以同名, 满足重载规则

 //不同作用域 可以同名
namespace N1
{
	void Swap(int* pa, int* pb)
	{
		cout << "void Swap(int* pa, int* pb)" << endl;
	}
}

namespace N2
{
	void Swap(int* px, int* py)
	{
		cout << "void Swap(int* pa, int* pb)" << endl;
	}
}


// 同一作用域 可以同名,满足重载规则
void Swap(double* pa, double* pb)
{
	cout << "void Swap(double* pa, double* pb)" << endl;
}

using namespace N1;
using namespace N2;
// 他们两依旧是ok,不是重载关系

int main()
{
	int a = 0, b = 1;
	double c = 0.1, d = 1.1;
	// 调用歧义
	//Swap(&a, &b);

	Swap(&c, &d);

	return 0;
}

这段代码N1, N2 不在同一作用域, 可以同名, 不构成重载, 但是命名空间全部展开, 会引发调用歧义.

下面两个构造函数重载
f()但是这样调用存在歧义

void f()
{
	cout << "f()" << endl;
}

void f(int a = 10)
{
	cout << "f(int a)" << endl;
}

2. 为什么C++支持函数重载, 而C语言不支持重载呢?

这是因为在函数定义与声明分离时, 编译阶段无法直接获得函数地址, 只是通过函数声明,语法可以通过, 链接阶段, C语言直接通过函数名字进行查找, 不支持函数重载, 而C++是使用修饰后的函数名字去查找就可以支持函数重载.

具体过程如下:

  1. 一个项目工程中, 声明和定义通常是分离的, 声明在.h文件中, 定义在.cpp文件中, 如下图
    在这里插入图片描述
    代码在变成可执行程序需要经过编译和链接, 编译分为三个过程, 首先经过预处理, 将.h与.cpp文件进行结合, 进行头文件展开, 宏替换, 条件编译等等, 生成.i文件, 此时就没有.h文件的事情了. 然后, 通过编译, 检查语法, 生成汇编代码, 此时语法通过, 检查语法匹配, 但没有函数地址. 最后通过汇编转成二进制机械码, 但是有函数的定义, 才能生成一堆汇编指令, 所以在链接阶段, 需要查找函数地址, 也就是将Test.o和Stack.o链接在一起.

在这里插入图片描述
如图所示, 转成汇编代码, 在调用StackInit()函数时, 语法通过, 然后执行下一句, jmp指令会通过StackInit()函数名去查找函数地址
在这里插入图片描述
函数有一对要执行的指令, 函数地址就是第一句指令的地址.
在这里插入图片描述
那么,也就是说在声明与定义分离时, 链接过程中需要通过函数名字去找函数地址, 而C语言直接使用函数名字查找,不支持重载, 而C++使用过修饰后的名字查找, 支持重载.

如下图, 我们先将函数定义注释, 就可以看到, 发上了链接错误, 此时我们再看如何进行修饰的, Windows平台下, C++会根据参数列表(参数个数 或 类型 或 类型顺序) 进行函数名字的修饰, 函数重载, 修饰出来的名字不一样, 那就可以区分. 而C语言则没有对函数名字进行修饰

在这里插入图片描述

不同从操作系统对函数名字的修饰规则也不太一样, 比如在Linux操作系统下,对这三个函数的修饰就很直观, 以首字母进行修饰

在这里插入图片描述

在这里插入图片描述
而我们将文件改成.c 就可以发现C语言没有对函数名字修饰, 所以不支持重载

在这里插入图片描述

对比Linux会发现,windows下vs编译器对函数名字修饰规则相对复杂难懂,但道理都是类似的,我们就不做细致的研究了。

六. 引用

1.引用的概念

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空间,它和它引用的变量共用同一块内存空间。
比如:李逵,在家称为"铁牛",江湖上人称"黑旋风"。

在这里插入图片描述

类型& 引用变量名(对象名) = 引用实体;

void TestRef()
{
	int a = 10;
	int& ra = a; //定义引用类型
	printf("%p\n", &a);
	printf("%p\n", &ra);

}
int main()
{
	TestRef();

	return 0;
}

在这里插入图片描述
注意: 引用类型必须和引用实体是同种类型的

2.引用的特性

  1. 引用在定义时必须初始化
  2. 一个变量可以有多个引用
  3. 引用一旦引用一个实体, 再不引用其它实体
void TestRef()
{
    int a = 10;
    int& ra = a;//<====定义引用类型
    printf("%p\n", &a);
    printf("%p\n", &ra);
}

3.常引用

void TestConstRef()
{
    const int a = 10;
    //int& ra = a;   // 该语句编译时会出错,a为常量
    const int& ra = a;
    // int& b = 10; // 该语句编译时会出错,b为常量
    const int& b = 10;
    double d = 12.34;
    //int& rd = d; // 该语句编译时会出错,类型不同
    const int& rd = d;
}

4.引用场景

  1. 做参数

之前我们在另一个函数交换值需要传地址, 有了引用就可以直接传引用,此时left就相当于a的别名, 而right就相当于b的别名.

void Swap(int& left, int& right)
{
   int temp = left;
   left = right;
   right = temp;
}

int main()
{
	int a = 10;
	int b = 20;
	Swap(a,b);
	return 0;
}
  1. 做返回值

后面我们在细讲

5.引用和指针的区别

typedef struct ListNode
{
	int val;
	struct ListNode* next;
}LTNode;

//之前我们不带哨兵位的链表插入结点需要传递二级指针
void ListPushBack(LTNode** phead, int x);

//这里也可以传递phead指针的引用
void ListPushBack(LTNode*& phead, int x);

//有的教材还可能这样写
typedef struct ListNode
{
	int val;
	struct ListNode* next;
}LTNode, * PNode;
//其本质也是一样的,只是将struct ListNode* 类型重命名为PNode
void ListPushBack(PNode& phead, int x);

这段代码, 是将z赋值给y, 因为引用一旦引用实体,就不可以引用别的实体

int main()
{
	// int& a;

	int x = 0;
	int& y = x;
	int z = 1;
	// y变成z的别名呢?
	// 还是z赋值给y
	y = z;

	return 0;
}

不管是引用普通变量还是指针变量, 只能权限的缩小, 而不能权限的放大 ,指针赋值也是, 因为被const修饰的地址不可以修改

int main(){

	int x = 0;
	int& y = x; //权限的平移,可以
	const int& z = x;//权限的缩小,可以
	y++;//可以,z++不可以




	const int m = 0;
	// int& n = m;m是只读的,n变成我的别名,n的权限是可读可写,权限的放大,不可以

	const int& n = m; //可以,不是权限的放大

	int p = m;// m拷贝的给p,p的修改不影响m

	// 权限的放大
	// p1可以修改 *p1不可以,const修饰是的*p1
	const int* p1 = &m;
	// p1++;
	// int* p2 = p1;//不可以,p1的内容不可以修改
	const int* p2 = p1;//可以,常量赋值给常量

	// 权限的缩小,可以
	int* p3 = &x;
	const int* p4 = p3;

	return 0;
}

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。
在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

引用和指针的不同点:

  1. 引用概念上定义一个变量的别名,指针存储一个变量地址。
  2. 引用在定义时必须初始化,指针没有要求
  3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何一个同类型实体
  4. 没有NULL引用,但有NULL指针
  5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32位平台下占4个字节)
  6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小
    int main()
    {
    int a = 10;
    int& ra = a;
    cout<<"&a = “<<&a<<endl;
    cout<<”&ra = "<<&ra<<endl;
    return 0;
    }
    int main()
    {
    int a = 10;
    int& ra = a;
    ra = 20;
    int* pa = &a;
    *pa = 20;
    return 0;
    }
  7. 有多级指针,但是没有多级引用
  8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理
  9. 引用比指针使用起来相对更安全

感谢点赞, 关注, 收藏!!!

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

sqlite 数据库 介绍

文章目录 前言一、什么是 SQLite &#xff1f;二、语法三、SQLite 场景四、磁盘文件 前言 下载 目前已经出到了&#xff0c; Version 3.46.0 SQLite&#xff0c;是一款轻型的数据库&#xff0c;是遵守ACID的关系型数据库管理系统&#xff0c;它包含在一个相对小的C库中。它是…

数学建模算法目标规划

在人们的生产实践中&#xff0c;经常会遇到如何利用现有资源来安排生产&#xff0c;以取得最大经济 效益的问题。此类问题构成了运筹学的一个重要分支—数学规划&#xff0c;而线性规划(Linear Programming 简记 LP)则是数学规划的一个重要分支。特别是在计算机能处理成千上万个…

第二届网络、通信与智能计算国际会议(NCIC 2024)

随着科技的飞速发展&#xff0c;网络通信与智能计算领域正迎来前所未有的变革。在这样的背景下&#xff0c;网络、通信与智能计算国际会议&#xff08;NCIC 2024&#xff09;将于2024年11月22日至25日在中国北京隆重召开。本次大会汇聚了国际学术界的顶尖专家和行业精英&#x…

目标检测算法简述

招聘信息共享社群https://bbs.csdn.net/forums/f6512aad40c7444c8252754ce2dbb427 目标检测算法是一种计算机视觉技术&#xff0c;用于识别图像或视频中的特定对象&#xff0c;并确定这些对象在场景中的精确位置。这些算法通常结合了分类和定位的功能&#xff0c;能够输出每个…

算法系列--分治排序|归并排序|逆序对的求解

一.基本概念与实现 归并排序(mergeSort)也是基于分治思想的一种排序方式,思路如下: 分解:根据中间下标mid将数组分解为两部分解决:不断执行上述分解过程,当分解到只有一个元素时,停止分解,此时就是有序的合并:合并两个有序的子区间,所有子区间合并的结果就是原问题的解 归并…

ESP32 蓝牙网关实践:BLE 设备数据采集与 MQTT 云平台发布(附代码示例)

摘要: 本文详细介绍了如何使用 ESP32 构建强大的蓝牙网关&#xff0c;实现蓝牙设备与 Wi-Fi/互联网之间的无缝连接和数据桥接。文章涵盖了连接和桥接功能、数据处理和分析能力&#xff0c;并提供了详细的代码示例和 Mermaid 生成的图表&#xff0c;助您轻松构建自己的蓝牙网关解…

SCI一区TOP|准随机分形搜索算法(QRFS)原理及实现【免费获取Matlab代码】

目录 1.背景2.算法原理2.1算法思想2.2算法过程 3.结果展示4.参考文献5.代码获取 1.背景 2024年&#xff0c;LA Beltran受到分形几何、低差异序列启发&#xff0c;提出了准随机分形搜索算法&#xff08;Quasi-random Fractal Search, QRFS&#xff09;。 2.算法原理 2.1算法思…

【Python】搭建属于自己 AI 机器人

目录 前言 1 准备工作 1.1 环境搭建 1.2 获取 API KEY 2 写代码 2.1 引用库 2.2 创建用户 2.3 创建对话 2.4 输出内容 2.5 调试 2.6 全部代码 2.7 简短的总结 3 优化代码 3.1 规范代码 3.1.1 引用库 3.1.2 创建提示词 3.1.3 创建模型 3.1.4 规范输出&#xf…

SQL面试题-留存率计算

表定义&#xff1a; create table if not exists liuliang_detail (user_id string comment ,record_time string comment yyyymmdd hh:mi:ss ) comment 流量明细表 ; 方法一&#xff1a; 计算的是整段时间范围内&#xff0c;每一天为基准的所有的留存1、2、7天的用户数。 …

cs231n作业2 双层神经网络

双层神经网络 我们选用ReLU函数和softmax函数&#xff1a; 步骤&#xff1a; 1、LOSS损失函数&#xff08;前向传播&#xff09;与梯度&#xff08;后向传播&#xff09;计算 Forward: 计算score&#xff0c;再根据score计算loss Backward&#xff1a;分别对W2、b2、W1、b1求…

使用Charles mock服务端响应数据

背景 服务端未提供接口/服务端接口返回结果有逻辑限制&#xff08;次数限制&#xff09;&#xff0c;不能通过原始接口返回多次模拟预期的返回结果&#xff0c;例如边界值情况 客户端受到接口响应数据的限制&#xff0c;无法继续开发或测试&#xff0c;会极大影响开发测试效率…

Unity入门之重要组件和API(3) : Transform

前言 Transform类主要处理游戏对象(GameObject)的位移、旋转、缩放、父子关系和坐标转换。 1.位置和位移 1.1必备知识点&#xff1a;Vector3 Vector3 主要用来表示三维坐标系中的一个点或者一个向量。 【声明】 Vector3 v1 new Vector3(); Vector3 v2 new Vector3(10, 10…

谷粒商城----通过缓存和分布式锁获取数据。

高并发下缓存失效的问题 高并发下缓存失效的问题--缓存穿透 指查询一个一定不存在的数据&#xff0c;由于缓存是不命中&#xff0c;将去查询数据库&#xff0c;但是数据库也无此记录&#xff0c;我们没有将这次查询的不写入缓存&#xff0c;这将导致这个不存在的数据每次请求…

详解「一本通 5.1 练习 1」括号配对(区间DP经典题)

一.题目 二.思路 题目的大意是说:给你一个只由[ ] ( )构成的字符串&#xff0c;请问需要增加多少个字符才能使其变为一个合法的括号序列。 因为添加若干字符使其达到匹配的目的等价于将不匹配的字符去除使得字符串达到匹配的目的 所以这题只需计算出已匹配完成的括号数,再…

深度学习与CV入门

文章目录 前言历史 前言 历史 tensorflow可以安装Tensorboard第三方库用于展示效果 TensorFlow工作流程&#xff1a;p6-4:20 使用tf.data加载数据。使用tf.data实例化读取训练数据和测试数据模型的建立与调试:使用动态图模式Eager Execution和著名的神经网络高层API框架Ker…

mongoDB教程(五):命名规范

还是大剑师兰特&#xff1a;曾是美国某知名大学计算机专业研究生&#xff0c;现为航空航海领域高级前端工程师&#xff1b;CSDN知名博主&#xff0c;GIS领域优质创作者&#xff0c;深耕openlayers、leaflet、mapbox、cesium&#xff0c;canvas&#xff0c;webgl&#xff0c;ech…

拍桌子、甩脸子、抡棒子没用,带出一流战斗力团队用好3招就够了

拍桌子、甩脸子、抡棒子没用&#xff0c;带出一流战斗力团队用好3招就够了 第一招&#xff1a;及时激励 在现实中&#xff0c;绝大部分管理者管理手段缺乏&#xff0c;只知道用钱进行激励。 而真正的高手不仅会满足员工物质上的需求&#xff0c;更注重员工心理上的满足。 他…

cs231n作业1——Softmax

参考文章&#xff1a;cs231n assignment1——softmax Softmax softmax其实和SVM差别不大&#xff0c;两者损失函数不同&#xff0c;softmax就是把各个类的得分转化成了概率。 损失函数&#xff1a; def softmax_loss_naive(W, X, y, reg):loss 0.0dW np.zeros_like(W)num_…

知识社区在线提问小程序模板源码

蓝色的知识问答&#xff0c;问答交流&#xff0c;知识社区&#xff0c;在线提问手机app小程序网页模板。包含&#xff1a;社区主页、提问、我的、绑定手机&#xff0c;实名认证等。 知识社区在线提问小程序模板源码

**kwargs 字典解包传参的方式

字典解包传参 在Python中&#xff0c;****kwargs**是一种通过字典解包 (dictionary unpacking) 的方式进行参数传递的方式。它将一个字典的键值对解包并传递给函数的命名参数。 示例代码 kwargs实参: {name: "jordan", age: 18, score: [80, 85, 85]} get_info形…