【C++】第八节—string类(上)——详解+代码示例

news2025/4/10 7:13:32

 hello,又见面了!

云边有个稻草人-CSDN博客

C++_云边有个稻草人的博客-CSDN博客——C++专栏(质量分高达97!)

菜鸟进化中。。。

目录

一、为什么要学习string类?

1.1 C语言中的字符串

1.2 面试题(暂不做讲解)

二、 标准库中的string类

2.1 string类(了解)

2.2 auto和范围for

2.3 string类的常用接口说明(注意下面我只讲解最常用的接口)

2.3.1 string类对象的常见构造

2.3.2 string类对象的容量操作

2.3.3 string类对象的访问及遍历操作

【operator[ ]】 

【遍历begin+end+迭代器第一弹】

【迭代器第二弹】

【const对象的迭代器和反向迭代器】 

2.4 string类对象的Element access(元素存取)

2.5 string类对象的修改操作

2.6 String类内部扩容细节

2.7 小试牛刀

         

              ——————————————《Rain》——————————————


正文开始——

一、为什么要学习string类?

1.1 C语言中的字符串

C 语言中,字符串是以 '\0' 结尾的一些字符的集合,为了操作方便, C 标准库中提供了一些 str 系列的库函数,但是这些库函数与字符串是分离开的,不太符合OOP 的思想,而且底层空间需要用户自己管理,稍不留神可能还会越界访问。

1.2 面试题(暂不做讲解)

415. 字符串相加 - 力扣(LeetCode)

OJ 中,有关字符串的题目基本以 string 类的形式出现,而且在常规工作中,为了简单、方便、快捷,基本都使用string 类,很少有人去使用 C 库中的字符串操作函数。

二、 标准库中的string

2.1 string类(了解)

https://cplusplus.com/reference/string/string/?kw=string,最好观看第一手的资料,自己阅读英文版

 C++标准库都封装在std这个命名空间里面的,使用string类时,必须包含#include头文件以及using namespace std;

#include<iostream>
#include<string>
#include<assert.h>

using namespace std;

//class string
//{
//public:
//  s2[]的底层
//	//为什么string类的对象能直接利用[]来访问和修改元素呢?下面是[]运算符的重载,引用返回能直接修改元素
//	char& operator[](size_t pos)
//	{
//		assert(pos < _size);
//		return _str[pos];
//	}
//private:
//	char* _str;
//	size_t _size;
//	size_t _capacity;
//};

int main()
{
	string s1;//空字符串
	string s2("1111122222");//将字符串拷贝s2进行赋值
	string s3("1111111111", 3);//拷贝字符串里面的前3个字符
	string s4(100, 'x');
	string s5(s2, 4, 3);//这里的4(pos)指的是下标
	string s6(s2,9);
	string s7(s2,4,90);

	cout << s1 << endl;
	cout << s2 << endl;
	cout << s3 << endl;
	cout << s4 << endl;
	cout << s5 << endl;
	cout << s6 << endl;
	cout << s7 << endl;

	//s2.operator[](0) = 'x';相当于调用的函数
	s2[1] = 'x';//直接像数组一样利用下标来修改内容
	cout << s2 << endl;

	//利用循环来遍历s2
	for (int i = 0; i < s2.size(); i++)
	{
		s2[i]++;
	}

	cout << s2 << endl;

	return 0;
}

2.2 auto和范围for

auto关键字

  • 在早期C/C++auto的含义是:使用auto修饰的变量,是具有自动存储器的局部变量,后来这个不重要了。C++11中,标准委员会变废为宝赋予了auto全新的含义即:auto不再是一个存储类型指示符,而是作为一个新的类型指示符来指示编译器,auto声明的变量必须由编译器在编译时期推导而得
  • auto声明指针类型时,用autoauto*没有任何区别,但用auto声明引用类型时则必须加&。
  • 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量
  • auto不能作为函数的参数(C++20开始支持),可以做返回值但是建议谨慎使用,见下:

  • auto不能直接用来声明数组

