栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C++

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C++

Chapter 3 数组、vector与字符串 3-1 数组的引入
# include 
# include 

int main()
{
    int a;//int
	int b[10]; //int[10]

	std::cout << std::is_same_v << 'n';//输出为1
}
int x;
std::cin >> x;
int b[x];		//该表达式不合法,类型原本应为int[x],但在编译器内无法处理该x,x是在编译之后地运行期输入的
// variable length array C++

int和int[1]是不同的类型,尺寸上相同,但是操作是不同的

数组初始化
int b[3]; //缺省初始化
int b[3] = {1,2,3}; // 聚合初始化(aggregate initialization)
int b[3] = {1,2}; // 前两个元素用给出元素初始化,最后一个用0初始化
int b[3] = {}; // 用0初始化所有元素
int b[] = {1,2,3}  // decltype(b) == int[3]
int b[]; // 不合法
# include 

int main()
{
	auto b = {1,2,3};
	std::cout << typeid(b).name() <
}

数组不支持复制

int b[3] = {1,2,3};
auto a = b;// a的类型为指针
auto& a = b;// a的类型为int(&)[3]

b[3]为内建数组,考虑易用性,有vector、string

char str[] = "Hello"; //str为char[6]类型
char str[] = {'H','e','l','l','o'}; //str为char[5]类型
数组的复杂声明 指针的数组
int x1;
int x2;
int x3;
int* a[3] = {&x1,&x2,&x3}; // a中包含三个元素,每个元素都是指针
数组的指针
int b[3];
int (*a)[3] = &b; // a是一个指针,指向一个包含三个元素的数组
std::cout << std::is_same_v << std::endl;//输出结果为1
声明数组的引用
int b[3];
int (&a)[3] = b;

C++当中不能定义引用的数组;

数组中的元素访问
int a[3] = {1,2,3};
// l-value:locator value--有地址的值,数组是左值
std::cout << a[0] << std::endl;//输出结果为1
//解释左值:
const int x = 3;
std::cout << std::is_same_v << std::endl;//(x)表示x是一个表达式,此时输出为0
std::cout << std::is_same_v < 
int a[3] = {1,2,3};
auto b = a; //--->a作为右值,隐式转换为int*,指向a中的第一个元素a[0]所在的地址

x[y]—>会被翻译为*((x)+(y)),即x+y的解引用,需要防止数组溢出

3-2 从数组到指针 数组到指针的隐式转换
int a[3] = {1,2,3};
auto b = a; // decay
// sizeof和decltype等不会产生隐式转换
// 隐式转换会丢失部分类型信息
// 可以通过声明引用来避免隐式转换
auto& b = a; //--->不产生隐式转换,int(&)[3]

注意,不要用extern指针来声明数组

# include 

void fun();
extern int* array;
int main(){
    std::cout << array[1] << std::endl;
}
//source.cpp
# include 

int array[4] = {1,2,3,4};

void fun()
{
    std::cout << array << std::endl;
}
// 运行错误
// 不是编译错误:每一个cpp都没有问题
// 不是链接错误:main.cpp.o与source.cpp.o没有类型信息
// 为什么运行的时候会报错?
// array打印出来是一个十六进制的数字--->指针
// fun()函数打印的地址和main函数打印的地址不同
// main()会打印出array里面的数
// fun()会打印数组的首个元素地址
// 可行的方案
# include 

void fun();
extern int array[];
int main(){
    std::cout << array[1] << std::endl;
}
//source.cpp
# include 

int array[4] = {1,2,3,4};

void fun()
{
    std::cout << array << std::endl;
}

Unknown Bounded Array 声明:
在一个程序里面需要用,在主程序里面需要声明,但不关注该数组的size

extern int array[]; —> 不完整类型

获得指向数组开头和结尾的指针
# include 

void fun();
extern int array[];

int main(){
    int a[3] = {1,2,3};
    //(&a[0])/a指向数组开头的指针
    std::cout << a + 3 << ' ' << &(a[3]) std::endl;
    std::cout << std::begin(a) < 
指针算数 
int a[] = {1,2,3};
auto ptr = a;
auto ptr2 = a + 3;
// 加减
ptr = ptr + 1; // 指针指向下一个int*

// 比较
std::cout << (ptr == ptr2) << std::endl; // 指向相同指针的时候可以做比较,但是指向不同数组的时候不建议

// 求距离
int distance = ptr2 - ptr;

// 解引用
std::cout << *ptr << std::endl;

// 指针索引
std::cout << (ptr) << std::endl;
3-3 其他操作 求元素个数操作
int a[3];

// 方法1:sizeof()  C当中就已经引入,但存在不便(如类型更新)
std::cout << sizeof(a) / sizeof(int) << std::endl;

// 方法2:std::size  the best method
std::cout << std::size(a) << std::endl;

// 方法3:end - begin  不太好,会增加运行期的负担
std::cout << std::cend(a) - std::cbegin(a) << std::endl;
元素遍历 基于元素个数遍历
int main(){
    int a[3] = {2,3,4};
    
    size_t index = 0;
    while (index < std::size(a))
    {
        std::cout << a[index] << std::endl;
        index = index + 1;
    }
}
基于©begin/©end遍历
int main(){
    int a[3] = {2,3,4};
    
    auto ptr = std::cbegin(a);
    while (ptr != std::cend(a))
    {
    	std::cout << *ptr << std::endl;
    	ptr = ptr + 1;
    }
}
基于range-based for循环
int main(){
    int a[3] = {2,3,4};
    
	for (int x : a)
	{
		std::cout << x << std::endl;
	}
}

C++ insights:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-BRt6JwdE-1652760807791)(C:UsersquanyAppDataRoamingTyporatypora-user-imagesimage-20220516200617226.png)]

