字符串和数组

来源:互联网 发布:淘宝客服欢迎用语 编辑:程序博客网 时间:2024/06/06 10:56

一、命名空间的using声明

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

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

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


二、标准库类型string

    标准库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;}

原创粉丝点击