auto有啥用呢,价值在哪里呢?
int main()
{
	int i = 0;
	int j = 0;

	//自动推导类型,根据等号右边的数据来自动推导左边数据的类型
	auto z = i; // int
	auto m = 1.1;  //double
	auto p = &i;   //int*
	int& r1 = i;   //r1的类型是int&,不是int

	auto r2 = r1;  //int,不是int&
	auto& r3 = r1;  //int&
	//auto r4;      //报错


	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//利用迭代器来遍历链表
	list<int>::iterator it = lt.begin();
	auto it = lt.begin();//在这里使用迭代器就非常的爽!不用再写那么长的代码了
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	// 后面学了map用auto会更爽,我们先引入map的迭代器看看这里使用auto的感觉
	// auto语法糖 ---> 简化代码,替代写起来长的类型
	std::map<std::string, std::string> dict;
	//std::map<std::string, std::string>::iterator dit = dict.begin();
	auto dit = dict.begin();  //很甜,超级甜~

	return 0;
}

范围for

  • 对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因此C++11中引入了基于范围的for循环。for循环后的括号由冒号分为两部分:第一部分是范围内用于迭代的变量,第二部分则表示被迭代的范围,自动迭代,自动取数据,自动判断结束。
  • 范围for可以作用到数组和容器对象上进行遍历。
  • 范围for的底层很简单,容器遍历实际就是替换为迭代器,这个从汇编层也可以看到。

int main()
{
	string s1("hello world");
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	// 范围for 
	// 适用于容器遍历和数组遍历
	// 自动取容器的数据赋值给左边的对象,左边的对象的名称随便取
	// 自动++,自动判断结束
	// 原理:范围for底层是迭代器

	//for (char ch : s1)
	for (auto ch : s1)//这里更喜欢用auto
	{
		cout << ch << " ";
	}
	cout << endl;

	//for (int n : lt)
	for (auto n : lt)
	{
		cout << n << " ";
	}
	cout << endl;

	return 0;
}

 有一个问题,如果按下面的代码数组里面的内容会不会被修改呢?

	for (auto ch : s1)//这里更喜欢用auto
	{
		cout << ch << " ";
	}
	cout << endl;

	for (auto ch : s1)//这里更喜欢用auto
	{
		ch++;
	}

	for (auto ch : s1)//这里更喜欢用auto
	{
		cout << ch << " ";
	}
	cout << endl;

为什么呢?

前面讲的只是单纯的赋值,并不能改变里面的数据,加上&即可,真是嘎嘎嘎香

对于范围for哪两种情况下要用引用呢?

  •  修改容器里面的数据
  • 如果容器里面存的是比较大的对象,那我们最好用引用以减少拷贝(如果我们用引用同时又不想修改里面的内容,就可以用const引用)

总结一下,对于string有三种遍历方式,这三种遍历方式都可读可写

  • [下标 ],对于sring和vector会比较方便,不适用于物理存储空间不连续的容器
  • 迭代器,通用遍历方式(可用于 list 这种物理空间不连续的)
  • 范围for

什么类都可以用范围for吗?

不是,像日期类,没有这种用法。原理:范围 for 的底层是迭代器

2.3 string类的常用接口说明(注意下面我只讲解最常用的接口)

2.3.1 string类对象的常见构造

2.3.2 string类对象的容量操作

注意:
  1. size()length()(都不包含最后结尾的\0)方法底层实现原理完全相同,引入size()的原因是为了与其他容器的接口保持一致,一般情况下基本都是用size()
  2. clear()只是将string中有效字符清空,不改变底层空间大小。
  3. resize(size_t n) resize(size_t n, char c)都是将字符串中有效字符个数改变到n个,不同的是当字符个数增多时:resize(n)0来填充多出的元素空间,resize(size_t n, char c)用字符c来填充多出的元素空间。注意:resize在改变元素个数时,如果是将元素个数增多,可能会改变底层容量的大小,如果是将元素个数减少,底层空间总大小不变。
  4. reserve(size_t res_arg=0):为string预留空间,不改变有效元素个数,当reserve的参数小于string的底层空间总大小时,reserver不会改变容量大小。
  5. max_size指最大能开到多少空间,不切实际没有什么意义,不同平台下返回的值不同。

【reserve 和 reverse】见下:

//reserve 保留 预留
//reverse 反转 翻转
int main()
{
	string s1;
	// 提前开空间,避免扩容(这是在知道大概需要多少空间的情况下比较好)
	s1.reserve(200);//编译器会开的比200大,同样满足需求,但是不会是小

	cout << s1.capacity() << endl;

	return 0;
}

