首页 > 编程语言 >【C++ Primer】字符串和数组

【C++ Primer】字符串和数组

时间:2023-10-10 10:05:11浏览次数:45  
标签:初始化 string int C++ 数组 字符串 using Primer 指针


一、命名空间的using声明

1、using声明:using namespace::name,例如:using std::cin。一旦声明了上述语句,就可以直接访问命名空间的变量。每个变量都需要using声明,位于头文件中的代码不应该使用using声明。

2、using编译:using namespace std;直接使用整个命名空间。

使用using声明比使用using编译指令更安全,这是由于它只导入指定的名称。如果该名称与局部名称发生冲突,编译器将付出指示。using编译指令导入所有名称,包括可能并不需要的名称。如果与局部名称发生冲突,则局部名称将覆盖名称空间版本,而编译器并不会发出警告,另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确的知道添加了哪些名称。

 

二、标准库类型string

string对象中所存储的内容,是不以空字符结尾的(区别于C风格字符串)。

 

#include <string>
using std::string;

 

1、定义和初始化string对象:

 

 

string s1;//初始化为空串。
string s2(s1);//s2是s1的副本。
string s2 = s1;//拷贝初始化。
string s3("value");//直接初始化。
string s3 = "value";//拷贝初始化。
string s4(10,'a');//初始化为多个相同字符组成的串。

 

2、string对象上的操作:

 

string s1,s2,s3;
int a;
cin >> s2;//从第一个真正的字符开始读,直到遇到空白为止。
while(cin >> s2)//读取未知数量的string对象(连续输入时,想结束输入可以换行后输入ctrl+Z)
	cout << s2 << endl;
cin.clear();//清空缓冲区。
cin >> a;
cin.get();//输入数字后使用cin.get()去掉换行符。
getline(cin,s3);//读取一整行(换行符被丢弃),保留输入时的空白符。

/*string的empty和size操作*/
if(!s3.empty() && s3.size()>3)//如果s3非空并且s3的长度大于3。
	cout << s3 << endl;

/*string::size_type类型*/
using st = string::size_type;
for (st i=0 ; i<s3.size() ; ++i)//无符号类型的值,用于处理string对象,好处在于避免混用带符号和无符号类型。
	cout << s3[i] << endl;

/*string对象相加、与字面值相加*/
string s4 = s2 + s3;//字符串连接。
string s5 = s3 + "abc";//必须确保每个加法运算(+)两侧的运算对象至少有一个是string,字符串字面值不等于string。

 

3、处理string对象的字符:

 

(1)范围for【c++11】:遍历给定序列中的每个元素并对序列中的每个值执行某种操作。

 

for (const auto s : s5)//对于s5中的每个字符,输出当前字符。
	cout << s << endl;
for (auto & s : s5)//s是引用,因此会改变s5中的字符值。
	s = toupper(s);

(2)下标运算符:下标从0计算起,string对象的下标必须大于0小于size(),使用下标必须确保其在合理范围内。

 

//用decltype定义变量的类型,isspace判断s[index]是否遇到空白符,toupper把小写字母转换为大写字母。
for (decltype(s.size()) index = 0 ; index != s.size() && !isspace(s[index]) ; ++index)
	s[index] = toupper(s[index]);

三、数组

 

数组的大小是确定的,不能随意增加元素(这一点与vector不同)。在某些情况下运行时性能较好,但是也损失了灵活性。

【Note】:如果不清楚元素的数量,请使用vector。

 

1、定义和初始化数组:

(1)简单的初始化:

 

int a[cnt];//数组的维度必须是常量表达式。
int cnt2 = 4,b[cnt2];
string s1 = {"abc","edf"};//列表初始化。

【Note】:不能将数组的内容拷贝给其他数组作为其初始值,也不能使用数组为其他数组赋值,所以函数也不能返回数组。

 

(2)复杂的数组声明:

 

int *ptrs[10];//ptrs是含有10个整型指针的数组。
int &refs[10];//错误:不存在引用的数组。
int (*p)[10] = &arr;//p指向一个含有10个整数的数组。
int (&a)[10] = arr;//a引用一个含有10个整数的数组。

由内向外(先右后左)的顺序阅读。

 

 

2、访问数组元素:

 

unsigned scores[11] = {};
unsigned grade;
while(cin >> grade)
{
    if(grade <= 100)
	++scores[grade/10];//通过下标访问。
}
for (auto i : scores)//i是size_t类型。
    cout << i << endl;

下标越界或者试图访问非法内存区域时,就会产生此类错误。

 

 

3、指针和数组:   

(1)在很多用到数组名字的地方,编译器都会自动的将其替换为一个指向数组首元素的指针(尤其是作为函数形参的时候)。在大多数表达式中,使用数组类型的对象其实是使用一个指向该数组首元素的指针。

 

int *p = scores;//等价于p = &scores[0]。
auto p2(scores);

(2)标准库函数begin和end【c++11】:

 

 

 

    为了让指针的使用更简单、安全,引入了begin和end的函数。

 

