本 Wiki 开启了 HTTPS。但由于同 IP 的 Blog 也开启了 HTTPS,因此本站必须要支持 SNI 的浏览器才能浏览。为了兼容一部分浏览器,本站保留了 HTTP 作为兼容。如果您的浏览器支持 SNI,请尽量通过 HTTPS 访问本站,谢谢!
这是本文档旧的修订版!
第 3 章笔记
int a; //int
int b[10]; // int[10]
size_t
(converted expression,比如浮点就不行)
int x;
std::cin >> x;
//不合法
//类型由编译器决定,但长度要在运行期才能得到
//编译器无法推断出b[x] 的类型
int b[x];
//合法
constexpr short y = 3;
int c[y];
–pedantic-errors
tag 来支持 variable length array。但这样做是有风险的,因为该功能是 complier denpend。除此之外,某些必须在编译器完成的功能也不能使用该类类型做为参数,比如 decltype(b)
int b[3]; //default int
int c[3] = {1, 2, 3}; // int[3], aggregate init
int cn[] = {1,2, 3}; //int[3]
int d[3] = {1,2} // partially aggregate init, 1,2,0
auto
:auto 会将 {}
视作 initialization_list
//char[6] 简化定义写法,会自动添加 ''\0'' 表示结束
char str[] = "hello";
//char[5] 完整定义写法,但不会为末尾添加 ''\0''
char str[] = {‘h’, 'e', 'l', 'l', '0'};
//a[3] 是有3个元素为指针的数组
int* a[3];
//注意括号
//a 是指针,指向 int[3]
int (*a) [3];
//a 是引用,指向 int[3]
int b[3];
int (&a) [3] = b;
引用不支持聚合初始化。C++ 中不支持元素为引用的数组。从概念上来说,引用不是对象。数组要求元素使对象,因此没有元素为引用的数组。
a[0]
[]
操作符x[y]
,且 x
, y
都是 Built-in 类型时,x[y]
被解析为 *(x+y)
,也就是转换为指针,再解引用。
int a[3] = {1,2,3};
auto b = a;
//int(&)
decltype(b)
//int*
a;
//int*
b;
//int, *(b+0)
b[0]
可以使用 decltype 来判断表达式是否是左值。
// decay, b 是 int* 类型
int a[3];
auto b = a;
//不会 decay 的范例
//decltype 返回的是数组的类型
// int[3]
decltype(a);
// int size * 3
sizeof(a);
// b 是 Int(&)[3] 类型
// 此时长度信息没有丢失
auto& b = a;
extern
指针声明数组
//声明数组
//不能使用 extern 指针
extern int array[4];
//illegal
//runtime error
extern int* array;
为什么不能这么做?
很多情况下,长度信息需要反复的修改。如果在声明的时候带上长度信息,那么每次更改 array 的长度都必须同时去声明中改变 array 的长度。因此很多情况下会使用指针替代数组。但 extern
不能直接使用指针代替数组。来看看下面的例子:
//source.cpp
int array[4] = {1,2,3,4};
void fun()
{
std::cout << array << std::endl;
}
//main.cpp
extern int* array;
void fun();
int main()
{
fun();
std::cout << array << std::endl;
}
// output
// 两个 array 的输出不一样
0x7ff718ee3000
0x200000001
问题出在哪里?
*(array + step)
array
打印出来是一个 16 进制的数。array
进行打印,那么 array
是一个地址</WRAP>