2.3.3 string类对象的访问及遍历操作

【operator[ ]】 

 上次我们学的日期类里面的取地址运算符的重载也是支持const对象和普通对象都可以调用。

【遍历begin+end+迭代器第一弹】

#include<iostream>
#include<string>
using namespace std;

int main()
{
	string s1("hello world");

	//[下标]的方式去遍历
	for (int i = 0; i < s1.size(); i++)
	{
		s1[i]++;//利用下标去修改数组的内容
	}
	for (int i = 0; i < s1.size(); i++)
	{
		cout<<s1[i]<<" ";
	}
	cout << endl;


	// 迭代器---像指针一样的对象(有可能是指针,有可能不是指针,要看底层的实现)
	// iterator是一个类型,是属于string类里面的一个内部类
	string::iterator it1 = s1.begin();

	while (it1 != s1.end())//s1.end()指向的是最后一个数据的下一个位置
	{
		(*it1)--;
		++it1;//*it1就是这个位置,++来走到下一个位置
	}

	it1 = s1.begin();
	while (it1 != s1.end())//s1.end()指向的是最后一个数据的下一个位置
	{
		cout << (*it1) << " ";
		++it1;//*it1就是这个位置,++来走到下一个位置
	}
	cout << endl;

	return 0;
}

用下标的访问方式来修改和读取数据很香,为啥还要用迭代器呢?

用下标访问的方式只适用于string和vector这样的结构,string和vector底层是连续的物理空间,用[ ]来访问就很方便,,但是我们后面学习链表和树形结构再用[ ]来访问就很不方便。[ ]不是通用的方式,而迭代器是通用的方式

看看下面举例迭代器具体在哪里使用——list(记得加上头文件#include<list>)

所有的容器都要定义迭代器,迭代器是所有容器通用的一种东西,都可以使用迭代器去遍历,所使用的方式也都是很相似的

int main()
{
	list<int> lt;

	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);

	//利用迭代器来遍历链表
	list<int>::iterator it = lt.begin();
	while (it != lt.end())
	{
		cout << *it << " ";
		it++;
	}
	cout << endl;

	return 0;
}

【迭代器第二弹】
int main()
{
	string s1("hello world");
	string::reverse_iterator rit = s1.rbegin();
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	return 0;
}

【const对象的迭代器和反向迭代器】 

int main()
{
	const string s1("hello world");
	string::const_reverse_iterator rit = s1.rbegin();//不能修改容器里面的内容
	while (rit != s1.rend())
	{
		cout << *rit << " ";
		++rit;
	}
	cout << endl;

	const string s2(s1);
	string::const_iterator it = s2.begin();//不能修改容器里面的内容,这里可以用auto
	while (it != s2.end())
	{
		cout << *it << " ";
		++it;
	}
	cout << endl;

	return 0;
}

上面介绍的就是我们常用的四种迭代器,iterator,reverse_iterator,const_iterator,const_reverse_iterator,其他的cbegin啥的我们不常用。

2.4 string类对象的Element access(元素存取)

对于operator[ ],见下:

 对于at,不同于operator[]直接assertion报错at会有抛出异常机制,见下:

back,front 返回的是最后一个字符和第一个字符,我们用[ ]和at也可以实现,注意返回的是引用,可以用来修改数据。(具体自己来查看文档)

int main()
{
	try
	{
		string s1("hello world1111");

		cout << s1.size() << endl;
		cout << s1.length() << endl;
		cout << s1.capacity() << endl;//空间大小,其实比本身容量还要再大一个
		cout << s1.max_size() << endl;

		cout << endl << endl;

		s1.clear();
		cout << s1.size() << endl;
		cout << s1.capacity() << endl;

		//s1[20];
		s1.at(20);
	}
	catch (const exception& e)
	{
		cout << e.what() << endl;
	}
	return 0;
}

2.5 string类对象的修改操作

注意:
  1. 1. string尾部追加字符时,s.push_back(c) / s.append(1, c) / s += 'c'三种的实现方式差不多,一般情况下string类的+=操作用的比较多,+=操作不仅可以连接单个字符,还可以连接字符串。
  2. string操作时,如果能够大概预估到放多少字符,可以先通过reserve把空间预留好。
