c++ primer笔记----字符串、向量和数组

本文介绍了C++标准库的基本使用方法,包括string和vector的定义、初始化、操作及迭代器的使用。同时,还详细讲解了数组和多维数组的使用技巧。

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

  • using声明
#include <iostream>
using std::cin;
using std::cout; using std::endl;
  • 定义和初始化string
string s1;  //默认初始化,s1是一个空字符串
string s2(s1);
string s2 = s1;
string s3 = "value";
string s3("value");
string s4(n, 'c');
  • 读写string
string s;
cin >> s;  //自动忽略开头的空白(空格、换行符、制表符等),直到遇到下一处空白为止

getline(cin. line);  //每次读取一行,直到遇到换行符。最后换行符被丢弃

line.empty();

auto len = line.size();  //len是类型 `string::size_type`。 unsigned
// 如果一条表达式中已经有了size()函数,就不要再使用int了。
// 自动转换是int-->unsigned int
  • stirng相加:字符串字面值并不是string对象
string s4 =s1 +", ";
string s5 = "hello " + ", ";  //错误: + 的两个运算对象至少一个是string对象
  • 处理或改变每个字符,范围for循环
#include <string>
using std::string;

string s("hello");
decltype(s.size()) punct_cnt = 0;   //类型声明
for(auto c : s)         //若要改变则 auto &c : s 。c的类型是 char
    if(ispunct(c))      //<cctype>
        ++punct_cnt;
  • 下标运算符[]:接收的参数类型是string::size_type。无符号类型的。c++标准库并不要求检测下标的合法性

  • vevtor:类模板,为编译器生成类而编写的一份说明

#include <vector>
using std::vector

vector<int> ivec;   //<对象>  <>里不能是引用,因为引用不是对象
  • 定义和初始化vector
vector<T> v1;  //空vector
vector<T> v2(v1);
vector<T> v2 = v1;
vector<T> v3(n, val);
vector<T> v4(n);  //n个对象,值是默认值
vector<T> v5{a, b, c};
vector<T> v5 = {a, b, c};

vector<string> v6("hi");   //error : {}
vector<string> v7{10};    //等价于 v7(10). 类型不匹配的情况
vector<string> v8{10, "hi"};  //等价于 v8(10, "hi")
  • 实例化:编译器根据模板创建类或函数的过程

  • vector操作

vector<int> v1;
v1.push_back(1);  //添加元素。 如果出现该语句,则不能使用范围for循环
  • 迭代器
auto b = v.begin(), e = v.end();  //如果为空,则都是尾后迭代器
for(auto it = s.begin(); it != s.end(); ++it)  
//!= 标准容器看迭代器都有的定义,  ++it比 it++更高效
  • 迭代器类型
vector<int>::iterator it;
string::iterator it2;

vector<int>::const_iterator it3;
string::const_iterator it4;

vector<int> v;
const vector<int> cv;
auto it1 = v.begin();    //vector<int>::iterator ,由对象是否是常量决定
auto it2 = cv.begin();   //vector<int>::const_iterator

auto it3 = v.cbegin();  //vector<int>::const_iterator
  • 迭代器访问成员
it->mem;
(*it).mem;
  • 凡是使用了迭代器的循环体,都不要向迭代器所属的容器添加元素

  • constexpr和常量表达式:值不会改变,在编译过程就得到计算结果的表达式。字面值属于常量表达式,用常量表达式初始化的const对象也是常量表达式

const int max_files = 20;
const int limit = max_files + 1;
int staff_size = 27;  //不是常量表达式
const int sz = get_size(); //看函数是不是constexpr函数

constexpr int mf =20;
  • 数组初始化
int arr[10];  //[]内是常量表达式

int a2[] = {0, 1, 2};  //大小是3
int a3[5] = {0, 1, 2}; //后面2个元素初始化为0
  • 字符数组特殊性
char a1[] = {'c', 'd'}; //大小是2
char a2[] = {'c', 'd', '\0';} //含有显示的空字符
char a3[] = "c++"; //大小是4,自动添加空字符
const char a4[6] = "daniel"; //error: 大小是7,没有空间存放空字符
  • 复杂的数组声明
int *ptrs[10]; //ptrs是含有10个整型指针的数组。 类型修饰符从右向左依次绑定
int &refs[10]; //error : 不存在引用的数组。 引用不是对象
int (*parray)[10] = &arr; //parray是指针,指向含有10个整数的数组
int (&arrref)[10] = arr;  //arrref是引用,引用含有10个整数的数组

int *(&arry)[10] = ptrs; //arry是引用,引用的是含有10个int指针的数组
  • 指针和数组:数组名和指针几乎相同,且都能进行++,>,*,-等运算。不同在于,num++非法, num++是一个指向数组开头的常量,不能作为左值。
string nums[] = {"1", "2", "3"};
string *p = &nums[0];  //[]里面的索引值是有符号的
  • C风格字符串:是为了表达和使用字符串而形成的一种约定俗称的写法。按此习惯书写的字符串存放在字符数组中并以空字符(null)结束。

  • string对象转换为C风格字符串

