新月传媒做网站 怎么样/颜色广告
文章目录
- 参考
- 描述
- 指针
- 运算符
- 地址运算符
- 奇偶分体
- 指针的创建
- 间接寻址运算符
- 句点运算符
- 运算符优先级问题
- 箭头运算符
- 运算符优先级
- 指针
- 野指针
- 空指针
- 通用指针
- 解引用
- 分析
- 指针的算术运算
- 加减运算
- 自增运算与自减运算
- 比较运算
- 指针与常量
- 指针常量
- 常量指针
- 指向常量的指针常量
- 指针与数组
- 数组标识符与指针
- 数组元素与指针
- 边界检查
参考
项目 | 描述 |
---|---|
精通C++ (第九版) | 托尼·加迪斯、朱迪·沃尔特斯、戈德弗雷·穆甘达 (著) / 黄刚 等 (译) |
搜索引擎 | Bing |
描述
项目 | 描述 |
---|---|
操作系统 | Windows 10 专业版(64 位) |
C++ 编译器 | gcc version 8.1.0 (x86_64-win32-seh-rev0, Built by MinGW-W64 project) |
指针
指针中存放着指向内存中的某一空间(空间大小为一个字节,内存以字节为基础进行地址的编排及内存的划分)的内存地址,CPU 可以通过这个地址以及一些其它信息获取到该内存地址对应的内存空间中存放的数据。
内存的每一个字节都有唯一的地址。变量的地址是分配给该变量的第一个字节的地址。
运算符
地址运算符
使用地址运算符 & 你将获得 C++ 分配给一个变量或常量(使用 const 等关键字定义的常量)的内存空间的第一个字节所对应的内存地址。你仅需将地址运算符放置在变量或常量的标识符前可取得该变量或常量所对应的地址。对此,请参考如下示例:
// 导入 iostream 以实现基本的输入输出
#include <iostream>
// 导入 string 以使用 String 类创建字符串
#include <string>
// 使用 C++ 标准命名空间
using namespace std;int main(){// 声明一些常量及变量int a;const int b = 1;char c = 'c';string d = "Hello World";// 输出被声明的变量或常量所处的内存空间// 所对应的地址。cout << &a << endl;cout << &b << endl;cout << &c << endl;cout << &d << endl;// 暂停控制台的继续运行,便于观察输出到控制台中的内容。system("pause");
}
执行效果
0x61fe08
0x61fe04
c
0x61fde0
请按任意键继续. . .
注:
- 内存地址前的 0x 表明该内存地址是以十六进制的格式进行显示的。
- 在默认情况下,通过 & 运算符向控制台输出的内容为十六进制格式的内存地址。相比于十六进制的格式的内存地址,你可能更愿意观察十进制格式的内存地址。为此,你可以通过在 &标识符 前添加 (long long) (使用 (long long) 是由于我的操作系统是 64 位 的,使用 8 个字节来实现地址。如果你的操作系统是 32 位 的操作系统,那么你还能够使用 (int) 来转换数值所使用的进制格式。)来将十六进制格式的内存地址转换为十进制格式的内存地址。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){int a;const int b = 1;char c = 'c';string d = "Hello World";cout << (long long)&a << endl;cout << (long long)&b << endl;cout << (long long)&c << endl;cout << (long long)&d << endl;system("pause");
}
执行效果
6422024
6422020
6422019
6421984
请按任意键继续. . .
- 你可以通过如下方式来得知计算机的地址使用多少个字节进行表示:
#include <iostream>
#include <string>
using namespace std;int main(){// 此处可以声明任意类型的指针,因为在一台计算机中,// 内存地址均使用相同个数的字节进行表示。int* a;// 通过 sizeof 运算符来获取指针所占用的内存空间cout << sizeof a << endl;system("pause");
}
执行结果
由于我的计算机支持 64 位 操作系统,而我使用的也是 64 位 的操作系统。因此,内存地址使用八个字节(一个字节包含八位,也即八个比特)进行表示。
8
请按任意键继续. . .
奇偶分体
在使用 C++ 指针时,你可能会发现这么一个现象:若变量或常量存储的数据的数据类型所占用的内存空间不止一个字节,那么该变量或常量的地址多为偶地址。
奇地址与偶地址
-
奇地址
若一个内存地址属于奇数,那么该地址将被认为是一个奇地址。 -
偶地址
若一个内存地址属于偶数,那么该地址将被认为是一个偶地址。
奇偶分体
为了实现存储器的字节寻址及整字(占用内存空间的大小为两个字节)读写功能,人们将存储器分成容量相等(占据相同的内存空间大小,该空间大小为一个字节)的两类存储体,即奇存储体与偶存储体。
奇存储体所占据的内存空间所对应的地址为奇地址,而偶存储体所占据的内存空间所对应的地址为偶地址。
寻址与整字读取功能
- 寻址
存储器能够通过传输过来的内存地址对内存单元进行查找。
- 整字读取功能
为了充分利用数据总线的传输能力,CPU 从内存中读取数据将以一个字为单位进行读取。且字的起始内存地址需为偶地址(原因暂不明😝)。因此,将包含多个字节数据的变量的起始地址设置为偶地址将有利于提高对数据进行读取操作的效率。
因此机制,当大小为一个字的数据的起始地址为奇地址时,CPU 需要从内存中读取两个字的数据才能获得我们所需要的那一个字的数据
指针的创建
指针是具有类型之分的,整型类型的指针仅能存储指向整型数据的内存地址。若你没有依据指针的类型为其赋值,C++ 将抛出错误。
如果你需要创建一个整型指针,那么你有如下创建方式:
#include <iostream>
#include <string>
using namespace std;int main(){// 声明并初始化一个整型变量int a = 99;// 三种不同的创建整型指针的方式int *b = &a;int * c = &a;int* d = &a;cout << (long long)b << endl;cout << (long long)c << endl;cout << (long long)d << endl;system("pause");
}
执行结果
可以看到,三个整型指针都成功的存储了指向整型变量的内存地址。
6422020
6422020
6422020
请按任意键继续. . .
注:
- 使用哪种风格创建指针取决于你更喜欢哪一种。
- 创建一个存储其它数据类型的变量或常量的地址的指针与创建整型指针的方式类似,你仅需要在合适的位置添加符号 * 即可。
- 在创建指针时指明指针存储的内存地址所指向的数据的数据类型是为了使 C++ 在通过目标地址取出数据的过程中,能够以正确的方式从内存中取出数据。
间接寻址运算符
使用间接寻址运算符你将能够获取到一个指针所指向的内存空间中的数据。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){// 声明并初始化一个字符型变量char firstCharacter = 'a';// 将字符型变量的地址赋值给字符型指针 char* firstCharacterPtr = &firstCharacter;// 直接输出 firstCharacter 变量中存储的值cout << firstCharacter << endl;// 输出 firstCharacterPtr 所处的内存空间所对应的内存地址cout << (long long)firstCharacterPtr << endl;// 通过 fistCharacter 的内存地址获取到该变量中存储的值cout << *firstCharacterPtr << endl;system("pause");
}
执行结果
a
6422039
a
请按任意键继续. . .
句点运算符
句点运算符 . 用于引用类、结构体及共用体等复合类型的成员。大致用法如下:
#include <iostream>
#include <string>
using namespace std;// 声明 Notebook 类
class Notebook
{public: string title = "TwoMoons";string content = "Hello World";
};int main(){// 实例化 Notebook 类Notebook notebook;// 输出 notebook 中的成员属性所包含的内容cout << notebook.title << endl;cout << notebook.content << endl;system("pause");
}
执行效果
TwoMoons
Hello World
请按任意键继续. . .
运算符优先级问题
使用 * 及 . 符号,你能够通过指针选择对象、结构体等复合类型中的成员。但由于句点运算符 . 的优先级要高于间接运算符 * 所以你还需要用到括号,以提升间接运算符的优先级。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;// 声明一个类
class Notebook
{// 通过关键字 public 将成员声明为公有成员public:string title = "TwoMoons";string content = "Hello World";
};int main(){// 通过类 Notebook 实例化一个对象Notebook notebook;// 创建一个 Notebook 类的指针Notebook* notebookPtr = ¬ebook;// 通过指针选择复合类型中的成员cout << (*notebookPtr).title << endl;cout << (*notebookPtr).content << endl;system("pause");
}
执行结果
TwoMoons
Hello World
请按任意键继续. . .
箭头运算符
通过指针选择复合类型中的成员较为不便(参考前一个示例),因此 C++ 提供了箭头运算符 -> 。箭头运算符能够使你通过指针访问成员的操作更为简便,并且使用箭头运算符还能够提高程序的可读性。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;class Notebook
{public: string title = "TwoMoons";string content = "Hello World";
};int main(){Notebook notebook;Notebook* notebookPtr = ¬ebook;// 通过箭头运算符选择复合类型中的成员cout << notebookPtr -> title << endl;cout << notebookPtr -> content << endl;system("pause");
}
执行效果
#include <iostream>
#include <string>
using namespace std;class Notebook
{public: string title = "TwoMoons";string content = "Hello World";
};int main(){Notebook notebook;Notebook* notebookPtr = ¬ebook;// 通过箭头运算符选择复合类型中的成员cout << notebookPtr -> title << endl;cout << notebookPtr -> content << endl;system("pause");
}
运算符优先级
对于 ()、->、. 及 * 共四种运算符的运算符优先级如下:
项目 | 描述 |
---|---|
最高优先级 | 小括号 () 及箭头运算符 -> |
次级优先级 | 句点运算符 . |
最低优先级 | 间接寻址运算符 * |
指针
野指针
指向非法内存区域的指针被称为野指针,野指针也被称为悬空指针。产生野指针的一种情况是:声明一个指针但未对该指针执行初始化操作。一个未初始化的指针中保存的地址由 C++ 随机分配。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){int* aPtr;// 向控制台中输出 C++ 分配的随机地址cout << (long long)aPtr << endl;// 向控制台中输出 C++ 分配的随机地址// 中存储的值cout << *aPtr << endl;system("pause");
}
执行效果
16
空指针
在声明指针时,如果你暂时没有可用于初始化该指针的地址,那么你可以将其赋值为 0、NULL 或 nullptr ,存储了这类值的指针被称为空指针。
野指针无法通过 if 语句 检测出来,但空指针可以。使用空指针可以避免无意中对野指针的使用(使用指针前,判断其是否为空指针)。
#include <iostream>
#include <string>
using namespace std;int main(){// 创建三个空指针int* ptr_nullptr = nullptr;int* ptr_0 = 0;int* ptr_NULL = NULL;// 输出指针中存放的内存地址cout << ptr_nullptr << endl;cout << ptr_0 << endl;cout << ptr_NULL << endl;// 对空指针进行判断if(!ptr_nullptr){cout << "指针 ptr_nullptr 为空指针" << endl;};if(!ptr_0){cout << "指针 ptr_0 为空指针" << endl;};if(ptr_NULL){cout << "指针 ptr_NULL 为非空指针" << endl;}else{cout << "指针 ptr_NULL 为空指针" << endl;};system("pause");
}
执行效果
0
0
0
指针 ptr_nullptr 为空指针
指针 ptr_0 为空指针
指针 ptr_NULL 为空指针
请按任意键继续. . .
注:
- 空指针中保存的地址为 0,该地址所对应的内存空间是操作系统所需要的。在大多数操作系统中,C++ 不允许你访问地址 0 中所保存的数据。
- 关键字 nullptr 在 C++ 11 中被提出。如 nullptr 无法正常使用,请检测你的 C++ 编译器是否支持 C++ 11。幸运的是,现在的编译器基本都支持了 C++ 11。
通用指针
通用指针可以接受指向任意数据类型的地址。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){// 声明一个通用指针void* ptr;// 声明变量int num;double db_num;string str;// 赋值ptr = #ptr = &db_num;ptr = &str;system("pause");
}
执行效果
在程序运行的过程中,C++ 并没有抛出错误。
解引用
通用指针并不能通过使用间接寻址运算符 * 实现对指针进行解引用的功能,这将导致 C++ 抛出错误。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){int num = 9;void* ptr = #// 下一行语句将导致 C++ 抛出错误cout << *num << endl;system("pause");
}
分析
C++ 无法对通用指针进行解引用操作是由于 C++ 不知道地址所指向的内存空间中存放着何种类型的数据,这导致了 C++ 不知道如何处理内存空间中的数据。
我们可以在对通用指针进行解引用操作前将指针转换为合适的类型的指针,以告知 C++ 如何处理与目标地址关联的内存空间中存储的数据。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){// 声明通用指针void* ptr;// 声明并初始化变量int num = 9;string first = "Hello World";char a = 'a';// 强制类型转换以实现通用指针的解引用操作ptr = #cout << *(int*)ptr << endl;ptr = &first;cout << *(string*)ptr << endl;ptr = &a;cout << *(char*)ptr << endl;system("pause");
}
执行效果
9
Hello World
a
请按任意键继续. . .
指针的算术运算
加减运算
指针是支持加减运算的,指针加一 并不是指针中保存的地址增加一,增加多少取决于指针所属的类型。
若为 int 类型的指针,则 指针加一 表示指针中保存的地址增加四,这是由于 int 类型的数据占用的内存空间为四个字节。
若为 dobule 类型的指针,则 指针加一 表示指针中保存的地址增加八,这是由于 dobule 类型的数据占用的内存空间为八个字节。
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){int* aPtr;double* bPtr;cout << "【原】" << endl;cout << (long long)aPtr << endl;cout << (long long)bPtr << endl;cout << "【后】" << endl;// 输出对指针进行加一运算后,指针中存储的值cout << (long long)(aPtr + 1) << endl;cout << (long long)(bPtr + 1) << endl;system("pause");
}
执行结果
【原】
16
1850768
【后】
20
1850776
请按任意键继续. . .
注:
- 指针不止可以进行加一运算,指针可以与任何一个整数相加,规律相同。
- 指针进行减法运算得到的结果可以通过加法运算中的规律来进行判断。换个说法就是,指针进行加减运算时,指针中存储的地址的增减变化遵循相同的规律。
自增运算与自减运算
指针还支持自增运算符(包括前置自增运算符与后置自增运算符)及自减运算符(包括前置自减运算符与后置自减运算符)。在将自增运算符与自减运算符作用到指针时,指针中存储的地址的改变与指针进行加减运算所导致的指针中存储的地址的改变所遵循的规律相同。而地址何时自增或自减则由运算符的位置(前置或后置)所决定。
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){int* aPtr;cout << (long long)(aPtr) << endl;cout << (long long)(aPtr--) << endl;cout << (long long)aPtr << endl;cout << (long long)(--aPtr) << endl;cout << (long long)(aPtr) << endl;system("pause");
}
执行结果
16
16
12
8
8
请按任意键继续. . .
比较运算
对 C++ 中的指针使用比较运算符,比较的是指针中存储的地址的大小。存储了更大的地址的指针要大于存储了更小的地址的指针。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){// 声明两个整型指针int* aPtr;int* bPtr;// 向控制台输出指针中存储的地址cout << "【值】" << endl;cout << (long long)aPtr << endl;cout << (long long)bPtr << endl;cout << "【比较】" << endl;// 对指针进行比较操作// 由于运算符优先级的关系,此处使用了括号cout << (aPtr > bPtr) << endl;cout << (aPtr < bPtr) << endl;cout << (aPtr == bPtr) << endl;system("pause");
}
执行效果
【值】
16
12139920
【比较】
0
1
0
请按任意键继续. . .
注:
指针所支持的比较运算符还包括 >=(大于或等于) 及 <=(小于或等于) 。
指针与常量
在某些特殊的情形下,我们可能需要保证指针中保存的内存地址所指向的数据或指针中保存的内存地址不可被改变。要达成这类目标,我们可以将指针声明为指针常量、常量指针或指向常量的指针常量。
指针常量
指针常量可以理解为 指针是常量,通过将指针声明为指针常量可以保证指针中保存的内存地址不被更改。若试图对指针常量中保存的地址进行更改,C++ 将抛出错误。
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){int a = 9;int b = 3;// 将指针声明为指针常量并对该指针执行初始化操作int* const aPtr = &a;cout << (long long)aPtr << endl;// 由于你已将指针声明为指针常量,故不可执行如下语句// (指针中存放的地址不可被改变)。// 否则,C++ 将抛出错误。// aPtr = &b;system("pause");
}
执行结果
6422028
请按任意键继续. . .
注:
- 将指针声明为指针常量的同时,必须对指针进行初始化操作。
- 对于语句(曾出现于上述示例中)
int* const aPtr = &a;
我们可以采用另一种写法:
int const *aPtr = &a;
使用第二种写法后,C++ 虽不会抛出错误,但采用第二种写法将使得指针不再具有指针常量的功能了。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){int a = 9;int b = 3;int const *aPtr = &a;cout << (long long)aPtr << endl;// 若常量指针的功能生效,则下一行 C++ 语句// 将导致 C++ 抛出错误。aPtr = &b;cout << *aPtr << endl;system("pause");
}
执行效果
6422036
3
请按任意键继续. . .
常量指针
常量指针可以理解为 常量的指针,通过将指针声明为常量指针可以保证指针中保存的内存地址所指向的数据不被改变。若试图对常量指针中保存的地址所指向的数据进行更改,C++ 将抛出错误。
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){int a = 9;const int* aPtr = &a;cout << *aPtr << endl;cout << (long long)aPtr << endl;// 由于已将指针声明为常量指针,故不可通对// 常量指针执行解引用操作来修改// 该指针指向的数据。因此不能使用如下语句// &aPtr = 10;// 若使用该语句,C++ 将抛出错误// 虽不能通过对常量指针执行解引用操作来修改// 该指针指向的数据。但可以直接通过相关变量// 修改目标数据。a = 10;cout << a << endl;system("pause");
}
执行效果
9
6422036
10
请按任意键继续. . .
注:
将指针声明为指针常量的同时,必须对指针进行初始化操作。
指向常量的指针常量
通过将指针声明为指向常量的指针常量可以保证指针中保存的内存地址及指针中保存的内存地址所指向的数据不被改变。若试图对指针(指向常量的指针常量)中保存的地址或指针(指向常量的指针常量)中保存的地址所指向的数据进行更改,C++ 将抛出错误。
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){int a = 3;int b = 9;// 将指针声明为指向常量的指针常量const int* const aPtr = &a;cout << (long long)aPtr << endl;// 在该示例中,对于指向常量的指针常量// 你不可使用如下语句。否则,C++ 将抛// 出错误。// *aPtr = 9;// aPtr = &b;system("pause");
}
执行效果
#include <iostream>
#include <string>
using namespace std;int main(){int a = 3;int b = 9;// 将指针声明为指向常量的指针常量const int* const aPtr = &a;cout << (long long)aPtr << endl;// 在该示例中,对于指向常量的指针常量// 你不可使用如下语句。否则,C++ 将抛// 出错误。// *aPtr = 9;// aPtr = &b;system("pause");
}
注:
- 将指针声明为指向常量的指针常量的同时,必须对指针进行初始化操作。
- 对于语句(曾出现于上述示例中)
const int* const aPtr = &a;
不可使用如下语句代替上述语句。C++ 将由此抛出错误。
const int const *aPtr = &a;
指针与数组
数组标识符与指针
表示数组的变量本身就是一个指针,存储着数组中首个元素所在的内存地址。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){// 声明并初始化一个数组int arr[] = {1, 2, 3, 4};// 将数组中的首元素所处的内存地址存储到指针中int* arrPtr = arr;cout << (long long)arr << endl;cout << (long long)arrPtr << endl;system("pause");
}
执行结果
6422016
6422016
请按任意键继续. . .
注:
- 用于存储数组等复合类型(对象、结构体等)的变量或常量所保存的值为一个地址。
- 你不可将地址运算符应用于表示数组等复合类型的变量或常量中,C++ 将为此抛出错误。
- 用于存放数组地址的标识符为一个 指针常量 ,你不可改变该标识符中存储的内存地址。对此,请参考如下示例:
#include <iostream>
#include <string>
using namespace std;int main(){int arr[] = {1, 2, 3, 4}; int num = 1;// 下方语句将导致 C++ 编译器抛出错误// arr = #// 上方语句用于将变量 num 的内存地址存储到数组标识符 arr 中system("pause");
}
数组元素与指针
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){int arr[] = {1, 2, 3, 4}; int num = 1;cout << "arr 首元素的内存地址\t" << (long long)arr << endl;cout << "arr 数组中第三个元素的内存地址\t" << (long long)&arr[2] << endl;// 尝试通过指针运算使用 arr 标识符获取 arr 数组// 中第三个元素的内存地址。cout << (long long)(arr + 2) << endl;system("pause");
}
执行效果
arr 首元素的内存地址 6422016
arr 数组中第三个元素的内存地址 6422024
6422024
请按任意键继续. . .
边界检查
Python 等语言将对数组执行边界检查,当使用了非法索引后,程序将抛出错误。对此,请参考如下示例:
# 定义一个 Python 列表(与 C++ 中的数组类似)
arr = [1, 2, 3, 4]# 输出数组 arr 中的第一个元素
print(arr[0])
# 输出数组 arr 中的第五(索引越界)个元素
print(arr[4])
执行结果
由于数组 arr 所能支持的最大索引为 3 ,在上述代码段中却使用了索引 4 ,由此发生了索引越界。Python 在执行代码 print(arr[4]) 检测到了该问题,立即抛出了错误。
1
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
Cell In[1], line 75 print(arr[0])6 # 输出数组 arr 中的第五(索引越界)个元素
----> 7 print(arr[4])IndexError: list index out of range
C++ 对数组不会执行边界检查,这意味着我们可以使用更大范围内的任意整数值作为数组的索引,而 C++ 将不会抛出错误。对此,请参考如下示例:
举个栗子
#include <iostream>
#include <string>
using namespace std;int main(){// 声明并初始化一个数组int arr[] = {1, 2, 3, 4};// 将数组中的元素输出cout << arr[0] << endl;cout << arr[4] << endl;system("pause");
}
执行效果
1
15678800
请按任意键继续. . .
相关文章:

C++ 之指针
文章目录参考描述指针运算符地址运算符奇偶分体指针的创建间接寻址运算符句点运算符运算符优先级问题箭头运算符运算符优先级指针野指针空指针通用指针解引用分析指针的算术运算加减运算自增运算与自减运算比较运算指针与常量指针常量常量指针指向常量的指针常量指针与数组数组…...

数据结构与算法---JS与栈
前言js里,是没有栈这种原生的数据结构。但是我们可以通过自定义创建栈类,来实现对添加/删除元素时更多的控制。创建栈类// 初始化一个基于数组的栈类 class Stack {constructor() {this.items [];} }为什么我们要选择数组作为栈类的存储数据类型&#x…...

HDLBits: 在线学习 SystemVerilog(二十三)-Problem 158-162(找BUG)
HDLBits: 在线学习 SystemVerilog(二十三)-Problem 158-162(找BUG)HDLBits 是一组小型电路设计习题集,使用 Verilog/SystemVerilog 硬件描述语言 (HDL) 练习数字硬件设计~网址如下:https://hdlbits.01xz.ne…...

国外SEO升级攻略:如何应对搜索引擎算法变化?
搜索引擎优化(SEO)是一个动态的领域,搜索引擎的算法经常会发生变化,这意味着SEO专业人员需要保持更新的技术知识和策略, 以适应变化并提高网站的排名。 以下是一些应对搜索引擎算法变化的升级攻略: 创造…...