int main()
{

    //其实string底层跟我们前面学的顺序表很相似
    class String
    {
     public:
            //...
     private:
            char buff[16];
            char* _str;
            size_t size;
            size_t _capacity;
    }

	//利用push_back只能插入单个字符
	string s1("hello");
	s1.push_back(',');
	s1.push_back('w');
	cout << s1 << endl;

	//利用append来插入字符串,具体更多用法查看文档
	s1.append("orld");
	cout << s1 << endl;
	s1.append(10, '~');
	cout << s1 << endl;


	string s2("hello pig");
	//利用迭代器
	s1.append(s2.begin(), s2.end());//将一整串都直接插入到s1的后面
	cout << s1 << endl;

	s1.append(s2.begin()+6, s2.end());//可以定位s2的字符将其插入
	cout << s1 << endl;

	//但是我们更多是使用+=这个运算符重载,这个确实更香,不经常使用push_back和append
	string s3("hello");
	s3 += ',';
	s3 += "world";
	cout << s3 << endl;

	return 0;
}

2.6 String类内部扩容细节

int main()
{
	string s1;
	size_t old = s1.capacity();
	
	for (int i = 0; i < 200; i++)
	{
		s1 += 'x';
		if (s1.capacity() != old)
		{
			cout << "capacity:"<< s1.capacity() << endl;
			old = s1.capacity();
		}
	}
	cout << endl;

	string s2("11111111");
	string s3("111111111111111111111222222222222222222");
	cout << sizeof(s2) << endl;

	return 0;
}

2.7 小试牛刀

917. 仅仅反转字母 - 力扣(LeetCode)

感慨一下,学了一些算法思想思路确实就是不一样了哈,继续学起来。对于本题,不难看出要使用双指针算法,经典的双指针算法

值得一提的是,我们要单独写一个判断是否是字母的函数,这样在while循环里面的条件就比较好写。这也是我第一次用C++来写算法题,那就一个方便呀,以前过得是什么苦日子~

现在基本啥都有了,以前是啥也没有纯纯自己造啊/woqu,还有,甘蕉力扣比洛谷刷题感觉好。

class Solution {
public:
    // 单独写一个函数——判断是否是字母
    bool isLetter(char ch) {
        if (ch >= 'a' && ch <= 'z')
            return true;
        if (ch >= 'A' && ch <= 'Z')
            return true;
        return false;
    }

    string reverseOnlyLetters(string s) {
        int begin = 0;
        int end = s.size() - 1;

        while (begin < end) {
            while (begin < end && !isLetter(s[begin])) {
                begin++;
            }
            while (begin < end && !isLetter(s[end])) {
                end--;
            }
            // 交换
            swap(s[begin], s[end]);
            begin++;
            end--;
        }
        return s;
    }
};

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

387. 字符串中的第一个唯一字符 - 力扣(LeetCode)

字符串最后一个单词的长度_牛客题霸_牛客网

125. 验证回文串 - 力扣(LeetCode)

415. 字符串相加 - 力扣(LeetCode)

string,vestor,list 都想实现逆置,逆置的底层逻辑是一样的,有点想实现逆置的函数模版,但是string,vector,list的底层结构不一样就无法直接写一个逆置的函数模版,但是!它们共同的一点都有迭代器,哈哈此时我们可以写一个关于迭代器的逆置函数模版,只要给我你的迭代器我就可以实现这些容器的逆置。

class Solution {
public:
    string addStrings(string num1, string num2) {
        string str;
        str.reserve( max(num1.size(), num2.size()) + 1);

        int end1 = num1.size()-1,end2 = num2.size()-1;

        int next = 0;
        while(end1 >= 0 || end2 >= 0)
        { 
            int x1 = end1 >= 0 ? num1[end1--]-'0' : 0 ;
            int x2 = end2 >= 0 ? num2[end2--]-'0' : 0 ;

            int ret = x1 + x2 + next;
            next = ret / 10;
            ret = ret % 10;
            str += ret+'0';
        }

        if(next == 1)
        {
            str += '1';
        }

        reverse(str.begin(),str.end());
        return str;
    }
};

541. 反转字符串 II - 力扣(LeetCode)

557. 反转字符串中的单词 III - 力扣(LeetCode)

43. 字符串相乘 - 力扣(LeetCode)