char *str = s.c_str(); //调用成员函数。
//如果想一直使用该字符串数组,组好重新拷贝一份
  • 使用数组初始化vector对象
int int_arr[] = {0, 1, 2, 3, 4, 5};
vector<int> ivec(begin(int_arr, end(int_arr))); //<iterator>,返回的指针int* 
  • 多维数组:数组的数组
int ia[3][4] = {{0,1,2,3}, {4,5,6,7}, {8,9,10,11}};//3个元素,每个元素是4元素数组
int ia[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};
int ia[3][4] = {{1}, {2}, {3}};

int (&row)[4] = ia[1];  //把row绑定到ia的第二个4元素数组上
  • 范围for
size_t cnt = 0;  //数组[]内的类型是size_t
for(auto &row:ia)   //不能是 auto row:ia。这样返回的int[4]数组的指针,
                    //下面循环就不对了。 加上&,返回的是数组
    for(auto &col:row){   //最后一个循环,可以去掉&
        col = cnt;
    }
  • 指针和多维数组:使用数组名字时,自动将其转换成指向数组首元素的指针
int ia[3][4];
int (*p)[4] = ia;  //名字-->指针
p = &ia[2];
int (&row)[4] = ia[1];  //把row绑定到ia的第二个4元素数组上

for(auto p=ia; p!=ia+3; ++p)  //名字-->指针, p是指针,指向含有4个整数的数组
    for(auto q=*p; q!=*p+4; ++q) //*p是数组,*P是数组名,名字-->指针

for(auto p=begin(ia); p!=end(ia);++p)
    for(auto q=begin(*p); q!=end(*p); ++q)
  • 类型别名
using int_array = int[4];
typedef int int_array[4];
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 “STC单片机电压测量”是一个以STC系列单片机为基础的电压检测应用案例,它涵盖了硬件电路设计、软件编程以及数据处理等核心知识点。STC单片机凭借其低功耗、高性价比丰富的I/O接口,在电子工程领域得到了广泛应用。 STC是Specialized Technology Corporation的缩写,该公司的单片机基于8051内核,具备内部振荡器、高速运算能力、ISP(在系统编程)IAP(在应用编程)功能,非常适合用于各种嵌入式控制系统。 在源代码方面,“浅雪”风格的代码通常简洁易懂,非常适合初学者学习。其中,“main.c”文件是程序的入口,包含了电压测量的核心逻辑;“STARTUP.A51”是启动代码,负责初始化单片机的硬件环境;“电压测量_uvopt.bak”“电压测量_uvproj.bak”可能是Keil编译器的配置文件备份,用于设置编译选项项目配置。 对于3S锂电池电压测量,3S锂电池由三节锂离子电池串联而成,标称电压为11.1V。测量时需要考虑电池的串联特性,通过分压电路将高电压转换为单片机可接受的范围,并实时监控,防止过充或过放,以确保电池的安全寿命。 在电压测量电路设计中,“电压测量.lnp”文件可能包含电路布局信息,而“.hex”文件是编译后的机器码,用于烧录到单片机中。电路中通常会使用ADC(模拟数字转换器)将模拟电压信号转换为数字信号供单片机处理。 在软件编程方面,“StringData.h”文件可能包含程序中使用的字符串常量数据结构定义。处理电压数据时,可能涉及浮点数运算,需要了解STC单片机对浮点数的支持情况,以及如何高效地存储显示电压值。 用户界面方面,“电压测量.uvgui.kidd”可能是用户界面的配置文件,用于显示测量结果。在嵌入式系统中,用
资源下载链接为: https://pan.quark.cn/s/abbae039bf2a 在 Android 开发中,Fragment 是界面的一个模块化组件,可用于在 Activity 中灵活地添加、删除或替换。将 ListView 集成到 Fragment 中,能够实现数据的动态加载与列表形式展示,对于构建复杂且交互丰富的界面非常有帮助。本文将详细介绍如何在 Fragment 中使用 ListView。 首先,需要在 Fragment 的布局文件中添加 ListView 的 XML 定义。一个基本的 ListView 元素代码如下: 接着,创建适配器来填充 ListView 的数据。通常会使用 BaseAdapter 的子类,如 ArrayAdapter 或自定义适配器。例如,创建一个简单的 MyListAdapter,继承自 ArrayAdapter,并在构造函数中传入数据集: 在 Fragment 的 onCreateView 或 onActivityCreated 方法中,实例化 ListView 适配器,并将适配器设置到 ListView 上: 为了提升用户体验,可以为 ListView 设置点击事件监听器: 性能优化也是关键。设置 ListView 的 android:cacheColorHint 属性可提升滚动流畅度。在 getView 方法中复用 convertView,可减少视图创建,提升性能。对于复杂需求,如异步加载数据,可使用 LoaderManager CursorLoader,这能更好地管理数据加载,避免内存泄漏,支持数据变更时自动刷新。 总结来说,Fragment 中的 ListView 使用涉及布局设计、适配器创建与定制、数据绑定及事件监听。掌握这些步骤,可构建功能强大的应用。实际开发中,还需优化 ListView 性能,确保应用流畅运
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值