X.509证书
证书格式ASN.1是一种抽象的数据结构,描述了复杂的对象,以及对象之间的关系。证书本质上是一个文件,需要一种专门的格式,才能在互联网中传输,证书需要通过一个规则将ASN.1转换为二进制文件,这就需要对证书以…...

高等数学——微分方程
文章目录概念一阶微分方程可降阶的微分方程高阶线性微分方程线性微分方程解的结构常系数齐次线性微分方程常系数非齐次线性微分方程概念 微分方程:含有未知函数的导数或微分的方程称为微分方程。微分方程的阶:微分方程中所出现的未知函数最高阶导数的阶…...

JAVA小记-生成PDF文件
项目场景: 例如:项目中需要生成PDF文件 项目使用情况 1、引入pom.xml <!--pdf相关依赖--> <dependency><groupId>com.itextpdf</groupId><artifactId>itextpdf</artifactId><version>5.5.13</version> </dependency>…...

Noah-MP陆面过程模型建模方法与站点、区域模拟
陆表过程的主要研究内容以及陆面模型在生态水文研究中的地位和作用 熟悉模型的发展历程,常见模型及各自特点; Noah-MP模型的原理 Noah-MP模型所需的系统环境与编译环境的搭建方法您都了解吗?? linux系统操作环境您熟悉吗&…...

