[深蓝学院] C++ Week 3: 数组

本文详细探讨了C++中的数组,包括初始化、元素访问、数组到指针的转换,以及C字符串和多维数组。同时,介绍了Vector的易用性和灵活性,以及String的使用。强调了数组与Vector的差异,以及数组大小不可变和不支持复制的原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文是深蓝学院c++课程的个人笔记和感悟,仅供学习参考。

1. 数组

1.1 数组初始化

1.1.1 可变长度的数组?

  • c++里面数组的初始化一般来说必须给定一个确切的大小,比如int b[3]
  • 如果用variable length的数组,比如int b[x],原则上是不可以的。
    因为系统在编译(compile)的时候没办法知道x这个变量是多少,那就没办法分配内存空间; 只有在运行(run)的时候才可能知道x是多少。

1.1.2 缺省值

  • 在main函数里面的缺省值是随机的。
  • 在main函数外面的全局定义的数组,则全部初始为0。
#include <iostream>

int b[3];
int main() {
    int a[3];

    std::cout << a[0] << std::endl;
    std::cout << b[0] << std::endl;

    return 0;
}

---result----
a[0]: 21919 (random)
b[0]: 0

1.1.3 聚合初始化

  • 如果3个长度的数组,只给它2个数值: int a[3] = {1,2}。那么a[3]自动初始化为0

1.1.4 不能用auto来声明数组类型

auto a = {1,2,3}中a的类型其实是std::initializer_list[3]

1.1.5 数组不能复制

c++不支持数组直接复制:

int a[] = {1,2,3}
int b = a; // X,错误!

问:为神马c++不支持数组的复制呢?
答:因为c++是一种注重性能的语言,复制得开辟好多空间喔~

1.1.6 字符串的初始化

char str[] = "hello" // char[6]
char str[] = "h", "e", "l", "l", "o" // char[5]

神奇!为神马第二种方式的str变量变成char[5],而第一个是char[6]呢?
原因: c/c++会在第一种初始化的字符串后面“偷偷地”加一个'\0'字符,用来判断字符串的结束。

1.2 数组的复杂声明

1.2.1 指针的数组 和 数组的指针

int* data[3] = {&x1, &x2, &x3}; //data是一个包含三个int*指针的数组
int (*data)[3] = {x1, x2, x3};  //data是一个int[3]数组的指针

1.2.2 声明数组的引用

int (&data)[3] = {x1, x2, x3}

1.3 数组的元素访问

1.3.1 左值和右值

数组对象是一个左值

1.3.2 转换成指针类型

1.3.3 x[y] -> * ((x)+(y))

  • a[1]其实等于1[a]: *((1)+(a))
  • 如果超出界限,就会出现内存访问越界,但是非常非常危险,因为会访问到越界的那个地址上的数据,而不会像python给你报错。

1.4 从数组到指针

1.4.1 数组和指针的隐式转换

在这里插入图片描述

  • 数组和指针如果用auto,是会发生隐式转换的。本来右边是个数组,auto之后就变成指针了。因为a[1] = *((1)+(a)),数组其实也是需要基于地址的访问。
  • 但是,数组和指针的内存结构其实非常不同,如上图所示:
    • 数组保存的直接就是数据内容
    • 指针保存的是指向的地址
  • extern int array[]用extern的时候一定不能用指针哈,不然会把array前8个字节的数据(而且根据高位低位的规则,后4位放在前面)当成指针指向的地址… 完全跑飞了
  • std::cbegin(array)
  • std::cend(array)这里的c是指const,防止不小心更内容。

1.5 数组的其他操作

1.5.1 数组所含元素的个数

  • sizeof(array) / sizeof(int)
  • std::size()
  • std::cbegin() and std::cend()

但对于std::vector来说,sizeof(vector)只能返回一个固定值24(根据编译器而定)。因为std::vector通常由三个8 byte的Pointer(指针)组成:

  • begin of vector
  • end of vector
  • end of reserved memory for vector (i.e. vector’s capacity)

1.5.2 遍历数组元素

  • 基于元素个数
    for(int i; i<std::size(array); i++)
  • 基于pointer
auto ptr = std::cbegin(a)
while(ptr != std::cend(a))
{
   ptr = ptr + 1;
}
  • 基于range-based for循环
for(int x: a){
	std::cout << x << std::endl;
}

1.6 C字符串

c字符串用strlen可以求出长度,但是一定要注意,在单个定义字符串的字符时,最后结尾要加一个\0来结尾。不然其实程序是pointer一直在内存里面找下一个字符,直到找到\0才会截止。

include <cstring>

char str1[] = "Hello";
char str2[] = ['H', 'e', 'l', 'l', 'o', '\0'];
auto ptr = str1;
std::cout << strlen(str1) << std::endl;
std::cout << strlen(str2) << std::endl;
std::cout << strlen(ptr) << std::endl;

1.7 多维数组

//一重大括号 vs 多重大括号
int x2[3][4] = {1,2,3,4,5,6};
int x2[3][4] = {{1,2,3,4}, {5,6}};
// (int, int, int, int), (int, int, int, int), (int, int, int, int)

// 自动补0
int x3[][3] = {1,2,3,4}
// 系统会直接给补全,初始化为X3[2][3]

int x4[][4] = {{1,2,3}, {5,6,7,8}}
// 自动会把第一排最后一个补0,{1,2,3,0}

2. Vector

2.1 Vector的易用性

  1. Vector可以复制,但Array不可以
  2. Vector可以在运行期改变元素个数,但Array不可以

相比之下,内建数组更加注重性能。

2.2 Vector的初始化

std::vector<int> a(3,1); //3个元素,每一个的数值都是1
std::vector<int> a{3,1};
std::vector<int> a = {1,2,3,4};
// {1,2,3} 表示一个std::initializer_list<T> 初始化列表

2.3 Vector的方法

std::vector<int> x1;

// Vector的基本方法
x1.size()
x1.empty()
x1.push_back(val)
x1.pop_back()

// Vector的比较
x1 == x2
x1 < x2 // Vector的比较是按照priority来: 
		// 先看第一位是不是相同,如果不同,那直接就用第一位的结果作为最终大小比较的结果啦!

// Vector中元素的遍历
x1[index]
x1.at(index) // 建议使用vec.at(idx),因为这样如果idx>size,系统会报错。

// 指针访问Vector
std::vector<int>* ptr = &x1;

// 指针访问Vector所包含的Method: -> 以及 .
(*ptr).size()
ptr->size()

2.4 多维Vector

int a[3][4];
//Array的a[0]和a[1]的维度都是一样的

std::vector<std::vector<int>> vec = {{1,2,3}, {4,5}};
//Vector可以不同维度的元素长度是可以不一样的

3. String

std::string x("Hello String");
std::string y("Hello");

y = y + "Wei";
//std::string是可以支持拼接的,但是内建字符串char[]是不能拼接的。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值