wordpress电影下载站主题,产品推广计划怎么写,咸阳seo推广,网站建设规划方案制作你好#xff0c;C#xff08;11#xff09;如何用string数据类型表示一串文字#xff1f;根据初始值自动推断数据类型的auto关键字#xff08;#xff23; 11#xff09;
3.5.2 字符串类型
使用char类型的变量我们可以表示单个字符#xff0c;那么#xff0c;我们又…你好C11如何用string数据类型表示一串文字根据初始值自动推断数据类型的auto关键字 11
3.5.2 字符串类型
使用char类型的变量我们可以表示单个字符那么我们又该如何表示拥有多个字符的字符串呢 我们注意到一个字符串是由多个字符串连起来形成的。很自然地一种最简单直接的方法就是利用数组一种数据组织管理方式它将多个相同类型的数据元素组 织起来形成一个数据序列以便于访问。更多可以参考后文3.6小节对数组的介绍来保存一个字符串中的各个字符最后用一个特殊字符‘\0’表示字符串的 结束以此来将多个char类型的字符数据串联成字符串。例如 // 定义一个字符数组用以保存字符串
char msg[32];
// 将各个字符依次保存到数组相应位置上
msg[0] G; // 第一个字符保存到数组的第一个位置后面的以此类推
msg[1] o;
msg[2] o;
msg[3] d;
// 在最后的位置保存一个‘\0’表示字符串结束
msg[4] \0;
// 输出msg数组中的字符串
coutmsgendl; 用字符数组表示字符串的方式虽然简单可行可是却有诸多使用上的不便。在C中我们更多地是用STLStandard Template Library标准模板库是利用模板技术实现的一套函数库其中提供了一些常用的容器和算法以便于对数据进行处理。这里的字符串类型 string就是由它定义的一种用以表示字符串的数据类型。关于STL在稍后的第8章中我们还将详细介绍中定义好的字符串类型string来表示字符 串。这种字符串类型实质上是对一个char类型字符数组的包装在保存字符串数据的同时还增加了一些对字符串的常用操作比如获取字符串长度查找特定字 符等这样字符串的处理就方便多了。就像char和wchar_t相互对应处理不同范围的字符一样与string对应的C还提供了可以处理 wchar_t类型字符的wstring字符串类型。例如 #include iostream
#include string // string类型所在的头文件using namespace std;int main()
{// 定义一个string类型变量表示英文字符串string strEn Good Morning!;// 定义一个wstring类型变量表示中文字符串wstring strChs L陕A-82103;// 用cout输出string类型字符串// 用wcout输出wstring类型字符串coutstrEn;wcout.imbue( locale ( chs ) ); // 设置区域wcoutstrChsendl;return 0;
} 可以看到因为string和wstring编码方式的不同不同的字符串在输出的时候需要采用不同的方式。对于wstring类型的字符串变量 在输出的时候需要使用wcout对象并且需要用imbue()函数设定字符的编码方式。另外这里值得指出的一点是英文字符串不仅可以用string 类型表示也可以使用wstring类型表示而中文字符串则只能使用wstring类型表示。
string类型不仅包装了字符数组可以存储字符串中的各个字符同时还提供了很多跟字符串相关的操作例如可以获得一个字符串的长度或者在字符串中查找某个字符等等极大地方便了对字符串的处理。例如 // 定义一个字符串变量用于保存用户输入的用户名
string strName ;cout请输入用户名endl;
// 获取用户输入的字符串并保存到strName变量
cinstrName;
// 通过string类型的length()函数获取strName的长度
// 并判断其长度是否小于6字符串中是否少于6个字符
if(strName.length() 6)
{// 如果小于则进行错误提示cout错误用户名至少包含6个字符endl;
} 在上面这段代码中我们首先定义了一个string类型的变量strName用以保存用户输入的用户名字符串然后用cin获取用户输入的字符串 并保存到strName变量。接着再利用string类型的length()函数获取字符串的长度也就是strName中的字符个数。最后用if条件结 构将其与我们要求的字符串长度6进行比较如果不符合条件则进行错误提示。 知道更多auto类型变量——根据初始值推断真实的数据类型 在前面的章节中我们介绍了C中的多种数据类型有表示整数的int类型也有表示浮点数的float类型有表示单个字符的char类型也有表 示字符串的string类型这些意义不同用途各异的数据类型为我们定义变量来表示现实世界中的数据提供了丰富的选择。但是这些数据类型在使用上有一个 共同的要求那就是在定义变量表示数据时我们必须先要知道所要表示的数据是什么类型到底是一个小数呢还是一串字符然后才能据此确定到底是该使用 float呢还是string。可是在开发实践中有时候我们并不能非常容易地确定一个变量应该具有的数据类型。比如将某个复杂表达式作为初始值赋值给 一个新定义的变量时我们往往很难确定这个表达式的数据类型从而无法确定变量应有的数据类型。为了解决这个问题C11为我们提供了auto关键 字使用它作为某个变量定义的数据类型编译器会根据这个变量的初始值自动推断出这个变量合理的数据类型而无需我们人为指定。例如 auto x 7; // 使用整数7对变量x进行初始化x被推断为int类型
auto y 1.982; // 使用浮点数1.982对变量y进行初始化y被推断为double类型Handler GetHandler();
// 使用GetHandler()函数的返回值对变量handler进行初始化
// handler被推断为Handler类型
auto handler GetHandler(); 这里我们在定义变量x的时候并没有指定其具体的数据类型而是使用auto做为代替。这样编译器在编译这段代码时会根据7这个初始值自动推断 x的实际数据类型为int。同样的道理使用浮点数1.982进行初始化的变量y会被编译器自动推断为double类型而最后的一个变量handler 会被初始化为GetHandler()函数的返回值类型Handler。虽然auto关键字会根据初始值自动推断变量的数据类型但是它的使用并不需要 花费额外的编译时间。有好处而又没有额外的花费auto关键字就像商场的免费大赠送这样的大便宜谁不喜欢呢? 实际上可以把auto关键字看成是一个变量定义中的数据类型占位符它占据了原来应该是具体数据类型的位置。而在编译的时候编译器会根据这个变 量的初始值推断出这个变量应有的具体数据类型然后替换掉auto关键字就成为一个普通的带有具体数据类型的变量定义了。用auto关键字定义变量的 形式跟一般的定义变量的形式并无二异唯一的差别之处在于用auto关键字定义变量时变量必须有初始值 auto 变量名 初始值表达式; // 赋值形式
// 或
auto 变量名{初始值表达式}; // 初始化列表形式
这样这个初始值表达式计算结果的数据类型将被编译器推断为变量的数据类型。 通常在定义变量时如果我们很难准确地推断它的数据类型或者是这个变量的数据类型难于书写就可以使用auto作为变量的数据类型来定义变量而 真正的数据类型就交由编译器去根据变量的初始值推断得到好了。做这种苦力活电脑要比人脑快多了。这样做不仅省去了我们自己推断数据类型的麻烦避免了可 能的人为错误同时也可以达到简化代码的目的。例如 template typename T
// 数据类型vectorT之后的“”符号表示其后所定义的变量是一个引用
// 引用是C中一种访问数据的特殊方式在稍后的7.1小节中我们将详细介绍
void printall(const vectorT v)
{// 根据v.begin()的返回值类型自动推断变量it的数据类型for (auto it v.begin(); it ! v.end(); it)cout *it endl;
} 为了表示同样的意义如果没有auto关键字帮忙我们不得不写成下面这种繁琐的形式 template typename T
void printall(const vectorT v)
{for (typename vectorT::const_iterator it v.begin();it ! v.end(); it)cout *it endl;
} 除了简化代码之外auto关键字有时候甚至能够帮助我们完成一些在C11之前不可能完成的任务成为一种必需。比如在模板函数中当一个变 量的数据类型依赖于模板参数时如果不使用auto关键字将根本无法确定变量的数据类型因为我们根本无法提前预知用户使用何种数据类型作为模板参数来 调用这个模板函数从而也就无法确定这个变量的数据类型。但是使用auto关键字之后一切难题都将迎刃而解。例如 template typename T,typename U
void mul(const T t,const U u)
{// ...// 用auto关键字做数据类型编译器将根据u和t的实际数据类型// 自动推断变量tmp的数据类型auto tmp t*u;// ...
} 在这里变量tmp的数据类型应该与模板参数T和U相乘结果的数据类型相同也就是依赖于T和U的数据类型。对于程序员来说在编写这个模板函数的 时候模板参数T和U的类型尚未确定这样变量tmp的类型也就无法确定。所以我们用auto关键字作为占位符占据数据类型的位置而真正的数据类 型则留待编译器在最终编译的时候根据具体给定的模板参数T和U的类型而推断得到。这样就把一件原来不可能的事情变成了可能。 使用auto关键字可以根据变量的初始值自动推断其数据类型这样就极大地方便了复杂数据类型变量的定义。但是这种方式好是好却有一个缺点 那就是每次推断得到的数据类型只能在定义变量的时候使用一次无法保留下来继续使用。好不容易推断得到的数据类型只能使用一次这就显得有点不够低碳环保 了。而有时候我们也需要这个推断得到的数据能够保留下来从而可以重复使用以定义相同类型的多个变量。为了弥补这个缺点C11还提供了一个 decltype关键字。它的使用语法形式如下 typedef decltype(表达式) 用户数据类型;
其中decltype(表达式)是这个表达式的推断数据类型declared type也就是这个表达式计算结果的数据类型。而typedef则是将这个数据类型定义为用户自定义的数据类型换句话说也就是为这个推断数据类型 取一个名字从而可以把它作为一个新的数据类型用在定义变量、创建对象等任何需要数据类型的地方。例如我们可以用decltype关键字改写上面的例 子 template typename T,typename U
void mul(const T t,const U u)
{// ...// 用decltype得到t*u的数据类型// 并用typedef关键字将其定义成一个新的数据类型Mtypedef decltype(t*u) M;// 用这个新的数据类型M定义指针变量表示变量或函数地址的变量,创建M类型对象M* tmp nullptr;tmp new M; // ...
} auto和decltype的作用有些相似都可以推断某个表达式的具体数据类型。但是两者的使用还是稍有差别。如果我们仅仅是想根据初始值确定 一个变量合适的数据类型那么auto是最佳人选。而只有当我们需要推断某个表达式的数据类型并将其作为一种新的数据类型重复使用比如定义多个相同 类型变量或者单独使用比如作为函数的返回值类型时我们才真正需要用到decltype。