找出字符串中第一个只出现一次的字符_牛客题霸_牛客网

今天就先学到这里吧,剩下的明天继续更!

完——


         

              ——————————————Rain——————————————

Rain_秦基博_高音质在线试听_Rain歌词|歌曲下载_酷狗音乐

至此结束——

我是云边有个稻草人

期待与你的下一次相遇!

(有机会再看一遍怪奇物语全季)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2329897.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Java 数组与 ArrayList 核心区别解析:从源码到实战!!!

&#x1f31f; Java 数组与 ArrayList 核心区别解析&#xff1a;从源码到实战 &#x1f4a1; Java 开发者必读&#xff01; 数组&#xff08;Array&#xff09;和 ArrayList 是 Java 中最常用的数据存储结构&#xff0c;但它们的底层设计、性能表现和适用场景差异显著。本文通…

【易飞】易飞批量选择品号处理方法,工作效率提升300%

开窗选择品号方式要么手动输入,要么以什么开头、包含、从A物料到B物料查询后返回的有规律的品号。对于没有规律且大量品号的处理方式是否有便捷的方法呢? 尤其在通常在查询多阶材料清单,查询库存明细表,整批变更元件等如品号无规律情况下,只能一个个选择,无法通过EXCEL方…

【最新版】啦啦外卖v64系统独立版源码+全部小程序APP端+安装教程

一.系统介绍 啦啦外卖跑腿平台独立版&#xff0c;使用的都知道该系统功能非常强大&#xff0c;应该说是目前外卖平台功能最全的一套系统。主要是功能非常多&#xff0c;拿来即用&#xff0c;包括客户端小程序、配送端小程序、商户端小程序&#xff0c;还有对应四个端的APP源码…

iproute2 工具集使用详解

目录 一、iproute2 核心命令&#xff1a;ip二、常用功能详解1. 管理网络接口&#xff08;link 对象&#xff09;2. 管理 IP 地址&#xff08;address 对象&#xff09;3. 管理路由表&#xff08;route 对象&#xff09;4. 管理 ARP 和邻居缓存&#xff08;neigh 对象&#xff0…

AD(Altium Designer)更换PCB文件的器件封装

一、确定是否拥有想换的器件PCB封装 1.1 打开现有的原理图 1.2 确定是否拥有想换的器件PCB文件 1.2.1 如果有 按照1.3进行切换器件PCB封装 1.2.2 如果没有 按照如下链接进行添加 AD(Altium Designer)已有封装库的基础上添加器件封装-CSDN博客https://blog.csdn.net/XU15…

【文献研究】含硼钢中BN表面偏析对可镀性的影响

《B 添加钢的溶融 Zn めっき性に及ぼす BN 表面析出の影響》由JFE公司田原大輔等人撰写。研究聚焦 B 添加钢在低露点退火时 BN 形成对镀锌性的影响&#xff0c;对汽车用高强度钢镀锌工艺优化意义重大。通过多组对比实验&#xff0c;结合多种分析手段&#xff0c;明确了相关因素…

React学习-css

W3Schools Tryit Editor CSS 教程 CSS 规则由两个主要的部分构成:选择器,以及一条或多条声明: p { /* 这是个注释 */ color:red; text-align:center; }选择器 CSS Id: #para1{ text-align:center; color:red; } Class: .center {text-align:center;} p…

数据分析-Excel-学习笔记Day1

Day1 复现报表聚合函数&#xff1a;日期联动快速定位区域SUMIF函数SUMIFS函数环比、同比计算IFERROR函数混合引用单元格格式总结汇报 拿到一个Excel表格&#xff0c;首先要看这个表格的构成&#xff08;包含了哪些数据&#xff09;&#xff0c;几行几列&#xff0c;每一列的名称…

树莓派PICO 设备烧录成cmsis dap

文章目录 1. 实际操作2. IO连接 1. 实际操作 2. IO连接

【数据结构】图的存储

目录 邻接矩阵 表示方法 代码定义 结构特点与度的信息 邻接表 表示方法 代码定义 结构特点与度的信息 十字链表 表示方法 第二步&#xff0c;将顶点x的firstIn域与所有headvex域为x的弧连起来。 结构特点与度的信息 邻接多重表 表示方法 结构特点与度的信息 图…