int *beg = begin(scores);//指向首元素。
int *lst = end(scores);//指向尾元素的下一个位置。

【Note】:尾后指针不能执行解引用和递增操作。

 

(3)指针运算:

    给指针加上一个整数,得到的新指针任然指向同一数组的其他元素,两个指针相减的结果是它们之间的距离。

 

4、C风格字符串

 

char a[4] = {'a','b','\0'};
char b[2] = {};
size_t l = strlen(a);//计算字符串大小,不包括空字符。
strcpy(b,a);//将a拷贝给b。
strcat(a,b);//将b连接到a后面。
for (const auto s : a)
{
    cout << s << endl;
}

【Note】:现代的C++程序应当尽量使用vector和迭代器,避免使用内置数组和指针;应该尽量使用string,避免使用C风格的字符串。
 

 

四、多维数组

    多维数组其实就是数组的数组。

 

//列表初始化,第一个维度可以省略。
int ia[][2] = 
{
    {1,2},
    {3,4}
};
for (auto p=begin(ia) ; p!=end(ia) ; ++p)
{
    for (auto q=begin(*p) ; q!=end(*p) ; ++q)
	cout << *q << endl;
}

 

标签:初始化,string,int,C++,数组,字符串,using,Primer,指针
From: https://blog.51cto.com/u_6526235/7788071

相关文章

  • 【C++ Primer】语句
     一、简单语句1、使用空语句时应该加上注释,从而令读这段代码的人知道该语句是有意省略的。2、程序块不以分号结束(但是类要以分号结束)。二、语句作用域1、可以在if、switch、while、for语句内定义变量(变量是临时的),在语句结束后变量就不起作用了,所以这些变量要初始化。三、条件语......
  • 【C++ Primer】函数
       函数是一个命名了的代码块,通过调用函数执行相应的代码,函数可重载。 一、函数基础实参初始化形参。return有两项工作:1、返回值(如果有的话);2、将控制权从被调函数转移回主调函数。 intfact(intval){intret=1;returnret>val?ret:val;}intmain(){......
  • 全面理解C++中的类
    1.类的访问属性:public,protect,privateC++中类的成员变量和函数都带有三种属性中的一种,假如没有特别声明,那么就默认是私有的(除了构造函数)。public表示是公开的,对象可以直接调用的变量或者函数;protect表示是保护性的,只有本类和子类函数能够访问(注意只是访问,本类对象和子类对象都不可......
  • .Net Core 统一全局处理字符串为Null问题
    services.AddControllersWithViews().AddNewtonsoftJson(options=>{//设置序列化时间格式options.SerializerSettings.DateFormatString="yyyy-MM-ddHH:mm:ss";options.Serializ......
  • .Net Core 中GUID字符串的几种格式化
    NET下的Guid格式化有如下五种:1.Guid.NewGuid().ToString("N")获取32位不包含“-”号的GUID字符串例如:1c64d58a9e834bfe8d053555d81453d02.Guid.NewGuid().ToString("D")获取32位包含“-”号的GUID字符串,默认格式例如:ae8672ac-a987-43f3-a7c2-ac7b3249ac7b3.Guid.NewGuid().......
  • C++移动和获取文件读写指针
    在读写文件时,有时希望直接跳到文件中的某处开始读写,这就需要先将文件的读写指针指向该处,然后再进行读写。ifstream类和fstream类有seekg成员函数,可以设置文件读指针的位置;ofstream类和fstream类有seekp成员函数,可以设置文件写指针的位置。所谓“位置”,就是指距离文件开头......
  • C++系列十:日常学习-范围库Ranges
    目录前言介绍举例:前言不错麽内容参考https://zh.cppreference.com/w/cpp/rangesChatjpt总结注意点:确保你的C++编译器支持C++20标准包含ranges头文件views的操作是惰性的,它们不会立即执行,而是在需要时计算。这意味着你可以构建复杂的管道,而不必担心性能问题。提供......
  • Go字符串实战操作大全!
    在本篇文章中,我们深入探讨了Go语言中字符串的魅力和深度。从基础定义、操作、字符编码到复杂的类型转换,每个环节都带有实例和代码示例来深化理解。通过这些深入的解析,读者不仅能够掌握字符串在Go中的核心概念,还能洞察Go设计哲学背后的思考。关注公众号【TechLeadCloud】,分享互......
  • c++ OOP(2)
    目录运算符重载继承多态抽象基类运算符重载重新定义+-*/操作,对同类对象使用,以时间类Time为例子进行理解Time.hclassTime{private:inthour,minute;public:Time();Time(inth,intm);voidshow_time();Timeoperato......
  • vue中的循环遍历对象、数组和字符串
    vue循环遍历对象、数组和字符串1.循环遍历对象1.1vue在html里面循环遍历对象v-for="(val,key,i)indimItemMap":key="key" val-每一项key-key值i-第几个<el-table-columnprop="score"label="评分":show-overflow-tooltip="true"ali......