全国青少年软件编程(Scratch)等级考试一级真题——2019.9
青少年软件编程(Scratch)等级考试试卷(一级)分数:100 题数:37一、单选题(共25题,每题2分,共50分)1.小明在做一个采访的小动画,想让主持人角色说“大家好!”3秒…...

第十四届蓝桥杯三月真题刷题训练——第 6 天
目录 第 1 题:星期计算 问题描述 运行限制 代码: 第 2 题:考勤刷卡 问题描述 输入格式 输出格式 样例输入 样例输出 评测用例规模与约定 运行限制 代码: 第 3 题:卡片 问题描述 输入格式 输出格式 样…...

安装MySQL数据库8.0服务实例
前言 之前尝试去安装了MySQL5.7的社区版本,今天来安装MySQL8.0的版本,并且以两种方式进行安装,一个是通过RPM包的安装,另一个则是编译的方式。 一. 前期准备 查看服务器IP [rootlocalhost ~]# hostname -I 192.168.161.166 19…...

数据的存储--->【大小端字节序】(Big Endian)(Little Endian)
⛩️博主主页:威化小餅干📝系列专栏:【C语言】藏宝图🎏 ✨绳锯⽊断,⽔滴⽯穿!一个编程爱好者的学习记录!✨前言计算机硬件有两种存储数据的方式:大端字节序——Big Endian小端字节序——Little …...

