本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这是本文档旧的修订版!
第 2 章笔记
10
x = 10
,x
就是对象sizeof()
测量std::numeric_limits
查找,范围为 $2^{bit length}$32
或者 64
位数据。如果存储的数据位置处于两次读取位置的之间,那么需要两次读写才可以完整的读取存取的数据。这种情况被称为内存对齐不良。这种情况可以通过安排数据的位置进行改良。alignof(type)
#include <limits>
int main(int argc, char const *argv[])
{
int x{0};
std::cout << "Size of: " << sizeof(x) << std::endl;
std::cout << "Int min: " << std::numeric_limits<int>::min() <<std::endl;
std::cout << "Int max: " << std::numeric_limits<int>::max() <<std::endl;
std::cout << "Alignof int" << alignof(int) << std::endl;
return 0;
}
char
, whcar_t
, char16_t
, char32_t
):char 以外的 char 是针对其他编码的特殊字型的;比如 Unicode
只有 unsigned
指代 unsigned int
unsigned char c1;
signed char c2;
int32_t
(32 bit, 4 byte) (fixed width integer types)int
): 十进制 / 8 进制 / 16 进制3.14
char
类型,比如转义字符 \n
, \x4d
char[]
类型,以 \0
作为结尾。因此,Hello
的长度是 6
位,而不是 5
位。true
/ false
nullptr
,nullptr_t
类型
// 指定 float 类型的字面值
float x = 1.3f;
// 指定一个 unsigned long long 类型的字面值
unsigned long long y = 2ULL;
C++ 11 允许用户自定义字面值的类型。该定义通过重写运算符 "" 进行定义。该功能可以方便我们定义一些单位(比如时间 / 重量)等等。下面的字面值代表了将接收到的 double 乘以 2 再转化为 int 的结果
int operator "" _customType(long double x)
{
return (int)x * 2;
}
int main(int argc, char const *argv[])
{
//using _customType as an literal type
int x = 3.14_customType;
std::cout << x << std::endl;
}
需要注意的是,User-defined literals 能接收的参数类型是有限的(引入的函数接收的类型是有限的)。
extern
:实现的是定义只有一处,声明可以有多处的概念,用于外部文件引用实现文件中的定义。
为什么要使用 extern 关键字?
假设我们有两个文件需要一起编译。A 中使用调用 B 中已经定义的变量 x。如果没有 extern
,那么会出现两种情况:
因此,如果希望在 A 中使用 B 中定义的 x,那么必须使用 extern
关键字。extern
会让编译器将定义视作外部文件变量在本地的声明,从而达到我们希望的效果:
//source.cpp
int x;
//main.cpp
extern int x;
int main()
{
std::cout << g_x << std::endl;
}
extern 引入的变量如果进行初始化,那么就会从声明转化为定义。
0
//direct init
int x(10);
//copy init
int x = 10;
//list init
int x{10};
std::cmp_XXX
库(C++ 20)
//p points to the address of the val
int* p = &val;
&
*
:不能访问没有内容的地址(0
地址)一般情况下会给一个 0
地址来保证错误的解引用一定会报错:
// 指针指向内容随机,解引用结果无法预测
int *p;
// null pointer
// 访问报错,但是内容稳定,方便查错
// 缺点是存在整型到指针的隐式转换
int *p = 0;
int *p = NULL;
// 防止隐式转换,C++ 11提供的 nullptr 指针对象
int *p = nullptr;
++ / –
:移动到下一个(上一个)指向的位置,距离取决于指针指向变量的类型==
:判断两个两个指针是否指向同一个内存单元
int x = 42;
int *p = &x;
int **pp = &p;
指针是对对象的间接引用:
false
if (p)
方式来书写条件判断指针可能存在的问题:指向的对象为空或者非法。采用引用是另外一个较好的选择。引用是变量的别名:
int x = 42;
//& is an type modifier here
int &refX = x;
int x = 0;
int y = 1;
int *ptr = &x;
//打印 ptr 结果相同,但实际上是不同的操作
//改变 x 所在内存的值为 y, 1 in x
*ptr = y;
//改变了 ptr 指向的位置,从 x 到 y,1 in y
ptr = &y;
从上面的例子来看,引用只能改变其指向内存地址中的内容,而不能改变其指向的位置。这要求引用在初始化的时候必须绑定一个实际的对象(的地址)。
需要注意非法引用的问题:通过函数返回局部变量的引用可能出现问题。
int* &refPx = ptr;