如何解决uniapp打包安卓只出现功能栏而无数据的问题

如何解决uniapp打包安卓只出现功能栏而无数据的问题 经验来自&#xff1a;关于Vue3中调试APP触发异常&#xff1a;exception:white screen cause create instanceContext failed,check js stack -> at useStore (app-service.js:2309:15)解决方案 - 甲辰哥来帮你算命 - 博客…

kotlin,数字滚动选择

用国内的通义灵码和codegeex都没有弄出来&#xff0c;最后只得用墙外的chatgpt才弄出一个满意的。kotlin真的有点难&#xff0c;好在有AI&#xff0c;让学习没这难了。 package com.example.mynumsetimport android.os.Bundle import androidx.activity.ComponentActivity imp…

【4】搭建k8s集群系列(二进制部署)之安装master节点组件(kube-apiserver)

一、下载k8s二进制文件 下载地址&#xff1a; https://github.com/kubernetes/kubernetes/blob/master/CHANGELOG/CHANGELOG -1.20.md 注&#xff1a;打开链接你会发现里面有很多包&#xff0c;下载一个 server 包就够了&#xff0c;包含了 Master 和 Worker Node 二进制文件。…

每日c/c++题 备战蓝桥杯(小球反弹)[镜像思路求解,最小公倍数]

思路&#xff1a; 错解&#xff1a;对于这道题而言&#xff0c;有的同学会选择用计算每次碰撞的坐标&#xff0c;直到坐标等于原点的方法来做&#xff0c;但这种方法实现起来比较繁琐&#xff0c;并且由于碰撞点的坐标有可能是浮点数&#xff0c;而浮点数会丢失精度&#xff0…

新潮透明液体水珠水滴失真故障扭曲折射特效海报字体标题设计ps样机动作素材 Bubble Photoshop Templates

只需单击几下即可创建引人注目的视觉效果&#xff01;您需要做的就是将您的文本或图像放入智能对象中并应用作。 包中包含&#xff1a; 15 个静态 Photoshop 模板&#xff08;PS 2019 及更高版本&#xff09; 01-05 垂直布局 &#xff08;22504000&#xff09;06-10 水平布局…

从零开始玩python--python版植物大战僵尸来袭

大家好呀&#xff0c;小伙伴们&#xff01;今天要给大家介绍一个超有趣的Python项目 - 用pygame制作植物大战僵尸游戏的进阶版本。相信不少小伙伴都玩过这款经典游戏&#xff0c;今天我们就用Python来实现它&#xff0c;让编程学习变得更加有趣&#xff01;&#x1f31f; 一、…

Visual Studio Code SSH 连接超时对策( keep SSH alive)

文章目录 问题解决方法一&#xff1a;配置服务端关于ClientAliveInterval和ClientAliveCountMax1、打开终端&#xff0c;打开SSH配置文件&#xff1a;输入以下命令&#xff1a;2、打开配置文件后&#xff0c;添加以下内容&#xff1a;3、添加后&#xff0c;Esc按 <Enter>…

【C语言入门】由浅入深学习指针 【第二期】

目录 1. 指针变量为什么要有类型&#xff1f; 2. 野指针 2.1 未初始化导致的野指针 2.2 指针越界导致的野指针 2.3 如何规避野指针 3. 指针运算 3.1 指针加减整数 3.2 指针减指针 3.3 指针的关系运算 4. 二级指针 5. 指针数组 5.1 如何使用指针数组模拟二维数组 上…

关于Ubuntu系统的远程控制及文件传输

目录 1. 网络配置1.1 虚拟机Ubuntu网络配置1.2树莓派网络配置 2. 远程终端登录3. FTP文件传输4. 安装Xming和PuTTY5. 使用X11转发6. 安装和使用VNC思考题解答参考资料 1. 网络配置 1.1 虚拟机Ubuntu网络配置 将虚拟机的网络连接设置为“桥接模式”&#xff0c;这样虚拟机的网…

IS-IS-单区域的配置

一、IS-IS的概念 IS-IS&#xff08;Intermediate System to Intermediate System&#xff0c;中间系统到中间系统&#xff09;是一种‌链路状态路由协议‌&#xff0c;最初设计用于‌OSI&#xff08;Open Systems Interconnection&#xff09;参考模型‌的网络层&#xff08;CL…