软件测试备战近三银四--面试心得
自信即巅峰,对待面试官就像和儿子一样,耐心!耐心!耐心!...

《Linux运维实战:ansible中的变量定义及以及变量的优先级》
一、配置文件优先级 Ansible配置以ini格式存储配置数据,在Ansible中⼏乎所有配置都可以通过Ansible的Playbook或环境变量来重新赋值。在运⾏Ansible命令时,命令将会按照以下顺序查找配置⽂件。 # ⾸先,Ansible命令会检查环境变量,…...

useEffect 通过 form.getFieldValue(‘xxx‘) 监听 Form表单变化
场景 子组件中,某一个表格的数据需要依赖于上级组件的某一个表单元素值进行计算。 毫无疑问,首先想到的肯定是监听 form 表单中元素的值,使用 useEffect 监听表单的变化,当值发生变化时,重新计算渲染。 首先说下我的…...

【晓龙oba出品 - 黑科技解题系列】- 最小操作次数使数组元素相等
思路 算法归根到底就是找规律的游戏,我们首先来看一个现象: 以数组nums [1,2,3,4,5]为例 当我们将数组排序后,可以知道最小值为1,最大值为5,此时我们需要四次运算可以使最小值与最大值相等: 第一次:2,3,4,…...

Activity的启动和结束
onCreate:创建活动。此时会把页面布局加载进内存,进入了初始状态。onStart:开启活动。此时会把活动页面显示在屏幕上,进入了就绪状态。onResume:恢复活动。此时活动页面进入活跃状态,能够与用户正常交互&am…...