3-4 C字符串
# include 

int main()
{
	char str[] = "Hello"; // char[6] numm-terminated string
    auto ptr = str; // char*
    // 遍历到''结束
    // C语言还提供了:strlen、strcmp来支持C字符串相关操作
    std::cout << strlen(str) << std::endl;
}

C字符串需要’’的支持

3-5 多维数组

多维数组的本质是数组的数组

int a[3][4]; // a[3]-->每个里面包含一个int[4]
int x2[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int x3[3][4] = {1,2,3,4,5};
多维数组的索引与遍历
int x2[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};

x2[0][3]; // 索引
// 遍历方式1
for (auto& p : x2)
{
    for (auto q:p)
    {
        std::cout << q << 'n';
    }
}
// 遍历方式2
size_t index0 = 0;
while (index0 < 3)
{
    size_t index1 = 0;
    while (index1 < 4)
    {
        std::cout << x2[index0][index1] << std::endl;
        index1 = index1 + 1;
    }
    index0 = index0 + 1;
}
// 遍历方式3,推荐进行x[0][0~3] x[1][0~3] x[2][0~3]遍历
size_t index1 = 0;
while (index1 < std::size(x2[0]))
{
    size_t index0 = 0;
    while (index0 < std::size(x2))
    {
        std::cout << x2[index0][index1] < 

【问题】为何不能用range-based for进行遍历?

3-6 vector

C++标准库中的一个类模板,模拟数组

序列容器,更侧重易用性

# include 
# include 

int main()
{
    int a[3];
    int b[3] = a;//报错
	std::vector x; // vector
    std::vector y;
    y = x;//不会报错
    
}

vector可以复制,可以在运行期动态改变元素个数(付出性能成本)

std::vector = {1,2,3}; // 聚合初始化
std::vector = x(3);
std::vector = x(3,1); // {1,1,1}
std::vector = x{3,1}; // {3,1}

其他方法

// 计算元素个数
std::cout << x1.size() << std::endl;
// 判断是否为空
std::cout << x1.empty() << std::endl;
// 添加元素
x1.push_back(2);
// 删除元素
x1.pop_back(); // 弹出最后一个元素
// vector的比较
std::cout << (x1 == x2) << std::endl;
std::cout << (x1 < x2) << std::endl; // 按元素次序进行比较,从头开始,如果x1的第一个元素小于x2的第一个元素,就会返回为1,如果相等,比较下一个元素

vector的遍历

std::vector = {1,2,3};
std::cout << x1[2] << std::endl; //返回3
std::cout << x1.at(2) << std::endl; //如果越界,会再运行期报错
auto b = std::begin(x1); // x1.begin()
auto a = std::end(x1); // x1.end()
while (b != x1.end())
{
    std::cout << *b << std::endl;
    b = b + 1;
}
// 或者
for (auto val : x1)
{
    std::cout << val << std::endl;
}

std::begin(x1)不再是指针,而是迭代器

*b;--->解引用
b[1] --->*(b + 1) //下标访问
b = b + 1;---> 移动
std::cout << a - b << std::endl;// 两个相减求距离

vector相关的其他内容

// 迭代器失效
std::vector = {1,2};
auto b = std::begin(x1); // x1.begin()
auto a = std::end(x1); // x1.end()
x1.push_back(3); // 可能b和a就不再有效了

多维vector

std::vector> x;
x.push_back(std::vector());
x[0].push_back(1);
std::cout << x[0][0] << std::endl;
std::vector x;
std::cout << x.size() << std::endl;

std::vector* ptr = &x;
std::cout << (*ptr).size << std::endl;
std::cout << ptr->size() << std::endl; // 上下相同
3-7 string

是C++标准库中定义的一个类模板特化别名,用于内建字符串的替代品

# include 
# include 

int main()
{
	std::string x = "Hello world";
	std::string y = x; // std::string y(x);
	y = y + '!';
	std::string z(3,'a');
}
//支持size/empty
//支持比较
//支持赋值
//支持拼接
//支持索引
//可转换为C字符串
std::string y("Hello");
auto ptr = y.c_str(); // 转换为C字符串
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/893028.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号