利用业务逻辑+OB分布式特性优化SQL
最近某人社局核心数据库上了OB,经常出现性能问题 某人社与我司合作多年,非常信任我司在数据库的专业能力,邀请我司过去看看能否提供帮助 与OB驻场工程师合作,抓取了一天的TOP SQL,跑得慢的SQL有几十条(注意只是某一天的…...

哈希表
文章目录什么是哈希问题引入哈希函数直接定址法除留余数法 (常用、重点)哈希冲突哈希冲突的解决方法闭散列开散列unordered_map && unordered_set 封装实现哈希的应用位图布隆过滤器哈希经典面试题哈希切分位图应用布隆过滤器什么是哈希 在上一…...

基于Halcon的MLP(多层感知神经网络)分类器分类操作实例
一、介绍 人工神经网络(Artificial Neural Network,ANN)简称神经网络(Neural Network,NN)或类神经网络,是一种模仿生物神经网络的结构和功能的数学模型或计算模型,用于对函数进行估计或近似。 MLP神经网络是一种基于神经网络、动态的分类器。MLP分类器使用神经…...

VR全景博物馆,打造7*24小时的线上参访体验
导语:博物馆作为人们了解历史、文化和艺术的重要场所,现在可以通过VR全景技术来进行展览,让参观者身临其境地感受历史文化的魅力。本文将介绍博物馆VR全景的特点、优势,以及如何使用VR全景技术来丰富博物馆的展览和教育活动。什么…...

Go 数据类型
基础数据类型 类型长度(字节)默认值说明bool1falsebyte10uint8,取值范围[0,255]rune40Unicode Code Point,int32int,uint4或者8032位或64位操作系统int8,uint810-128~127,0-255int16,uint1620-32768~32767,…...

Mybatis-Plus学透?一篇足够(持续更新中)
01、Mybatis-Plus入门 一、简介 MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。如果你想对自己的项目进行技术升级,不妨尝试将mybatis换成Mybati…...

船用燃料油市场调研报告-主要企业、市场规模、份额及发展趋势
船用燃料油市场报告主要研究:市场规模: 产能、产量、销售、产值、价格、成本、利润等行业分析:原材料、市场应用、产品种类、市场需求、市场供给,下游市场分析、供应链分析等竞争分析:主要企业情况、市场份额、并购、扩…...

python趣味编程-奥赛罗游戏
在上一期我们用Python实现了一个高速公路汽车游戏的游戏,这一期我们继续使用Python实现一个简单的奥赛罗游戏,让我们开始今天的旅程吧~ 在Python中使用Turtle实现的奥赛罗游戏 在Python中使用Turtle的简单奥赛罗游戏 是一个以 Python 为程序设计语言的项…...

经典卷积模型回顾13—ResNetXt实现图像分类(matlab)
ResNetXt是ResNet的变种,在ResNet基础上引入了"split-transform-merge"的思想,旨在进一步提升模型的性能和准确率。ResNetXt模型的核心思想是通过对输入进行分组,然后对每个分组进行不同的变换,最后再将变换后的结果合并…...

Spring学习——Maven进阶
分模块开发与设计 创建模块 书写模块代码 通过maven指令安装模块到本地仓库(install指令) 在pom.xml中导入坐标执行maven的install命令将模块安装到本地maven仓库 团队内部开发可以发布模块功能到团队内部可共享的仓库中(私服) 依赖管理 依赖指当前项目运行所需…...

第23篇:基础知识-Java Switch Case
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。 switch case 语句语法格式如下: switch(expression){ case value : //语句 break; //可选 case value : //语句 break; //可选 //你可以有任意数量的…...

Go 实现多态和 参数的动态个数及动态类型
引子 go语言作为静态(编译期类型检测)强类型(手写代码进行类型转换)语言, 要想实现 动态语言的鸭子类型的调用方法,做到 一个入参是不同类型,还是有些麻烦的; 需求 希望写代码时像python一样的鸭子类型,不用管参数类型,都可以调用同一个方法;希望 入参像python一样 能够在 个…...

vue 指令
Vue 提供了很多指令,如:v-model, v-show,v-if等等,有利于应付开发时出现的各种情况。Vue 也提供了自定义指令,有利于开发者将某些通用性功能封装成一个指令,进行全局或局部注册。如:复制指令&am…...